@rsbuild/core 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -596,7 +596,10 @@ var init_config = __esm({
596
596
  scriptLoading: "defer"
597
597
  });
598
598
  getDefaultSecurityConfig = () => ({
599
- nonce: ""
599
+ nonce: "",
600
+ sri: {
601
+ enable: false
602
+ }
600
603
  });
601
604
  getDefaultToolsConfig = () => ({
602
605
  cssExtract: {
@@ -765,15 +768,15 @@ function loadEnv({
765
768
  publicVars
766
769
  };
767
770
  }
768
- var import_node_fs2, import_node_path5, import_shared6, import_dotenv_expand, import_dotenv;
771
+ var import_node_fs2, import_node_path5, import_shared6, import_dotenv, import_dotenv_expand;
769
772
  var init_loadEnv = __esm({
770
773
  "src/loadEnv.ts"() {
771
774
  "use strict";
772
775
  import_node_fs2 = __toESM(require("fs"));
773
776
  import_node_path5 = require("path");
774
777
  import_shared6 = require("@rsbuild/shared");
775
- import_dotenv_expand = require("../compiled/dotenv-expand/index.js");
776
778
  import_dotenv = require("../compiled/dotenv/index.js");
779
+ import_dotenv_expand = require("../compiled/dotenv-expand/index.js");
777
780
  init_helpers();
778
781
  }
779
782
  });
@@ -849,11 +852,10 @@ function getEntryObject(config, target) {
849
852
  if (!config.source?.entry) {
850
853
  return {};
851
854
  }
852
- return (0, import_shared8.mergeChainedOptions)({
853
- defaults: {},
854
- options: config.source?.entry,
855
- utils: { target },
856
- useObjectParam: true
855
+ return (0, import_shared8.reduceConfigsMergeContext)({
856
+ initial: {},
857
+ config: config.source?.entry,
858
+ ctx: { target }
857
859
  });
858
860
  }
859
861
  var import_shared8, pluginEntry;
@@ -916,7 +918,7 @@ async function createContextByConfig(options, bundlerType, config = {}) {
916
918
  return {
917
919
  entry: getEntryObject(config, "web"),
918
920
  targets: config.output?.targets || [],
919
- version: "0.7.2",
921
+ version: "0.7.3",
920
922
  rootPath,
921
923
  distPath,
922
924
  cachePath,
@@ -1385,10 +1387,10 @@ async function modifyRspackConfig(context, rspackConfig, utils) {
1385
1387
  utils
1386
1388
  );
1387
1389
  if (context.config.tools?.rspack) {
1388
- modifiedConfig = (0, import_shared13.mergeChainedOptions)({
1389
- defaults: modifiedConfig,
1390
- options: context.config.tools.rspack,
1391
- utils,
1390
+ modifiedConfig = await (0, import_shared13.reduceConfigsAsyncWithContext)({
1391
+ initial: modifiedConfig,
1392
+ config: context.config.tools.rspack,
1393
+ ctx: utils,
1392
1394
  mergeFn: utils.mergeConfig
1393
1395
  });
1394
1396
  }
@@ -3200,12 +3202,12 @@ var init_basic = __esm({
3200
3202
  name: "rsbuild:basic",
3201
3203
  setup(api) {
3202
3204
  api.modifyBundlerChain(
3203
- (chain, { env, isProd: isProd4, target, bundler, CHAIN_ID: CHAIN_ID3 }) => {
3205
+ (chain, { env, isProd: isProd5, target, bundler, CHAIN_ID: CHAIN_ID3 }) => {
3204
3206
  const config = api.getNormalizedConfig();
3205
3207
  chain.name(import_shared25.TARGET_ID_MAP[target]);
3206
3208
  chain.devtool((0, import_shared25.getJsSourceMap)(config));
3207
3209
  chain.context(api.context.rootPath);
3208
- chain.mode(isProd4 ? "production" : "development");
3210
+ chain.mode(isProd5 ? "production" : "development");
3209
3211
  chain.merge({
3210
3212
  infrastructureLogging: {
3211
3213
  // Using `error` level to avoid `cache.PackFileCacheStrategy` logs
@@ -3218,9 +3220,9 @@ var init_basic = __esm({
3218
3220
  exportsPresence: "error"
3219
3221
  }
3220
3222
  });
3221
- const isMinimize = isProd4 && config.output.minify !== false;
3223
+ const isMinimize = isProd5 && config.output.minify !== false;
3222
3224
  chain.optimization.minimize(isMinimize);
3223
- const usingHMR = (0, import_shared25.isUsingHMR)(config, { target, isProd: isProd4 });
3225
+ const usingHMR = (0, import_shared25.isUsingHMR)(config, { target, isProd: isProd5 });
3224
3226
  if (usingHMR) {
3225
3227
  chain.plugin(CHAIN_ID3.PLUGIN.HMR).use(bundler.HotModuleReplacementPlugin);
3226
3228
  }
@@ -3402,7 +3404,7 @@ async function applyCSSRule({
3402
3404
  rule,
3403
3405
  config,
3404
3406
  context,
3405
- utils: { target, isProd: isProd4, CHAIN_ID: CHAIN_ID3 },
3407
+ utils: { target, isProd: isProd5, CHAIN_ID: CHAIN_ID3 },
3406
3408
  importLoaders = 1
3407
3409
  }) {
3408
3410
  const browserslist = await (0, import_shared28.getBrowserslistWithDefault)(
@@ -3411,7 +3413,7 @@ async function applyCSSRule({
3411
3413
  target
3412
3414
  );
3413
3415
  const enableExtractCSS = isUseCssExtract(config, target);
3414
- const localIdentName = getCSSModulesLocalIdentName(config, isProd4);
3416
+ const localIdentName = getCSSModulesLocalIdentName(config, isProd5);
3415
3417
  const cssLoaderOptions = getCSSLoaderOptions({
3416
3418
  config,
3417
3419
  importLoaders,
@@ -3422,9 +3424,9 @@ async function applyCSSRule({
3422
3424
  if (enableExtractCSS) {
3423
3425
  rule.use(CHAIN_ID3.USE.MINI_CSS_EXTRACT).loader(getCssExtractPlugin().loader).options(config.tools.cssExtract.loaderOptions).end();
3424
3426
  } else {
3425
- const styleLoaderOptions = (0, import_shared28.mergeChainedOptions)({
3426
- defaults: {},
3427
- options: config.tools.styleLoader
3427
+ const styleLoaderOptions = (0, import_shared28.reduceConfigs)({
3428
+ initial: {},
3429
+ config: config.tools.styleLoader
3428
3430
  });
3429
3431
  rule.use(CHAIN_ID3.USE.STYLE).loader(getCompiledPath("style-loader")).options(styleLoaderOptions).end();
3430
3432
  }
@@ -3454,8 +3456,8 @@ var init_css = __esm({
3454
3456
  init_pluginHelper();
3455
3457
  enableNativeCss = (config) => !config.output.injectStyles;
3456
3458
  isUseCssExtract = (config, target) => !config.output.injectStyles && target !== "node" && target !== "web-worker";
3457
- getCSSModulesLocalIdentName = (config, isProd4) => config.output.cssModules.localIdentName || // Using shorter classname in production to reduce bundle size
3458
- (isProd4 ? "[local]-[hash:base64:6]" : "[path][name]__[local]-[hash:base64:6]");
3459
+ getCSSModulesLocalIdentName = (config, isProd5) => config.output.cssModules.localIdentName || // Using shorter classname in production to reduce bundle size
3460
+ (isProd5 ? "[local]-[hash:base64:6]" : "[path][name]__[local]-[hash:base64:6]");
3459
3461
  normalizeCssLoaderOptions = (options, exportOnlyLocals) => {
3460
3462
  if (options.modules && exportOnlyLocals) {
3461
3463
  let { modules } = options;
@@ -3492,12 +3494,12 @@ var init_css = __esm({
3492
3494
  });
3493
3495
  if (!hasAutoprefixer) {
3494
3496
  const { default: autoprefixer } = await import("@rsbuild/shared/autoprefixer");
3495
- const autoprefixerOptions = (0, import_shared28.mergeChainedOptions)({
3496
- defaults: {
3497
+ const autoprefixerOptions = (0, import_shared28.reduceConfigs)({
3498
+ initial: {
3497
3499
  flexbox: "no-2009",
3498
3500
  overrideBrowserslist: browserslist
3499
3501
  },
3500
- options: config.tools.autoprefixer
3502
+ config: config.tools.autoprefixer
3501
3503
  });
3502
3504
  pluginObjects.push(autoprefixer(autoprefixerOptions));
3503
3505
  }
@@ -3532,10 +3534,10 @@ var init_css = __esm({
3532
3534
  },
3533
3535
  sourceMap: config.output.sourceMap.css
3534
3536
  };
3535
- const mergedConfig = (0, import_shared28.mergeChainedOptions)({
3536
- defaults: defaultPostcssConfig,
3537
- options: config.tools.postcss,
3538
- utils
3537
+ const mergedConfig = (0, import_shared28.reduceConfigsWithContext)({
3538
+ initial: defaultPostcssConfig,
3539
+ config: config.tools.postcss,
3540
+ ctx: utils
3539
3541
  });
3540
3542
  if (extraPlugins.length) {
3541
3543
  mergedConfig?.postcssOptions?.plugins.push(...extraPlugins);
@@ -3559,9 +3561,9 @@ var init_css = __esm({
3559
3561
  },
3560
3562
  sourceMap: config.output.sourceMap.css
3561
3563
  };
3562
- const mergedCssLoaderOptions = (0, import_shared28.mergeChainedOptions)({
3563
- defaults: defaultOptions2,
3564
- options: config.tools.cssLoader,
3564
+ const mergedCssLoaderOptions = (0, import_shared28.reduceConfigs)({
3565
+ initial: defaultOptions2,
3566
+ config: config.tools.cssLoader,
3565
3567
  mergeFn: import_shared28.deepmerge
3566
3568
  });
3567
3569
  const cssLoaderOptions = normalizeCssLoaderOptions(
@@ -3602,13 +3604,13 @@ __export(output_exports, {
3602
3604
  pluginOutput: () => pluginOutput
3603
3605
  });
3604
3606
  function getPublicPath({
3605
- isProd: isProd4,
3607
+ isProd: isProd5,
3606
3608
  config,
3607
3609
  context
3608
3610
  }) {
3609
3611
  const { dev, output } = config;
3610
3612
  let publicPath = import_shared29.DEFAULT_ASSET_PREFIX;
3611
- if (isProd4) {
3613
+ if (isProd5) {
3612
3614
  if (typeof output.assetPrefix === "string") {
3613
3615
  publicPath = output.assetPrefix;
3614
3616
  }
@@ -3641,20 +3643,23 @@ var init_output = __esm({
3641
3643
  name: "rsbuild:output",
3642
3644
  setup(api) {
3643
3645
  api.modifyBundlerChain(
3644
- async (chain, { CHAIN_ID: CHAIN_ID3, target, isProd: isProd4, isServer, isServiceWorker }) => {
3646
+ async (chain, { CHAIN_ID: CHAIN_ID3, target, isProd: isProd5, isServer, isServiceWorker }) => {
3645
3647
  const config = api.getNormalizedConfig();
3646
3648
  const publicPath = getPublicPath({
3647
3649
  config,
3648
- isProd: isProd4,
3650
+ isProd: isProd5,
3649
3651
  context: api.context
3650
3652
  });
3651
3653
  const jsPath = (0, import_shared29.getDistPath)(config, "js");
3652
3654
  const jsAsyncPath = (0, import_shared29.getDistPath)(config, "jsAsync");
3653
- const jsFilename = (0, import_shared29.getFilename)(config, "js", isProd4);
3655
+ const jsFilename = (0, import_shared29.getFilename)(config, "js", isProd5);
3654
3656
  chain.output.path(api.context.distPath).filename(import_node_path15.posix.join(jsPath, jsFilename)).chunkFilename(import_node_path15.posix.join(jsAsyncPath, jsFilename)).publicPath(publicPath).pathinfo(false).hashFunction("xxhash64");
3655
3657
  if (isServer) {
3656
3658
  const serverPath = (0, import_shared29.getDistPath)(config, "server");
3657
- chain.output.path(import_node_path15.posix.join(api.context.distPath, serverPath)).filename("[name].js").chunkFilename("[name].js").libraryTarget("commonjs2");
3659
+ chain.output.path(import_node_path15.posix.join(api.context.distPath, serverPath)).filename("[name].js").chunkFilename("[name].js").library({
3660
+ ...chain.output.get("library") || {},
3661
+ type: "commonjs2"
3662
+ });
3658
3663
  }
3659
3664
  if (isServiceWorker) {
3660
3665
  const workerPath = (0, import_shared29.getDistPath)(config, "worker");
@@ -3669,7 +3674,7 @@ var init_output = __esm({
3669
3674
  if (isUseCssExtract(config, target)) {
3670
3675
  const extractPluginOptions = config.tools.cssExtract.pluginOptions;
3671
3676
  const cssPath = (0, import_shared29.getDistPath)(config, "css");
3672
- const cssFilename = (0, import_shared29.getFilename)(config, "css", isProd4);
3677
+ const cssFilename = (0, import_shared29.getFilename)(config, "css", isProd5);
3673
3678
  const cssAsyncPath = (0, import_shared29.getDistPath)(config, "cssAsync");
3674
3679
  chain.plugin(CHAIN_ID3.PLUGIN.MINI_CSS_EXTRACT).use(getCssExtractPlugin(), [
3675
3680
  {
@@ -3719,10 +3724,10 @@ function applyAlias({
3719
3724
  if (!alias) {
3720
3725
  return;
3721
3726
  }
3722
- const mergedAlias = (0, import_shared30.mergeChainedOptions)({
3723
- defaults: {},
3724
- options: alias,
3725
- utils: { target }
3727
+ const mergedAlias = (0, import_shared30.reduceConfigsWithContext)({
3728
+ initial: {},
3729
+ config: alias,
3730
+ ctx: { target }
3726
3731
  });
3727
3732
  for (const name of Object.keys(mergedAlias)) {
3728
3733
  const values = (0, import_shared30.castArray)(mergedAlias[name]);
@@ -4044,12 +4049,12 @@ var init_asset = __esm({
4044
4049
  pluginAsset = () => ({
4045
4050
  name: "rsbuild:asset",
4046
4051
  setup(api) {
4047
- api.modifyBundlerChain((chain, { isProd: isProd4, target }) => {
4052
+ api.modifyBundlerChain((chain, { isProd: isProd5, target }) => {
4048
4053
  const config = api.getNormalizedConfig();
4049
4054
  const createAssetRule = (assetType, exts, emit2) => {
4050
4055
  const regExp = getRegExpForExts(exts);
4051
4056
  const distDir = (0, import_shared34.getDistPath)(config, assetType);
4052
- const filename = (0, import_shared34.getFilename)(config, assetType, isProd4);
4057
+ const filename = (0, import_shared34.getFilename)(config, assetType, isProd5);
4053
4058
  const { dataUriLimit } = config.output;
4054
4059
  const maxSize = typeof dataUriLimit === "number" ? dataUriLimit : dataUriLimit[assetType];
4055
4060
  const rule = chain.module.rule(assetType).test(regExp);
@@ -4127,9 +4132,9 @@ var init_minimize = __esm({
4127
4132
  }
4128
4133
  return options;
4129
4134
  };
4130
- parseMinifyOptions = (config, isProd4 = true) => {
4135
+ parseMinifyOptions = (config, isProd5 = true) => {
4131
4136
  const minify = config.output.minify;
4132
- if (minify === false || !isProd4) {
4137
+ if (minify === false || !isProd5) {
4133
4138
  return {
4134
4139
  minifyJs: false,
4135
4140
  minifyCss: false,
@@ -4161,9 +4166,9 @@ var init_minimize = __esm({
4161
4166
  if (api.context.bundlerType === "webpack") {
4162
4167
  return;
4163
4168
  }
4164
- api.modifyBundlerChain(async (chain, { isProd: isProd4 }) => {
4169
+ api.modifyBundlerChain(async (chain, { isProd: isProd5 }) => {
4165
4170
  const config = api.getNormalizedConfig();
4166
- const isMinimize = isProd4 && config.output.minify !== false;
4171
+ const isMinimize = isProd5 && config.output.minify !== false;
4167
4172
  if (!isMinimize) {
4168
4173
  return;
4169
4174
  }
@@ -4366,10 +4371,17 @@ var init_HtmlBasicPlugin = __esm({
4366
4371
  addTitleTag(headTags, data.plugin.options?.title);
4367
4372
  }
4368
4373
  addFavicon(headTags, favicon);
4369
- const result = await this.modifyTagsFn({
4370
- headTags: headTags.map(formatBasicTag),
4371
- bodyTags: bodyTags.map(formatBasicTag)
4372
- });
4374
+ const result = await this.modifyTagsFn(
4375
+ {
4376
+ headTags: headTags.map(formatBasicTag),
4377
+ bodyTags: bodyTags.map(formatBasicTag)
4378
+ },
4379
+ {
4380
+ compilation,
4381
+ assetPrefix: data.publicPath,
4382
+ filename: data.outputName
4383
+ }
4384
+ );
4373
4385
  Object.assign(data, {
4374
4386
  headTags: result.headTags.map(fromBasicTag),
4375
4387
  bodyTags: result.bodyTags.map(fromBasicTag)
@@ -4497,8 +4509,8 @@ function getTerserMinifyOptions(config) {
4497
4509
  const finalOptions = applyRemoveConsole(options, config);
4498
4510
  return finalOptions;
4499
4511
  }
4500
- async function getHtmlMinifyOptions(isProd4, config) {
4501
- if (!isProd4 || !config.output.minify || !parseMinifyOptions(config).minifyHtml) {
4512
+ async function getHtmlMinifyOptions(isProd5, config) {
4513
+ if (!isProd5 || !config.output.minify || !parseMinifyOptions(config).minifyHtml) {
4502
4514
  return false;
4503
4515
  }
4504
4516
  const minifyJS = getTerserMinifyOptions(config);
@@ -4519,29 +4531,25 @@ async function getHtmlMinifyOptions(isProd4, config) {
4519
4531
  return typeof htmlMinifyOptions === "object" ? (0, import_shared38.deepmerge)(htmlMinifyDefaultOptions, htmlMinifyOptions) : htmlMinifyDefaultOptions;
4520
4532
  }
4521
4533
  function getTitle(entryName, config) {
4522
- return (0, import_shared38.mergeChainedOptions)({
4523
- defaults: "",
4524
- options: config.html.title,
4525
- utils: { entryName },
4526
- useObjectParam: true
4534
+ return (0, import_shared38.reduceConfigsMergeContext)({
4535
+ initial: "",
4536
+ config: config.html.title,
4537
+ ctx: { entryName }
4527
4538
  });
4528
4539
  }
4529
4540
  function getInject(entryName, config) {
4530
- return (0, import_shared38.mergeChainedOptions)({
4531
- defaults: "head",
4532
- options: config.html.inject,
4533
- utils: { entryName },
4534
- useObjectParam: true,
4535
- isFalsy: import_shared38.isNil
4541
+ return (0, import_shared38.reduceConfigsMergeContext)({
4542
+ initial: "head",
4543
+ config: config.html.inject,
4544
+ ctx: { entryName }
4536
4545
  });
4537
4546
  }
4538
4547
  async function getTemplate(entryName, config, rootPath) {
4539
4548
  const DEFAULT_TEMPLATE = import_node_path20.default.resolve(STATIC_PATH, "template.html");
4540
- const templatePath = (0, import_shared38.mergeChainedOptions)({
4541
- defaults: DEFAULT_TEMPLATE,
4542
- options: config.html.template,
4543
- utils: { entryName },
4544
- useObjectParam: true
4549
+ const templatePath = (0, import_shared38.reduceConfigsMergeContext)({
4550
+ initial: DEFAULT_TEMPLATE,
4551
+ config: config.html.template,
4552
+ ctx: { entryName }
4545
4553
  });
4546
4554
  if (templatePath === DEFAULT_TEMPLATE) {
4547
4555
  return {
@@ -4566,19 +4574,17 @@ async function getTemplate(entryName, config, rootPath) {
4566
4574
  };
4567
4575
  }
4568
4576
  function getFavicon(entryName, config) {
4569
- return (0, import_shared38.mergeChainedOptions)({
4570
- defaults: "",
4571
- options: config.html.favicon,
4572
- utils: { entryName },
4573
- useObjectParam: true
4577
+ return (0, import_shared38.reduceConfigsMergeContext)({
4578
+ initial: "",
4579
+ config: config.html.favicon,
4580
+ ctx: { entryName }
4574
4581
  });
4575
4582
  }
4576
4583
  function getMetaTags(entryName, config, templateContent) {
4577
- const metaTags = (0, import_shared38.mergeChainedOptions)({
4578
- defaults: {},
4579
- options: config.html.meta,
4580
- utils: { entryName },
4581
- useObjectParam: true
4584
+ const metaTags = (0, import_shared38.reduceConfigsMergeContext)({
4585
+ initial: {},
4586
+ config: config.html.meta,
4587
+ ctx: { entryName }
4582
4588
  });
4583
4589
  if (templateContent && metaTags.charset) {
4584
4590
  const charsetRegExp = /<meta[^>]+charset=["'][^>]*>/i;
@@ -4603,10 +4609,10 @@ function getTemplateParameters(entryName, config, assetPrefix) {
4603
4609
  options: pluginOptions
4604
4610
  }
4605
4611
  };
4606
- return (0, import_shared38.mergeChainedOptions)({
4607
- defaults: defaultOptions2,
4608
- options: templateParameters,
4609
- utils: { entryName }
4612
+ return (0, import_shared38.reduceConfigsWithContext)({
4613
+ initial: defaultOptions2,
4614
+ config: templateParameters,
4615
+ ctx: { entryName }
4610
4616
  });
4611
4617
  };
4612
4618
  }
@@ -4655,12 +4661,12 @@ var init_html = __esm({
4655
4661
  name: "rsbuild:html",
4656
4662
  setup(api) {
4657
4663
  api.modifyBundlerChain(
4658
- async (chain, { HtmlPlugin, isProd: isProd4, CHAIN_ID: CHAIN_ID3, target }) => {
4664
+ async (chain, { HtmlPlugin, isProd: isProd5, CHAIN_ID: CHAIN_ID3, target }) => {
4659
4665
  const config = api.getNormalizedConfig();
4660
4666
  if ((0, import_shared38.isHtmlDisabled)(config, target)) {
4661
4667
  return;
4662
4668
  }
4663
- const minify = await getHtmlMinifyOptions(isProd4, config);
4669
+ const minify = await getHtmlMinifyOptions(isProd5, config);
4664
4670
  const assetPrefix = getPublicPathFromChain(chain, false);
4665
4671
  const entries = chain.entryPoints.entries() || {};
4666
4672
  const entryNames = Object.keys(entries);
@@ -4669,11 +4675,7 @@ var init_html = __esm({
4669
4675
  const finalOptions = await Promise.all(
4670
4676
  entryNames.map(async (entryName) => {
4671
4677
  const entryValue = entries[entryName].values();
4672
- const chunks = getChunks(
4673
- entryName,
4674
- // EntryDescription type is different between webpack and Rspack
4675
- entryValue
4676
- );
4678
+ const chunks = getChunks(entryName, entryValue);
4677
4679
  const inject = getInject(entryName, config);
4678
4680
  const filename = htmlPaths[entryName];
4679
4681
  const { templatePath, templateContent } = await getTemplate(
@@ -4719,13 +4721,10 @@ var init_html = __esm({
4719
4721
  pluginOptions.favicon = favicon;
4720
4722
  }
4721
4723
  }
4722
- const finalOptions2 = (0, import_shared38.mergeChainedOptions)({
4723
- defaults: pluginOptions,
4724
- options: typeof config.tools.htmlPlugin === "boolean" ? {} : config.tools.htmlPlugin,
4725
- utils: {
4726
- entryName,
4727
- entryValue
4728
- }
4724
+ const finalOptions2 = (0, import_shared38.reduceConfigsWithContext)({
4725
+ initial: pluginOptions,
4726
+ config: typeof config.tools.htmlPlugin === "boolean" ? {} : config.tools.htmlPlugin,
4727
+ ctx: { entryName, entryValue }
4729
4728
  });
4730
4729
  return finalOptions2;
4731
4730
  })
@@ -4750,52 +4749,21 @@ var init_html = __esm({
4750
4749
  }
4751
4750
  }
4752
4751
  );
4753
- api.onAfterCreateCompiler(({ compiler }) => {
4754
- const { nonce } = api.getNormalizedConfig().security;
4755
- if (!nonce) {
4756
- return;
4757
- }
4758
- (0, import_shared38.applyToCompiler)(compiler, (compiler2) => {
4759
- const { plugins } = compiler2.options;
4760
- const hasHTML = plugins.some(
4761
- (plugin) => plugin && plugin.constructor.name === "HtmlBasicPlugin"
4762
- );
4763
- if (!hasHTML) {
4764
- return;
4765
- }
4766
- const injectCode = (0, import_shared38.createVirtualModule)(
4767
- `__webpack_nonce__ = "${nonce}";`
4768
- );
4769
- new compiler2.webpack.EntryPlugin(compiler2.context, injectCode, {
4770
- name: void 0
4771
- }).apply(compiler2);
4772
- });
4773
- });
4774
4752
  api.modifyHTMLTags({
4775
4753
  // ensure `crossorigin` and `nonce` can be applied to all tags
4776
4754
  order: "post",
4777
4755
  handler: ({ headTags, bodyTags }) => {
4778
4756
  const config = api.getNormalizedConfig();
4779
4757
  const { crossorigin } = config.html;
4780
- const { nonce } = config.security;
4781
4758
  const allTags = [...headTags, ...bodyTags];
4782
4759
  if (crossorigin) {
4783
4760
  const formattedCrossorigin = crossorigin === true ? "anonymous" : crossorigin;
4784
4761
  for (const tag of allTags) {
4785
4762
  if (tag.tag === "script" && tag.attrs?.src || tag.tag === "link" && tag.attrs?.rel === "stylesheet") {
4786
- tag.attrs ||= {};
4787
4763
  tag.attrs.crossorigin ??= formattedCrossorigin;
4788
4764
  }
4789
4765
  }
4790
4766
  }
4791
- if (nonce) {
4792
- for (const tag of allTags) {
4793
- if (tag.tag === "script" || tag.tag === "style") {
4794
- tag.attrs ??= {};
4795
- tag.attrs.nonce = nonce;
4796
- }
4797
- }
4798
- }
4799
4767
  return { headTags, bodyTags };
4800
4768
  }
4801
4769
  });
@@ -5096,9 +5064,9 @@ var init_swc = __esm({
5096
5064
  await applyCoreJs(swcConfig, chain, polyfillMode);
5097
5065
  }
5098
5066
  }
5099
- const mergedSwcConfig = (0, import_shared42.mergeChainedOptions)({
5100
- defaults: swcConfig,
5101
- options: config.tools.swc,
5067
+ const mergedSwcConfig = (0, import_shared42.reduceConfigs)({
5068
+ initial: swcConfig,
5069
+ config: config.tools.swc,
5102
5070
  mergeFn: import_shared42.deepmerge
5103
5071
  });
5104
5072
  rule.use(CHAIN_ID3.USE.SWC).loader(builtinSwcLoaderName).options(mergedSwcConfig);
@@ -6541,8 +6509,8 @@ var init_lazyCompilation = __esm({
6541
6509
  pluginLazyCompilation = () => ({
6542
6510
  name: "rsbuild:lazy-compilation",
6543
6511
  setup(api) {
6544
- api.modifyBundlerChain((chain, { isProd: isProd4, target }) => {
6545
- if (isProd4 || target !== "web") {
6512
+ api.modifyBundlerChain((chain, { isProd: isProd5, target }) => {
6513
+ if (isProd5 || target !== "web") {
6546
6514
  return;
6547
6515
  }
6548
6516
  const config = api.getNormalizedConfig();
@@ -6602,6 +6570,222 @@ var init_lazyCompilation = __esm({
6602
6570
  }
6603
6571
  });
6604
6572
 
6573
+ // src/plugins/sri.ts
6574
+ var sri_exports = {};
6575
+ __export(sri_exports, {
6576
+ pluginSri: () => pluginSri
6577
+ });
6578
+ var import_node_crypto2, import_shared57, getAssetName, pluginSri;
6579
+ var init_sri = __esm({
6580
+ "src/plugins/sri.ts"() {
6581
+ "use strict";
6582
+ import_node_crypto2 = __toESM(require("crypto"));
6583
+ import_shared57 = require("@rsbuild/shared");
6584
+ init_constants();
6585
+ getAssetName = (url2, assetPrefix) => {
6586
+ if (url2.startsWith(assetPrefix)) {
6587
+ return (0, import_shared57.removeLeadingSlash)(url2.replace(assetPrefix, ""));
6588
+ }
6589
+ return (0, import_shared57.removeLeadingSlash)(url2);
6590
+ };
6591
+ pluginSri = () => ({
6592
+ name: "rsbuild:sri",
6593
+ setup(api) {
6594
+ const placeholder = "RSBUILD_INTEGRITY_PLACEHOLDER:";
6595
+ const getAlgorithm = () => {
6596
+ const config = api.getNormalizedConfig();
6597
+ const { sri } = config.security;
6598
+ const enable = sri.enable === "auto" ? (0, import_shared57.isProd)() : sri.enable;
6599
+ if (!enable) {
6600
+ return null;
6601
+ }
6602
+ const { algorithm = "sha384" } = sri;
6603
+ return algorithm;
6604
+ };
6605
+ api.modifyHTMLTags({
6606
+ // ensure `sri` can be applied to all tags
6607
+ order: "post",
6608
+ handler(tags, { assetPrefix }) {
6609
+ const algorithm = getAlgorithm();
6610
+ if (!algorithm) {
6611
+ return tags;
6612
+ }
6613
+ const allTags = [...tags.headTags, ...tags.bodyTags];
6614
+ for (const tag of allTags) {
6615
+ let url2 = "";
6616
+ if (!tag.attrs) {
6617
+ continue;
6618
+ }
6619
+ if (tag.tag === "script" && typeof tag.attrs.src === "string") {
6620
+ url2 = tag.attrs.src;
6621
+ } else if (tag.tag === "link" && tag.attrs.rel === "stylesheet" && typeof tag.attrs.href === "string") {
6622
+ url2 = tag.attrs.href;
6623
+ }
6624
+ if (!url2) {
6625
+ continue;
6626
+ }
6627
+ const assetName = getAssetName(url2, assetPrefix);
6628
+ if (!assetName) {
6629
+ continue;
6630
+ }
6631
+ tag.attrs.integrity ??= `${placeholder}${assetName}`;
6632
+ }
6633
+ return tags;
6634
+ }
6635
+ });
6636
+ const replaceIntegrity = (htmlContent, assets, algorithm, integrityCache) => {
6637
+ const regex = /integrity="RSBUILD_INTEGRITY_PLACEHOLDER:([^"]+)"/g;
6638
+ const matches = htmlContent.matchAll(regex);
6639
+ let replacedHtml = htmlContent;
6640
+ const calcIntegrity = (algorithm2, assetName, data) => {
6641
+ if (integrityCache.has(assetName)) {
6642
+ return integrityCache.get(assetName);
6643
+ }
6644
+ const hash = import_node_crypto2.default.createHash(algorithm2).update(data).digest().toString("base64");
6645
+ const integrity = `${algorithm2}-${hash}`;
6646
+ integrityCache.set(assetName, integrity);
6647
+ return integrity;
6648
+ };
6649
+ for (const match of matches) {
6650
+ const assetName = match[1];
6651
+ if (!assetName) {
6652
+ continue;
6653
+ }
6654
+ if (assets[assetName]) {
6655
+ const integrity = calcIntegrity(
6656
+ algorithm,
6657
+ assetName,
6658
+ assets[assetName].buffer()
6659
+ );
6660
+ replacedHtml = replacedHtml.replaceAll(
6661
+ `integrity="${placeholder}${assetName}"`,
6662
+ `integrity="${integrity}"`
6663
+ );
6664
+ } else {
6665
+ import_shared57.logger.debug(
6666
+ `[rsbuild:sri] failed to generate integrity for ${assetName}.`
6667
+ );
6668
+ replacedHtml = replacedHtml.replace(
6669
+ `integrity="${placeholder}${assetName}"`,
6670
+ ""
6671
+ );
6672
+ }
6673
+ }
6674
+ return replacedHtml;
6675
+ };
6676
+ class SriReplaceIntegrityPlugin {
6677
+ constructor(algorithm) {
6678
+ __publicField(this, "algorithm");
6679
+ this.algorithm = algorithm;
6680
+ }
6681
+ apply(compiler) {
6682
+ compiler.hooks.compilation.tap(
6683
+ "SriReplaceIntegrityPlugin",
6684
+ (compilation) => {
6685
+ compilation.hooks.processAssets.tapPromise(
6686
+ {
6687
+ name: "SriReplaceIntegrityPlugin",
6688
+ // use to final stage to get the final asset content
6689
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT
6690
+ },
6691
+ async (assets) => {
6692
+ const integrityCache = /* @__PURE__ */ new Map();
6693
+ for (const asset of Object.keys(assets)) {
6694
+ if (!HTML_REGEX.test(asset)) {
6695
+ continue;
6696
+ }
6697
+ const htmlContent = assets[asset].source();
6698
+ if (!htmlContent.includes(placeholder)) {
6699
+ continue;
6700
+ }
6701
+ assets[asset] = new compiler.webpack.sources.RawSource(
6702
+ replaceIntegrity(
6703
+ htmlContent,
6704
+ assets,
6705
+ this.algorithm,
6706
+ integrityCache
6707
+ )
6708
+ );
6709
+ }
6710
+ }
6711
+ );
6712
+ }
6713
+ );
6714
+ }
6715
+ }
6716
+ api.modifyBundlerChain((chain, { target }) => {
6717
+ const config = api.getNormalizedConfig();
6718
+ if ((0, import_shared57.isHtmlDisabled)(config, target)) {
6719
+ return;
6720
+ }
6721
+ const algorithm = getAlgorithm();
6722
+ if (!algorithm) {
6723
+ return;
6724
+ }
6725
+ chain.plugin("rsbuild-sri-replace").use(SriReplaceIntegrityPlugin, [algorithm]);
6726
+ });
6727
+ }
6728
+ });
6729
+ }
6730
+ });
6731
+
6732
+ // src/plugins/nonce.ts
6733
+ var nonce_exports = {};
6734
+ __export(nonce_exports, {
6735
+ pluginNonce: () => pluginNonce
6736
+ });
6737
+ var import_shared58, pluginNonce;
6738
+ var init_nonce = __esm({
6739
+ "src/plugins/nonce.ts"() {
6740
+ "use strict";
6741
+ import_shared58 = require("@rsbuild/shared");
6742
+ pluginNonce = () => ({
6743
+ name: "rsbuild:nonce",
6744
+ setup(api) {
6745
+ api.onAfterCreateCompiler(({ compiler }) => {
6746
+ const { nonce } = api.getNormalizedConfig().security;
6747
+ if (!nonce) {
6748
+ return;
6749
+ }
6750
+ (0, import_shared58.applyToCompiler)(compiler, (compiler2) => {
6751
+ const { plugins } = compiler2.options;
6752
+ const hasHTML = plugins.some(
6753
+ (plugin) => plugin && plugin.constructor.name === "HtmlBasicPlugin"
6754
+ );
6755
+ if (!hasHTML) {
6756
+ return;
6757
+ }
6758
+ const injectCode = (0, import_shared58.createVirtualModule)(
6759
+ `__webpack_nonce__ = "${nonce}";`
6760
+ );
6761
+ new compiler2.webpack.EntryPlugin(compiler2.context, injectCode, {
6762
+ name: void 0
6763
+ }).apply(compiler2);
6764
+ });
6765
+ });
6766
+ api.modifyHTMLTags({
6767
+ // ensure `nonce` can be applied to all tags
6768
+ order: "post",
6769
+ handler: ({ headTags, bodyTags }) => {
6770
+ const config = api.getNormalizedConfig();
6771
+ const { nonce } = config.security;
6772
+ const allTags = [...headTags, ...bodyTags];
6773
+ if (nonce) {
6774
+ for (const tag of allTags) {
6775
+ if (tag.tag === "script" || tag.tag === "style") {
6776
+ tag.attrs ??= {};
6777
+ tag.attrs.nonce = nonce;
6778
+ }
6779
+ }
6780
+ }
6781
+ return { headTags, bodyTags };
6782
+ }
6783
+ });
6784
+ }
6785
+ });
6786
+ }
6787
+ });
6788
+
6605
6789
  // src/createRsbuild.ts
6606
6790
  var createRsbuild_exports = {};
6607
6791
  __export(createRsbuild_exports, {
@@ -6640,6 +6824,8 @@ async function applyDefaultPlugins(pluginManager, context) {
6640
6824
  const { pluginModuleFederation: pluginModuleFederation2 } = await Promise.resolve().then(() => (init_moduleFederation(), moduleFederation_exports));
6641
6825
  const { pluginRspackProfile: pluginRspackProfile2 } = await Promise.resolve().then(() => (init_rspackProfile(), rspackProfile_exports));
6642
6826
  const { pluginLazyCompilation: pluginLazyCompilation2 } = await Promise.resolve().then(() => (init_lazyCompilation(), lazyCompilation_exports));
6827
+ const { pluginSri: pluginSri2 } = await Promise.resolve().then(() => (init_sri(), sri_exports));
6828
+ const { pluginNonce: pluginNonce2 } = await Promise.resolve().then(() => (init_nonce(), nonce_exports));
6643
6829
  pluginManager.addPlugins([
6644
6830
  pluginBasic2(),
6645
6831
  pluginEntry2(),
@@ -6651,8 +6837,8 @@ async function applyDefaultPlugins(pluginManager, context) {
6651
6837
  // cleanOutput plugin should before the html plugin
6652
6838
  pluginCleanOutput2(),
6653
6839
  pluginAsset2(),
6654
- pluginHtml2(async (tags) => {
6655
- const result = await context.hooks.modifyHTMLTags.call(tags);
6840
+ pluginHtml2(async (...args) => {
6841
+ const result = await context.hooks.modifyHTMLTags.call(...args);
6656
6842
  return result[0];
6657
6843
  }),
6658
6844
  pluginWasm2(),
@@ -6675,7 +6861,9 @@ async function applyDefaultPlugins(pluginManager, context) {
6675
6861
  pluginManifest2(),
6676
6862
  pluginModuleFederation2(),
6677
6863
  pluginRspackProfile2(),
6678
- pluginLazyCompilation2()
6864
+ pluginLazyCompilation2(),
6865
+ pluginSri2(),
6866
+ pluginNonce2()
6679
6867
  ]);
6680
6868
  }
6681
6869
  async function createRsbuild(options = {}) {
@@ -6693,9 +6881,9 @@ async function createRsbuild(options = {}) {
6693
6881
  );
6694
6882
  const pluginAPI = getPluginAPI({ context, pluginManager });
6695
6883
  context.pluginAPI = pluginAPI;
6696
- (0, import_shared57.debug)("add default plugins");
6884
+ (0, import_shared59.debug)("add default plugins");
6697
6885
  await applyDefaultPlugins(pluginManager, context);
6698
- (0, import_shared57.debug)("add default plugins done");
6886
+ (0, import_shared59.debug)("add default plugins done");
6699
6887
  const provider = rsbuildConfig.provider || await getRspackProvider();
6700
6888
  const providerInstance = await provider({
6701
6889
  context,
@@ -6704,13 +6892,13 @@ async function createRsbuild(options = {}) {
6704
6892
  setCssExtractPlugin
6705
6893
  });
6706
6894
  const rsbuild = {
6707
- ...(0, import_shared57.pick)(pluginManager, [
6895
+ ...(0, import_shared59.pick)(pluginManager, [
6708
6896
  "addPlugins",
6709
6897
  "getPlugins",
6710
6898
  "removePlugins",
6711
6899
  "isPluginExists"
6712
6900
  ]),
6713
- ...(0, import_shared57.pick)(pluginAPI, [
6901
+ ...(0, import_shared59.pick)(pluginAPI, [
6714
6902
  "onBeforeBuild",
6715
6903
  "onBeforeCreateCompiler",
6716
6904
  "onBeforeStartDevServer",
@@ -6726,7 +6914,7 @@ async function createRsbuild(options = {}) {
6726
6914
  "getRsbuildConfig",
6727
6915
  "getNormalizedConfig"
6728
6916
  ]),
6729
- ...(0, import_shared57.pick)(providerInstance, [
6917
+ ...(0, import_shared59.pick)(providerInstance, [
6730
6918
  "build",
6731
6919
  "preview",
6732
6920
  "initConfigs",
@@ -6743,11 +6931,11 @@ async function createRsbuild(options = {}) {
6743
6931
  }
6744
6932
  return rsbuild;
6745
6933
  }
6746
- var import_shared57, getRspackProvider, pickRsbuildConfig;
6934
+ var import_shared59, getRspackProvider, pickRsbuildConfig;
6747
6935
  var init_createRsbuild = __esm({
6748
6936
  "src/createRsbuild.ts"() {
6749
6937
  "use strict";
6750
- import_shared57 = require("@rsbuild/shared");
6938
+ import_shared59 = require("@rsbuild/shared");
6751
6939
  init_createContext();
6752
6940
  init_initPlugins();
6753
6941
  init_pluginHelper();
@@ -6769,7 +6957,7 @@ var init_createRsbuild = __esm({
6769
6957
  "moduleFederation",
6770
6958
  "_privateMeta"
6771
6959
  ];
6772
- return (0, import_shared57.pick)(rsbuildConfig, keys);
6960
+ return (0, import_shared59.pick)(rsbuildConfig, keys);
6773
6961
  };
6774
6962
  }
6775
6963
  });
@@ -6788,7 +6976,7 @@ async function init({
6788
6976
  cwd: root,
6789
6977
  mode: cliOptions?.envMode
6790
6978
  });
6791
- if ((0, import_shared58.isDev)()) {
6979
+ if ((0, import_shared60.isDev)()) {
6792
6980
  onBeforeRestartServer(envs.cleanup);
6793
6981
  }
6794
6982
  const { content: config, filePath: configFilePath } = await loadConfig({
@@ -6828,17 +7016,17 @@ async function init({
6828
7016
  });
6829
7017
  } catch (err) {
6830
7018
  if (isRestart) {
6831
- import_shared58.logger.error(err);
7019
+ import_shared60.logger.error(err);
6832
7020
  } else {
6833
7021
  throw err;
6834
7022
  }
6835
7023
  }
6836
7024
  }
6837
- var import_shared58, commonOpts;
7025
+ var import_shared60, commonOpts;
6838
7026
  var init_init = __esm({
6839
7027
  "src/cli/init.ts"() {
6840
7028
  "use strict";
6841
- import_shared58 = require("@rsbuild/shared");
7029
+ import_shared60 = require("@rsbuild/shared");
6842
7030
  init_config();
6843
7031
  init_loadEnv();
6844
7032
  init_restart();
@@ -6856,7 +7044,7 @@ __export(src_exports, {
6856
7044
  defineConfig: () => defineConfig,
6857
7045
  loadConfig: () => loadConfig,
6858
7046
  loadEnv: () => loadEnv,
6859
- logger: () => import_shared61.logger,
7047
+ logger: () => import_shared63.logger,
6860
7048
  mergeRsbuildConfig: () => mergeRsbuildConfig,
6861
7049
  rspack: () => import_core10.rspack,
6862
7050
  version: () => version
@@ -6888,7 +7076,7 @@ __export(internal_exports, {
6888
7076
  // src/cli/commands.ts
6889
7077
  var import_node_fs5 = require("fs");
6890
7078
  var import_node_path28 = require("path");
6891
- var import_shared59 = require("@rsbuild/shared");
7079
+ var import_shared61 = require("@rsbuild/shared");
6892
7080
  var import_commander = require("../compiled/commander/index.js");
6893
7081
  init_helpers();
6894
7082
  init_init();
@@ -6905,7 +7093,7 @@ var applyServerOptions = (command) => {
6905
7093
  command.option("-o --open [url]", "open the page in browser on startup").option("--port <port>", "specify a port number for server to listen").option("--host <host>", "specify the host that the server listens to");
6906
7094
  };
6907
7095
  function runCli() {
6908
- import_commander.program.name("rsbuild").usage("<command> [options]").version("0.7.2");
7096
+ import_commander.program.name("rsbuild").usage("<command> [options]").version("0.7.3");
6909
7097
  const devCommand = import_commander.program.command("dev");
6910
7098
  const buildCommand = import_commander.program.command("build");
6911
7099
  const previewCommand = import_commander.program.command("preview");
@@ -6919,8 +7107,8 @@ function runCli() {
6919
7107
  const rsbuild = await init({ cliOptions: options });
6920
7108
  await rsbuild?.startDevServer();
6921
7109
  } catch (err) {
6922
- import_shared59.logger.error("Failed to start dev server.");
6923
- import_shared59.logger.error(err);
7110
+ import_shared61.logger.error("Failed to start dev server.");
7111
+ import_shared61.logger.error(err);
6924
7112
  process.exit(1);
6925
7113
  }
6926
7114
  });
@@ -6931,8 +7119,8 @@ function runCli() {
6931
7119
  watch: options.watch
6932
7120
  });
6933
7121
  } catch (err) {
6934
- import_shared59.logger.error("Failed to build.");
6935
- import_shared59.logger.error(err);
7122
+ import_shared61.logger.error("Failed to build.");
7123
+ import_shared61.logger.error(err);
6936
7124
  process.exit(1);
6937
7125
  }
6938
7126
  });
@@ -6943,14 +7131,14 @@ function runCli() {
6943
7131
  const { distPath } = rsbuild.context;
6944
7132
  if (!(0, import_node_fs5.existsSync)(distPath)) {
6945
7133
  throw new Error(
6946
- `The output directory ${import_shared59.color.yellow(
7134
+ `The output directory ${import_shared61.color.yellow(
6947
7135
  distPath
6948
7136
  )} does not exist, please build the project before previewing.`
6949
7137
  );
6950
7138
  }
6951
7139
  if (isEmptyDir(distPath)) {
6952
7140
  throw new Error(
6953
- `The output directory ${import_shared59.color.yellow(
7141
+ `The output directory ${import_shared61.color.yellow(
6954
7142
  distPath
6955
7143
  )} is empty, please build the project before previewing.`
6956
7144
  );
@@ -6958,8 +7146,8 @@ function runCli() {
6958
7146
  }
6959
7147
  await rsbuild?.preview();
6960
7148
  } catch (err) {
6961
- import_shared59.logger.error("Failed to start preview server.");
6962
- import_shared59.logger.error(err);
7149
+ import_shared61.logger.error("Failed to start preview server.");
7150
+ import_shared61.logger.error(err);
6963
7151
  process.exit(1);
6964
7152
  }
6965
7153
  });
@@ -6973,8 +7161,8 @@ function runCli() {
6973
7161
  writeToDisk: true
6974
7162
  });
6975
7163
  } catch (err) {
6976
- import_shared59.logger.error("Failed to inspect config.");
6977
- import_shared59.logger.error(err);
7164
+ import_shared61.logger.error("Failed to inspect config.");
7165
+ import_shared61.logger.error(err);
6978
7166
  process.exit(1);
6979
7167
  }
6980
7168
  });
@@ -6982,7 +7170,7 @@ function runCli() {
6982
7170
  }
6983
7171
 
6984
7172
  // src/cli/prepare.ts
6985
- var import_shared60 = require("@rsbuild/shared");
7173
+ var import_shared62 = require("@rsbuild/shared");
6986
7174
  function initNodeEnv() {
6987
7175
  if (!process.env.NODE_ENV) {
6988
7176
  const command = process.argv[2];
@@ -6995,7 +7183,7 @@ function prepareCli() {
6995
7183
  if (!npm_execpath || npm_execpath.includes("npx-cli.js") || npm_execpath.includes(".bun")) {
6996
7184
  console.log();
6997
7185
  }
6998
- import_shared60.logger.greet(` ${`Rsbuild v${"0.7.2"}`}
7186
+ import_shared62.logger.greet(` ${`Rsbuild v${"0.7.3"}`}
6999
7187
  `);
7000
7188
  }
7001
7189
 
@@ -7018,10 +7206,10 @@ init_prodServer();
7018
7206
  init_loadEnv();
7019
7207
  init_createRsbuild();
7020
7208
  init_config();
7021
- var import_shared61 = require("@rsbuild/shared");
7209
+ var import_shared63 = require("@rsbuild/shared");
7022
7210
  init_mergeConfig();
7023
7211
  init_constants();
7024
- var version = "0.7.2";
7212
+ var version = "0.7.3";
7025
7213
  // Annotate the CommonJS export names for ESM import in node:
7026
7214
  0 && (module.exports = {
7027
7215
  PLUGIN_CSS_NAME,