@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.js CHANGED
@@ -23,12 +23,12 @@ var __publicField = (obj, key, value) => {
23
23
  return value;
24
24
  };
25
25
 
26
- // ../../node_modules/.pnpm/@modern-js+module-tools@2.50.0_eslint@9.4.0_typescript@5.4.5/node_modules/@modern-js/module-tools/shims/esm.js
26
+ // ../../node_modules/.pnpm/@modern-js+module-tools@2.51.0_eslint@9.4.0_typescript@5.4.5/node_modules/@modern-js/module-tools/shims/esm.js
27
27
  import { fileURLToPath } from "url";
28
28
  import path from "path";
29
29
  var getFilename, getDirname, __dirname, __filename;
30
30
  var init_esm = __esm({
31
- "../../node_modules/.pnpm/@modern-js+module-tools@2.50.0_eslint@9.4.0_typescript@5.4.5/node_modules/@modern-js/module-tools/shims/esm.js"() {
31
+ "../../node_modules/.pnpm/@modern-js+module-tools@2.51.0_eslint@9.4.0_typescript@5.4.5/node_modules/@modern-js/module-tools/shims/esm.js"() {
32
32
  "use strict";
33
33
  getFilename = () => fileURLToPath(import.meta.url);
34
34
  getDirname = () => path.dirname(getFilename());
@@ -636,7 +636,10 @@ var init_config = __esm({
636
636
  scriptLoading: "defer"
637
637
  });
638
638
  getDefaultSecurityConfig = () => ({
639
- nonce: ""
639
+ nonce: "",
640
+ sri: {
641
+ enable: false
642
+ }
640
643
  });
641
644
  getDefaultToolsConfig = () => ({
642
645
  cssExtract: {
@@ -757,8 +760,8 @@ var init_config = __esm({
757
760
  import fs2 from "fs";
758
761
  import { join as join3 } from "path";
759
762
  import { getNodeEnv as getNodeEnv2 } from "@rsbuild/shared";
760
- import { expand } from "../compiled/dotenv-expand/index.js";
761
763
  import { parse } from "../compiled/dotenv/index.js";
764
+ import { expand } from "../compiled/dotenv-expand/index.js";
762
765
  function loadEnv({
763
766
  cwd = process.cwd(),
764
767
  mode = getNodeEnv2(),
@@ -889,17 +892,16 @@ import {
889
892
  castArray as castArray2,
890
893
  color as color4,
891
894
  createVirtualModule,
892
- mergeChainedOptions
895
+ reduceConfigsMergeContext
893
896
  } from "@rsbuild/shared";
894
897
  function getEntryObject(config, target) {
895
898
  if (!config.source?.entry) {
896
899
  return {};
897
900
  }
898
- return mergeChainedOptions({
899
- defaults: {},
900
- options: config.source?.entry,
901
- utils: { target },
902
- useObjectParam: true
901
+ return reduceConfigsMergeContext({
902
+ initial: {},
903
+ config: config.source?.entry,
904
+ ctx: { target }
903
905
  });
904
906
  }
905
907
  var pluginEntry;
@@ -967,7 +969,7 @@ async function createContextByConfig(options, bundlerType, config = {}) {
967
969
  return {
968
970
  entry: getEntryObject(config, "web"),
969
971
  targets: config.output?.targets || [],
970
- version: "0.7.2",
972
+ version: "0.7.3",
971
973
  rootPath,
972
974
  distPath,
973
975
  cachePath,
@@ -1443,8 +1445,8 @@ import {
1443
1445
  chainToConfig,
1444
1446
  debug as debug2,
1445
1447
  getNodeEnv as getNodeEnv4,
1446
- mergeChainedOptions as mergeChainedOptions2,
1447
- modifyBundlerChain
1448
+ modifyBundlerChain,
1449
+ reduceConfigsAsyncWithContext
1448
1450
  } from "@rsbuild/shared";
1449
1451
  import { rspack as rspack2 } from "@rspack/core";
1450
1452
  async function modifyRspackConfig(context, rspackConfig, utils) {
@@ -1454,10 +1456,10 @@ async function modifyRspackConfig(context, rspackConfig, utils) {
1454
1456
  utils
1455
1457
  );
1456
1458
  if (context.config.tools?.rspack) {
1457
- modifiedConfig = mergeChainedOptions2({
1458
- defaults: modifiedConfig,
1459
- options: context.config.tools.rspack,
1460
- utils,
1459
+ modifiedConfig = await reduceConfigsAsyncWithContext({
1460
+ initial: modifiedConfig,
1461
+ config: context.config.tools.rspack,
1462
+ ctx: utils,
1461
1463
  mergeFn: utils.mergeConfig
1462
1464
  });
1463
1465
  }
@@ -3325,12 +3327,12 @@ var init_basic = __esm({
3325
3327
  name: "rsbuild:basic",
3326
3328
  setup(api) {
3327
3329
  api.modifyBundlerChain(
3328
- (chain, { env, isProd: isProd4, target, bundler, CHAIN_ID: CHAIN_ID3 }) => {
3330
+ (chain, { env, isProd: isProd5, target, bundler, CHAIN_ID: CHAIN_ID3 }) => {
3329
3331
  const config = api.getNormalizedConfig();
3330
3332
  chain.name(TARGET_ID_MAP2[target]);
3331
3333
  chain.devtool(getJsSourceMap(config));
3332
3334
  chain.context(api.context.rootPath);
3333
- chain.mode(isProd4 ? "production" : "development");
3335
+ chain.mode(isProd5 ? "production" : "development");
3334
3336
  chain.merge({
3335
3337
  infrastructureLogging: {
3336
3338
  // Using `error` level to avoid `cache.PackFileCacheStrategy` logs
@@ -3343,9 +3345,9 @@ var init_basic = __esm({
3343
3345
  exportsPresence: "error"
3344
3346
  }
3345
3347
  });
3346
- const isMinimize = isProd4 && config.output.minify !== false;
3348
+ const isMinimize = isProd5 && config.output.minify !== false;
3347
3349
  chain.optimization.minimize(isMinimize);
3348
- const usingHMR = isUsingHMR(config, { target, isProd: isProd4 });
3350
+ const usingHMR = isUsingHMR(config, { target, isProd: isProd5 });
3349
3351
  if (usingHMR) {
3350
3352
  chain.plugin(CHAIN_ID3.PLUGIN.HMR).use(bundler.HotModuleReplacementPlugin);
3351
3353
  }
@@ -3516,7 +3518,8 @@ import {
3516
3518
  getBrowserslistWithDefault as getBrowserslistWithDefault2,
3517
3519
  isFunction as isFunction5,
3518
3520
  isPlainObject as isPlainObject2,
3519
- mergeChainedOptions as mergeChainedOptions3
3521
+ reduceConfigs,
3522
+ reduceConfigsWithContext
3520
3523
  } from "@rsbuild/shared";
3521
3524
  async function loadUserPostcssrc(root) {
3522
3525
  const cached = userPostcssrcCache.get(root);
@@ -3540,7 +3543,7 @@ async function applyCSSRule({
3540
3543
  rule,
3541
3544
  config,
3542
3545
  context,
3543
- utils: { target, isProd: isProd4, CHAIN_ID: CHAIN_ID3 },
3546
+ utils: { target, isProd: isProd5, CHAIN_ID: CHAIN_ID3 },
3544
3547
  importLoaders = 1
3545
3548
  }) {
3546
3549
  const browserslist = await getBrowserslistWithDefault2(
@@ -3549,7 +3552,7 @@ async function applyCSSRule({
3549
3552
  target
3550
3553
  );
3551
3554
  const enableExtractCSS = isUseCssExtract(config, target);
3552
- const localIdentName = getCSSModulesLocalIdentName(config, isProd4);
3555
+ const localIdentName = getCSSModulesLocalIdentName(config, isProd5);
3553
3556
  const cssLoaderOptions = getCSSLoaderOptions({
3554
3557
  config,
3555
3558
  importLoaders,
@@ -3560,9 +3563,9 @@ async function applyCSSRule({
3560
3563
  if (enableExtractCSS) {
3561
3564
  rule.use(CHAIN_ID3.USE.MINI_CSS_EXTRACT).loader(getCssExtractPlugin().loader).options(config.tools.cssExtract.loaderOptions).end();
3562
3565
  } else {
3563
- const styleLoaderOptions = mergeChainedOptions3({
3564
- defaults: {},
3565
- options: config.tools.styleLoader
3566
+ const styleLoaderOptions = reduceConfigs({
3567
+ initial: {},
3568
+ config: config.tools.styleLoader
3566
3569
  });
3567
3570
  rule.use(CHAIN_ID3.USE.STYLE).loader(getCompiledPath("style-loader")).options(styleLoaderOptions).end();
3568
3571
  }
@@ -3591,8 +3594,8 @@ var init_css = __esm({
3591
3594
  init_pluginHelper();
3592
3595
  enableNativeCss = (config) => !config.output.injectStyles;
3593
3596
  isUseCssExtract = (config, target) => !config.output.injectStyles && target !== "node" && target !== "web-worker";
3594
- getCSSModulesLocalIdentName = (config, isProd4) => config.output.cssModules.localIdentName || // Using shorter classname in production to reduce bundle size
3595
- (isProd4 ? "[local]-[hash:base64:6]" : "[path][name]__[local]-[hash:base64:6]");
3597
+ getCSSModulesLocalIdentName = (config, isProd5) => config.output.cssModules.localIdentName || // Using shorter classname in production to reduce bundle size
3598
+ (isProd5 ? "[local]-[hash:base64:6]" : "[path][name]__[local]-[hash:base64:6]");
3596
3599
  normalizeCssLoaderOptions = (options, exportOnlyLocals) => {
3597
3600
  if (options.modules && exportOnlyLocals) {
3598
3601
  let { modules } = options;
@@ -3629,12 +3632,12 @@ var init_css = __esm({
3629
3632
  });
3630
3633
  if (!hasAutoprefixer) {
3631
3634
  const { default: autoprefixer } = await import("@rsbuild/shared/autoprefixer");
3632
- const autoprefixerOptions = mergeChainedOptions3({
3633
- defaults: {
3635
+ const autoprefixerOptions = reduceConfigs({
3636
+ initial: {
3634
3637
  flexbox: "no-2009",
3635
3638
  overrideBrowserslist: browserslist
3636
3639
  },
3637
- options: config.tools.autoprefixer
3640
+ config: config.tools.autoprefixer
3638
3641
  });
3639
3642
  pluginObjects.push(autoprefixer(autoprefixerOptions));
3640
3643
  }
@@ -3669,10 +3672,10 @@ var init_css = __esm({
3669
3672
  },
3670
3673
  sourceMap: config.output.sourceMap.css
3671
3674
  };
3672
- const mergedConfig = mergeChainedOptions3({
3673
- defaults: defaultPostcssConfig,
3674
- options: config.tools.postcss,
3675
- utils
3675
+ const mergedConfig = reduceConfigsWithContext({
3676
+ initial: defaultPostcssConfig,
3677
+ config: config.tools.postcss,
3678
+ ctx: utils
3676
3679
  });
3677
3680
  if (extraPlugins.length) {
3678
3681
  mergedConfig?.postcssOptions?.plugins.push(...extraPlugins);
@@ -3696,9 +3699,9 @@ var init_css = __esm({
3696
3699
  },
3697
3700
  sourceMap: config.output.sourceMap.css
3698
3701
  };
3699
- const mergedCssLoaderOptions = mergeChainedOptions3({
3700
- defaults: defaultOptions2,
3701
- options: config.tools.cssLoader,
3702
+ const mergedCssLoaderOptions = reduceConfigs({
3703
+ initial: defaultOptions2,
3704
+ config: config.tools.cssLoader,
3702
3705
  mergeFn: deepmerge2
3703
3706
  });
3704
3707
  const cssLoaderOptions = normalizeCssLoaderOptions(
@@ -3748,13 +3751,13 @@ import {
3748
3751
  } from "@rsbuild/shared";
3749
3752
  import { rspack as rspack5 } from "@rspack/core";
3750
3753
  function getPublicPath({
3751
- isProd: isProd4,
3754
+ isProd: isProd5,
3752
3755
  config,
3753
3756
  context
3754
3757
  }) {
3755
3758
  const { dev, output } = config;
3756
3759
  let publicPath = DEFAULT_ASSET_PREFIX3;
3757
- if (isProd4) {
3760
+ if (isProd5) {
3758
3761
  if (typeof output.assetPrefix === "string") {
3759
3762
  publicPath = output.assetPrefix;
3760
3763
  }
@@ -3785,20 +3788,23 @@ var init_output = __esm({
3785
3788
  name: "rsbuild:output",
3786
3789
  setup(api) {
3787
3790
  api.modifyBundlerChain(
3788
- async (chain, { CHAIN_ID: CHAIN_ID3, target, isProd: isProd4, isServer, isServiceWorker }) => {
3791
+ async (chain, { CHAIN_ID: CHAIN_ID3, target, isProd: isProd5, isServer, isServiceWorker }) => {
3789
3792
  const config = api.getNormalizedConfig();
3790
3793
  const publicPath = getPublicPath({
3791
3794
  config,
3792
- isProd: isProd4,
3795
+ isProd: isProd5,
3793
3796
  context: api.context
3794
3797
  });
3795
3798
  const jsPath = getDistPath3(config, "js");
3796
3799
  const jsAsyncPath = getDistPath3(config, "jsAsync");
3797
- const jsFilename = getFilename2(config, "js", isProd4);
3800
+ const jsFilename = getFilename2(config, "js", isProd5);
3798
3801
  chain.output.path(api.context.distPath).filename(posix.join(jsPath, jsFilename)).chunkFilename(posix.join(jsAsyncPath, jsFilename)).publicPath(publicPath).pathinfo(false).hashFunction("xxhash64");
3799
3802
  if (isServer) {
3800
3803
  const serverPath = getDistPath3(config, "server");
3801
- chain.output.path(posix.join(api.context.distPath, serverPath)).filename("[name].js").chunkFilename("[name].js").libraryTarget("commonjs2");
3804
+ chain.output.path(posix.join(api.context.distPath, serverPath)).filename("[name].js").chunkFilename("[name].js").library({
3805
+ ...chain.output.get("library") || {},
3806
+ type: "commonjs2"
3807
+ });
3802
3808
  }
3803
3809
  if (isServiceWorker) {
3804
3810
  const workerPath = getDistPath3(config, "worker");
@@ -3813,7 +3819,7 @@ var init_output = __esm({
3813
3819
  if (isUseCssExtract(config, target)) {
3814
3820
  const extractPluginOptions = config.tools.cssExtract.pluginOptions;
3815
3821
  const cssPath = getDistPath3(config, "css");
3816
- const cssFilename = getFilename2(config, "css", isProd4);
3822
+ const cssFilename = getFilename2(config, "css", isProd5);
3817
3823
  const cssAsyncPath = getDistPath3(config, "cssAsync");
3818
3824
  chain.plugin(CHAIN_ID3.PLUGIN.MINI_CSS_EXTRACT).use(getCssExtractPlugin(), [
3819
3825
  {
@@ -3837,7 +3843,7 @@ __export(resolve_exports, {
3837
3843
  });
3838
3844
  import {
3839
3845
  castArray as castArray4,
3840
- mergeChainedOptions as mergeChainedOptions4
3846
+ reduceConfigsWithContext as reduceConfigsWithContext2
3841
3847
  } from "@rsbuild/shared";
3842
3848
  function applyFullySpecified({
3843
3849
  chain,
@@ -3867,10 +3873,10 @@ function applyAlias({
3867
3873
  if (!alias) {
3868
3874
  return;
3869
3875
  }
3870
- const mergedAlias = mergeChainedOptions4({
3871
- defaults: {},
3872
- options: alias,
3873
- utils: { target }
3876
+ const mergedAlias = reduceConfigsWithContext2({
3877
+ initial: {},
3878
+ config: alias,
3879
+ ctx: { target }
3874
3880
  });
3875
3881
  for (const name of Object.keys(mergedAlias)) {
3876
3882
  const values = castArray4(mergedAlias[name]);
@@ -4202,12 +4208,12 @@ var init_asset = __esm({
4202
4208
  pluginAsset = () => ({
4203
4209
  name: "rsbuild:asset",
4204
4210
  setup(api) {
4205
- api.modifyBundlerChain((chain, { isProd: isProd4, target }) => {
4211
+ api.modifyBundlerChain((chain, { isProd: isProd5, target }) => {
4206
4212
  const config = api.getNormalizedConfig();
4207
4213
  const createAssetRule = (assetType, exts, emit2) => {
4208
4214
  const regExp = getRegExpForExts(exts);
4209
4215
  const distDir = getDistPath4(config, assetType);
4210
- const filename = getFilename3(config, assetType, isProd4);
4216
+ const filename = getFilename3(config, assetType, isProd5);
4211
4217
  const { dataUriLimit } = config.output;
4212
4218
  const maxSize = typeof dataUriLimit === "number" ? dataUriLimit : dataUriLimit[assetType];
4213
4219
  const rule = chain.module.rule(assetType).test(regExp);
@@ -4290,9 +4296,9 @@ var init_minimize = __esm({
4290
4296
  }
4291
4297
  return options;
4292
4298
  };
4293
- parseMinifyOptions = (config, isProd4 = true) => {
4299
+ parseMinifyOptions = (config, isProd5 = true) => {
4294
4300
  const minify = config.output.minify;
4295
- if (minify === false || !isProd4) {
4301
+ if (minify === false || !isProd5) {
4296
4302
  return {
4297
4303
  minifyJs: false,
4298
4304
  minifyCss: false,
@@ -4324,9 +4330,9 @@ var init_minimize = __esm({
4324
4330
  if (api.context.bundlerType === "webpack") {
4325
4331
  return;
4326
4332
  }
4327
- api.modifyBundlerChain(async (chain, { isProd: isProd4 }) => {
4333
+ api.modifyBundlerChain(async (chain, { isProd: isProd5 }) => {
4328
4334
  const config = api.getNormalizedConfig();
4329
- const isMinimize = isProd4 && config.output.minify !== false;
4335
+ const isMinimize = isProd5 && config.output.minify !== false;
4330
4336
  if (!isMinimize) {
4331
4337
  return;
4332
4338
  }
@@ -4534,10 +4540,17 @@ var init_HtmlBasicPlugin = __esm({
4534
4540
  addTitleTag(headTags, data.plugin.options?.title);
4535
4541
  }
4536
4542
  addFavicon(headTags, favicon);
4537
- const result = await this.modifyTagsFn({
4538
- headTags: headTags.map(formatBasicTag),
4539
- bodyTags: bodyTags.map(formatBasicTag)
4540
- });
4543
+ const result = await this.modifyTagsFn(
4544
+ {
4545
+ headTags: headTags.map(formatBasicTag),
4546
+ bodyTags: bodyTags.map(formatBasicTag)
4547
+ },
4548
+ {
4549
+ compilation,
4550
+ assetPrefix: data.publicPath,
4551
+ filename: data.outputName
4552
+ }
4553
+ );
4541
4554
  Object.assign(data, {
4542
4555
  headTags: result.headTags.map(fromBasicTag),
4543
4556
  bodyTags: result.bodyTags.map(fromBasicTag)
@@ -4636,18 +4649,16 @@ __export(html_exports, {
4636
4649
  });
4637
4650
  import path9, { isAbsolute as isAbsolute6 } from "path";
4638
4651
  import {
4639
- applyToCompiler as applyToCompiler2,
4640
4652
  castArray as castArray5,
4641
4653
  color as color11,
4642
- createVirtualModule as createVirtualModule2,
4643
4654
  deepmerge as deepmerge4,
4644
4655
  fse as fse5,
4645
4656
  getDistPath as getDistPath5,
4646
4657
  isHtmlDisabled,
4647
- isNil,
4648
4658
  isPlainObject as isPlainObject3,
4649
4659
  isURL,
4650
- mergeChainedOptions as mergeChainedOptions5
4660
+ reduceConfigsMergeContext as reduceConfigsMergeContext2,
4661
+ reduceConfigsWithContext as reduceConfigsWithContext3
4651
4662
  } from "@rsbuild/shared";
4652
4663
  function applyRemoveConsole(options, config) {
4653
4664
  const { removeConsole } = config.performance;
@@ -4681,8 +4692,8 @@ function getTerserMinifyOptions(config) {
4681
4692
  const finalOptions = applyRemoveConsole(options, config);
4682
4693
  return finalOptions;
4683
4694
  }
4684
- async function getHtmlMinifyOptions(isProd4, config) {
4685
- if (!isProd4 || !config.output.minify || !parseMinifyOptions(config).minifyHtml) {
4695
+ async function getHtmlMinifyOptions(isProd5, config) {
4696
+ if (!isProd5 || !config.output.minify || !parseMinifyOptions(config).minifyHtml) {
4686
4697
  return false;
4687
4698
  }
4688
4699
  const minifyJS = getTerserMinifyOptions(config);
@@ -4703,29 +4714,25 @@ async function getHtmlMinifyOptions(isProd4, config) {
4703
4714
  return typeof htmlMinifyOptions === "object" ? deepmerge4(htmlMinifyDefaultOptions, htmlMinifyOptions) : htmlMinifyDefaultOptions;
4704
4715
  }
4705
4716
  function getTitle(entryName, config) {
4706
- return mergeChainedOptions5({
4707
- defaults: "",
4708
- options: config.html.title,
4709
- utils: { entryName },
4710
- useObjectParam: true
4717
+ return reduceConfigsMergeContext2({
4718
+ initial: "",
4719
+ config: config.html.title,
4720
+ ctx: { entryName }
4711
4721
  });
4712
4722
  }
4713
4723
  function getInject(entryName, config) {
4714
- return mergeChainedOptions5({
4715
- defaults: "head",
4716
- options: config.html.inject,
4717
- utils: { entryName },
4718
- useObjectParam: true,
4719
- isFalsy: isNil
4724
+ return reduceConfigsMergeContext2({
4725
+ initial: "head",
4726
+ config: config.html.inject,
4727
+ ctx: { entryName }
4720
4728
  });
4721
4729
  }
4722
4730
  async function getTemplate(entryName, config, rootPath) {
4723
4731
  const DEFAULT_TEMPLATE = path9.resolve(STATIC_PATH, "template.html");
4724
- const templatePath = mergeChainedOptions5({
4725
- defaults: DEFAULT_TEMPLATE,
4726
- options: config.html.template,
4727
- utils: { entryName },
4728
- useObjectParam: true
4732
+ const templatePath = reduceConfigsMergeContext2({
4733
+ initial: DEFAULT_TEMPLATE,
4734
+ config: config.html.template,
4735
+ ctx: { entryName }
4729
4736
  });
4730
4737
  if (templatePath === DEFAULT_TEMPLATE) {
4731
4738
  return {
@@ -4750,19 +4757,17 @@ async function getTemplate(entryName, config, rootPath) {
4750
4757
  };
4751
4758
  }
4752
4759
  function getFavicon(entryName, config) {
4753
- return mergeChainedOptions5({
4754
- defaults: "",
4755
- options: config.html.favicon,
4756
- utils: { entryName },
4757
- useObjectParam: true
4760
+ return reduceConfigsMergeContext2({
4761
+ initial: "",
4762
+ config: config.html.favicon,
4763
+ ctx: { entryName }
4758
4764
  });
4759
4765
  }
4760
4766
  function getMetaTags(entryName, config, templateContent) {
4761
- const metaTags = mergeChainedOptions5({
4762
- defaults: {},
4763
- options: config.html.meta,
4764
- utils: { entryName },
4765
- useObjectParam: true
4767
+ const metaTags = reduceConfigsMergeContext2({
4768
+ initial: {},
4769
+ config: config.html.meta,
4770
+ ctx: { entryName }
4766
4771
  });
4767
4772
  if (templateContent && metaTags.charset) {
4768
4773
  const charsetRegExp = /<meta[^>]+charset=["'][^>]*>/i;
@@ -4787,10 +4792,10 @@ function getTemplateParameters(entryName, config, assetPrefix) {
4787
4792
  options: pluginOptions
4788
4793
  }
4789
4794
  };
4790
- return mergeChainedOptions5({
4791
- defaults: defaultOptions2,
4792
- options: templateParameters,
4793
- utils: { entryName }
4795
+ return reduceConfigsWithContext3({
4796
+ initial: defaultOptions2,
4797
+ config: templateParameters,
4798
+ ctx: { entryName }
4794
4799
  });
4795
4800
  };
4796
4801
  }
@@ -4838,12 +4843,12 @@ var init_html = __esm({
4838
4843
  name: "rsbuild:html",
4839
4844
  setup(api) {
4840
4845
  api.modifyBundlerChain(
4841
- async (chain, { HtmlPlugin, isProd: isProd4, CHAIN_ID: CHAIN_ID3, target }) => {
4846
+ async (chain, { HtmlPlugin, isProd: isProd5, CHAIN_ID: CHAIN_ID3, target }) => {
4842
4847
  const config = api.getNormalizedConfig();
4843
4848
  if (isHtmlDisabled(config, target)) {
4844
4849
  return;
4845
4850
  }
4846
- const minify = await getHtmlMinifyOptions(isProd4, config);
4851
+ const minify = await getHtmlMinifyOptions(isProd5, config);
4847
4852
  const assetPrefix = getPublicPathFromChain(chain, false);
4848
4853
  const entries = chain.entryPoints.entries() || {};
4849
4854
  const entryNames = Object.keys(entries);
@@ -4852,11 +4857,7 @@ var init_html = __esm({
4852
4857
  const finalOptions = await Promise.all(
4853
4858
  entryNames.map(async (entryName) => {
4854
4859
  const entryValue = entries[entryName].values();
4855
- const chunks = getChunks(
4856
- entryName,
4857
- // EntryDescription type is different between webpack and Rspack
4858
- entryValue
4859
- );
4860
+ const chunks = getChunks(entryName, entryValue);
4860
4861
  const inject = getInject(entryName, config);
4861
4862
  const filename = htmlPaths[entryName];
4862
4863
  const { templatePath, templateContent } = await getTemplate(
@@ -4902,13 +4903,10 @@ var init_html = __esm({
4902
4903
  pluginOptions.favicon = favicon;
4903
4904
  }
4904
4905
  }
4905
- const finalOptions2 = mergeChainedOptions5({
4906
- defaults: pluginOptions,
4907
- options: typeof config.tools.htmlPlugin === "boolean" ? {} : config.tools.htmlPlugin,
4908
- utils: {
4909
- entryName,
4910
- entryValue
4911
- }
4906
+ const finalOptions2 = reduceConfigsWithContext3({
4907
+ initial: pluginOptions,
4908
+ config: typeof config.tools.htmlPlugin === "boolean" ? {} : config.tools.htmlPlugin,
4909
+ ctx: { entryName, entryValue }
4912
4910
  });
4913
4911
  return finalOptions2;
4914
4912
  })
@@ -4933,52 +4931,21 @@ var init_html = __esm({
4933
4931
  }
4934
4932
  }
4935
4933
  );
4936
- api.onAfterCreateCompiler(({ compiler }) => {
4937
- const { nonce } = api.getNormalizedConfig().security;
4938
- if (!nonce) {
4939
- return;
4940
- }
4941
- applyToCompiler2(compiler, (compiler2) => {
4942
- const { plugins } = compiler2.options;
4943
- const hasHTML = plugins.some(
4944
- (plugin) => plugin && plugin.constructor.name === "HtmlBasicPlugin"
4945
- );
4946
- if (!hasHTML) {
4947
- return;
4948
- }
4949
- const injectCode = createVirtualModule2(
4950
- `__webpack_nonce__ = "${nonce}";`
4951
- );
4952
- new compiler2.webpack.EntryPlugin(compiler2.context, injectCode, {
4953
- name: void 0
4954
- }).apply(compiler2);
4955
- });
4956
- });
4957
4934
  api.modifyHTMLTags({
4958
4935
  // ensure `crossorigin` and `nonce` can be applied to all tags
4959
4936
  order: "post",
4960
4937
  handler: ({ headTags, bodyTags }) => {
4961
4938
  const config = api.getNormalizedConfig();
4962
4939
  const { crossorigin } = config.html;
4963
- const { nonce } = config.security;
4964
4940
  const allTags = [...headTags, ...bodyTags];
4965
4941
  if (crossorigin) {
4966
4942
  const formattedCrossorigin = crossorigin === true ? "anonymous" : crossorigin;
4967
4943
  for (const tag of allTags) {
4968
4944
  if (tag.tag === "script" && tag.attrs?.src || tag.tag === "link" && tag.attrs?.rel === "stylesheet") {
4969
- tag.attrs ||= {};
4970
4945
  tag.attrs.crossorigin ??= formattedCrossorigin;
4971
4946
  }
4972
4947
  }
4973
4948
  }
4974
- if (nonce) {
4975
- for (const tag of allTags) {
4976
- if (tag.tag === "script" || tag.tag === "style") {
4977
- tag.attrs ??= {};
4978
- tag.attrs.nonce = nonce;
4979
- }
4980
- }
4981
- }
4982
4949
  return { headTags, bodyTags };
4983
4950
  }
4984
4951
  });
@@ -5188,7 +5155,7 @@ import {
5188
5155
  getBrowserslistWithDefault as getBrowserslistWithDefault3,
5189
5156
  getCoreJsVersion,
5190
5157
  isWebTarget,
5191
- mergeChainedOptions as mergeChainedOptions6
5158
+ reduceConfigs as reduceConfigs2
5192
5159
  } from "@rsbuild/shared";
5193
5160
  async function getDefaultSwcConfig(config, rootPath, target) {
5194
5161
  return {
@@ -5294,9 +5261,9 @@ var init_swc = __esm({
5294
5261
  await applyCoreJs(swcConfig, chain, polyfillMode);
5295
5262
  }
5296
5263
  }
5297
- const mergedSwcConfig = mergeChainedOptions6({
5298
- defaults: swcConfig,
5299
- options: config.tools.swc,
5264
+ const mergedSwcConfig = reduceConfigs2({
5265
+ initial: swcConfig,
5266
+ config: config.tools.swc,
5300
5267
  mergeFn: deepmerge5
5301
5268
  });
5302
5269
  rule.use(CHAIN_ID3.USE.SWC).loader(builtinSwcLoaderName).options(mergedSwcConfig);
@@ -6782,8 +6749,8 @@ var init_lazyCompilation = __esm({
6782
6749
  pluginLazyCompilation = () => ({
6783
6750
  name: "rsbuild:lazy-compilation",
6784
6751
  setup(api) {
6785
- api.modifyBundlerChain((chain, { isProd: isProd4, target }) => {
6786
- if (isProd4 || target !== "web") {
6752
+ api.modifyBundlerChain((chain, { isProd: isProd5, target }) => {
6753
+ if (isProd5 || target !== "web") {
6787
6754
  return;
6788
6755
  }
6789
6756
  const config = api.getNormalizedConfig();
@@ -6843,6 +6810,229 @@ var init_lazyCompilation = __esm({
6843
6810
  }
6844
6811
  });
6845
6812
 
6813
+ // src/plugins/sri.ts
6814
+ var sri_exports = {};
6815
+ __export(sri_exports, {
6816
+ pluginSri: () => pluginSri
6817
+ });
6818
+ import crypto2 from "crypto";
6819
+ import {
6820
+ isHtmlDisabled as isHtmlDisabled4,
6821
+ isProd as isProd4,
6822
+ logger as logger16,
6823
+ removeLeadingSlash as removeLeadingSlash2
6824
+ } from "@rsbuild/shared";
6825
+ var getAssetName, pluginSri;
6826
+ var init_sri = __esm({
6827
+ "src/plugins/sri.ts"() {
6828
+ "use strict";
6829
+ init_esm();
6830
+ init_constants();
6831
+ getAssetName = (url2, assetPrefix) => {
6832
+ if (url2.startsWith(assetPrefix)) {
6833
+ return removeLeadingSlash2(url2.replace(assetPrefix, ""));
6834
+ }
6835
+ return removeLeadingSlash2(url2);
6836
+ };
6837
+ pluginSri = () => ({
6838
+ name: "rsbuild:sri",
6839
+ setup(api) {
6840
+ const placeholder = "RSBUILD_INTEGRITY_PLACEHOLDER:";
6841
+ const getAlgorithm = () => {
6842
+ const config = api.getNormalizedConfig();
6843
+ const { sri } = config.security;
6844
+ const enable = sri.enable === "auto" ? isProd4() : sri.enable;
6845
+ if (!enable) {
6846
+ return null;
6847
+ }
6848
+ const { algorithm = "sha384" } = sri;
6849
+ return algorithm;
6850
+ };
6851
+ api.modifyHTMLTags({
6852
+ // ensure `sri` can be applied to all tags
6853
+ order: "post",
6854
+ handler(tags, { assetPrefix }) {
6855
+ const algorithm = getAlgorithm();
6856
+ if (!algorithm) {
6857
+ return tags;
6858
+ }
6859
+ const allTags = [...tags.headTags, ...tags.bodyTags];
6860
+ for (const tag of allTags) {
6861
+ let url2 = "";
6862
+ if (!tag.attrs) {
6863
+ continue;
6864
+ }
6865
+ if (tag.tag === "script" && typeof tag.attrs.src === "string") {
6866
+ url2 = tag.attrs.src;
6867
+ } else if (tag.tag === "link" && tag.attrs.rel === "stylesheet" && typeof tag.attrs.href === "string") {
6868
+ url2 = tag.attrs.href;
6869
+ }
6870
+ if (!url2) {
6871
+ continue;
6872
+ }
6873
+ const assetName = getAssetName(url2, assetPrefix);
6874
+ if (!assetName) {
6875
+ continue;
6876
+ }
6877
+ tag.attrs.integrity ??= `${placeholder}${assetName}`;
6878
+ }
6879
+ return tags;
6880
+ }
6881
+ });
6882
+ const replaceIntegrity = (htmlContent, assets, algorithm, integrityCache) => {
6883
+ const regex = /integrity="RSBUILD_INTEGRITY_PLACEHOLDER:([^"]+)"/g;
6884
+ const matches = htmlContent.matchAll(regex);
6885
+ let replacedHtml = htmlContent;
6886
+ const calcIntegrity = (algorithm2, assetName, data) => {
6887
+ if (integrityCache.has(assetName)) {
6888
+ return integrityCache.get(assetName);
6889
+ }
6890
+ const hash = crypto2.createHash(algorithm2).update(data).digest().toString("base64");
6891
+ const integrity = `${algorithm2}-${hash}`;
6892
+ integrityCache.set(assetName, integrity);
6893
+ return integrity;
6894
+ };
6895
+ for (const match of matches) {
6896
+ const assetName = match[1];
6897
+ if (!assetName) {
6898
+ continue;
6899
+ }
6900
+ if (assets[assetName]) {
6901
+ const integrity = calcIntegrity(
6902
+ algorithm,
6903
+ assetName,
6904
+ assets[assetName].buffer()
6905
+ );
6906
+ replacedHtml = replacedHtml.replaceAll(
6907
+ `integrity="${placeholder}${assetName}"`,
6908
+ `integrity="${integrity}"`
6909
+ );
6910
+ } else {
6911
+ logger16.debug(
6912
+ `[rsbuild:sri] failed to generate integrity for ${assetName}.`
6913
+ );
6914
+ replacedHtml = replacedHtml.replace(
6915
+ `integrity="${placeholder}${assetName}"`,
6916
+ ""
6917
+ );
6918
+ }
6919
+ }
6920
+ return replacedHtml;
6921
+ };
6922
+ class SriReplaceIntegrityPlugin {
6923
+ constructor(algorithm) {
6924
+ __publicField(this, "algorithm");
6925
+ this.algorithm = algorithm;
6926
+ }
6927
+ apply(compiler) {
6928
+ compiler.hooks.compilation.tap(
6929
+ "SriReplaceIntegrityPlugin",
6930
+ (compilation) => {
6931
+ compilation.hooks.processAssets.tapPromise(
6932
+ {
6933
+ name: "SriReplaceIntegrityPlugin",
6934
+ // use to final stage to get the final asset content
6935
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT
6936
+ },
6937
+ async (assets) => {
6938
+ const integrityCache = /* @__PURE__ */ new Map();
6939
+ for (const asset of Object.keys(assets)) {
6940
+ if (!HTML_REGEX.test(asset)) {
6941
+ continue;
6942
+ }
6943
+ const htmlContent = assets[asset].source();
6944
+ if (!htmlContent.includes(placeholder)) {
6945
+ continue;
6946
+ }
6947
+ assets[asset] = new compiler.webpack.sources.RawSource(
6948
+ replaceIntegrity(
6949
+ htmlContent,
6950
+ assets,
6951
+ this.algorithm,
6952
+ integrityCache
6953
+ )
6954
+ );
6955
+ }
6956
+ }
6957
+ );
6958
+ }
6959
+ );
6960
+ }
6961
+ }
6962
+ api.modifyBundlerChain((chain, { target }) => {
6963
+ const config = api.getNormalizedConfig();
6964
+ if (isHtmlDisabled4(config, target)) {
6965
+ return;
6966
+ }
6967
+ const algorithm = getAlgorithm();
6968
+ if (!algorithm) {
6969
+ return;
6970
+ }
6971
+ chain.plugin("rsbuild-sri-replace").use(SriReplaceIntegrityPlugin, [algorithm]);
6972
+ });
6973
+ }
6974
+ });
6975
+ }
6976
+ });
6977
+
6978
+ // src/plugins/nonce.ts
6979
+ var nonce_exports = {};
6980
+ __export(nonce_exports, {
6981
+ pluginNonce: () => pluginNonce
6982
+ });
6983
+ import { applyToCompiler as applyToCompiler2, createVirtualModule as createVirtualModule2 } from "@rsbuild/shared";
6984
+ var pluginNonce;
6985
+ var init_nonce = __esm({
6986
+ "src/plugins/nonce.ts"() {
6987
+ "use strict";
6988
+ init_esm();
6989
+ pluginNonce = () => ({
6990
+ name: "rsbuild:nonce",
6991
+ setup(api) {
6992
+ api.onAfterCreateCompiler(({ compiler }) => {
6993
+ const { nonce } = api.getNormalizedConfig().security;
6994
+ if (!nonce) {
6995
+ return;
6996
+ }
6997
+ applyToCompiler2(compiler, (compiler2) => {
6998
+ const { plugins } = compiler2.options;
6999
+ const hasHTML = plugins.some(
7000
+ (plugin) => plugin && plugin.constructor.name === "HtmlBasicPlugin"
7001
+ );
7002
+ if (!hasHTML) {
7003
+ return;
7004
+ }
7005
+ const injectCode = createVirtualModule2(
7006
+ `__webpack_nonce__ = "${nonce}";`
7007
+ );
7008
+ new compiler2.webpack.EntryPlugin(compiler2.context, injectCode, {
7009
+ name: void 0
7010
+ }).apply(compiler2);
7011
+ });
7012
+ });
7013
+ api.modifyHTMLTags({
7014
+ // ensure `nonce` can be applied to all tags
7015
+ order: "post",
7016
+ handler: ({ headTags, bodyTags }) => {
7017
+ const config = api.getNormalizedConfig();
7018
+ const { nonce } = config.security;
7019
+ const allTags = [...headTags, ...bodyTags];
7020
+ if (nonce) {
7021
+ for (const tag of allTags) {
7022
+ if (tag.tag === "script" || tag.tag === "style") {
7023
+ tag.attrs ??= {};
7024
+ tag.attrs.nonce = nonce;
7025
+ }
7026
+ }
7027
+ }
7028
+ return { headTags, bodyTags };
7029
+ }
7030
+ });
7031
+ }
7032
+ });
7033
+ }
7034
+ });
7035
+
6846
7036
  // src/createRsbuild.ts
6847
7037
  var createRsbuild_exports = {};
6848
7038
  __export(createRsbuild_exports, {
@@ -6882,6 +7072,8 @@ async function applyDefaultPlugins(pluginManager, context) {
6882
7072
  const { pluginModuleFederation: pluginModuleFederation2 } = await Promise.resolve().then(() => (init_moduleFederation(), moduleFederation_exports));
6883
7073
  const { pluginRspackProfile: pluginRspackProfile2 } = await Promise.resolve().then(() => (init_rspackProfile(), rspackProfile_exports));
6884
7074
  const { pluginLazyCompilation: pluginLazyCompilation2 } = await Promise.resolve().then(() => (init_lazyCompilation(), lazyCompilation_exports));
7075
+ const { pluginSri: pluginSri2 } = await Promise.resolve().then(() => (init_sri(), sri_exports));
7076
+ const { pluginNonce: pluginNonce2 } = await Promise.resolve().then(() => (init_nonce(), nonce_exports));
6885
7077
  pluginManager.addPlugins([
6886
7078
  pluginBasic2(),
6887
7079
  pluginEntry2(),
@@ -6893,8 +7085,8 @@ async function applyDefaultPlugins(pluginManager, context) {
6893
7085
  // cleanOutput plugin should before the html plugin
6894
7086
  pluginCleanOutput2(),
6895
7087
  pluginAsset2(),
6896
- pluginHtml2(async (tags) => {
6897
- const result = await context.hooks.modifyHTMLTags.call(tags);
7088
+ pluginHtml2(async (...args) => {
7089
+ const result = await context.hooks.modifyHTMLTags.call(...args);
6898
7090
  return result[0];
6899
7091
  }),
6900
7092
  pluginWasm2(),
@@ -6917,7 +7109,9 @@ async function applyDefaultPlugins(pluginManager, context) {
6917
7109
  pluginManifest2(),
6918
7110
  pluginModuleFederation2(),
6919
7111
  pluginRspackProfile2(),
6920
- pluginLazyCompilation2()
7112
+ pluginLazyCompilation2(),
7113
+ pluginSri2(),
7114
+ pluginNonce2()
6921
7115
  ]);
6922
7116
  }
6923
7117
  async function createRsbuild(options = {}) {
@@ -7017,7 +7211,7 @@ var init_createRsbuild = __esm({
7017
7211
  });
7018
7212
 
7019
7213
  // src/cli/init.ts
7020
- import { isDev as isDev2, logger as logger16 } from "@rsbuild/shared";
7214
+ import { isDev as isDev2, logger as logger17 } from "@rsbuild/shared";
7021
7215
  async function init({
7022
7216
  cliOptions,
7023
7217
  isRestart
@@ -7071,7 +7265,7 @@ async function init({
7071
7265
  });
7072
7266
  } catch (err) {
7073
7267
  if (isRestart) {
7074
- logger16.error(err);
7268
+ logger17.error(err);
7075
7269
  } else {
7076
7270
  throw err;
7077
7271
  }
@@ -7121,7 +7315,7 @@ init_helpers();
7121
7315
  init_init();
7122
7316
  import { existsSync } from "fs";
7123
7317
  import { join as join12 } from "path";
7124
- import { color as color13, logger as logger17 } from "@rsbuild/shared";
7318
+ import { color as color13, logger as logger18 } from "@rsbuild/shared";
7125
7319
  import { program } from "../compiled/commander/index.js";
7126
7320
  var applyCommonOptions = (command) => {
7127
7321
  command.option(
@@ -7136,7 +7330,7 @@ var applyServerOptions = (command) => {
7136
7330
  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");
7137
7331
  };
7138
7332
  function runCli() {
7139
- program.name("rsbuild").usage("<command> [options]").version("0.7.2");
7333
+ program.name("rsbuild").usage("<command> [options]").version("0.7.3");
7140
7334
  const devCommand = program.command("dev");
7141
7335
  const buildCommand = program.command("build");
7142
7336
  const previewCommand = program.command("preview");
@@ -7150,8 +7344,8 @@ function runCli() {
7150
7344
  const rsbuild = await init({ cliOptions: options });
7151
7345
  await rsbuild?.startDevServer();
7152
7346
  } catch (err) {
7153
- logger17.error("Failed to start dev server.");
7154
- logger17.error(err);
7347
+ logger18.error("Failed to start dev server.");
7348
+ logger18.error(err);
7155
7349
  process.exit(1);
7156
7350
  }
7157
7351
  });
@@ -7162,8 +7356,8 @@ function runCli() {
7162
7356
  watch: options.watch
7163
7357
  });
7164
7358
  } catch (err) {
7165
- logger17.error("Failed to build.");
7166
- logger17.error(err);
7359
+ logger18.error("Failed to build.");
7360
+ logger18.error(err);
7167
7361
  process.exit(1);
7168
7362
  }
7169
7363
  });
@@ -7189,8 +7383,8 @@ function runCli() {
7189
7383
  }
7190
7384
  await rsbuild?.preview();
7191
7385
  } catch (err) {
7192
- logger17.error("Failed to start preview server.");
7193
- logger17.error(err);
7386
+ logger18.error("Failed to start preview server.");
7387
+ logger18.error(err);
7194
7388
  process.exit(1);
7195
7389
  }
7196
7390
  });
@@ -7204,8 +7398,8 @@ function runCli() {
7204
7398
  writeToDisk: true
7205
7399
  });
7206
7400
  } catch (err) {
7207
- logger17.error("Failed to inspect config.");
7208
- logger17.error(err);
7401
+ logger18.error("Failed to inspect config.");
7402
+ logger18.error(err);
7209
7403
  process.exit(1);
7210
7404
  }
7211
7405
  });
@@ -7214,7 +7408,7 @@ function runCli() {
7214
7408
 
7215
7409
  // src/cli/prepare.ts
7216
7410
  init_esm();
7217
- import { logger as logger18 } from "@rsbuild/shared";
7411
+ import { logger as logger19 } from "@rsbuild/shared";
7218
7412
  function initNodeEnv() {
7219
7413
  if (!process.env.NODE_ENV) {
7220
7414
  const command = process.argv[2];
@@ -7227,7 +7421,7 @@ function prepareCli() {
7227
7421
  if (!npm_execpath || npm_execpath.includes("npx-cli.js") || npm_execpath.includes(".bun")) {
7228
7422
  console.log();
7229
7423
  }
7230
- logger18.greet(` ${`Rsbuild v${"0.7.2"}`}
7424
+ logger19.greet(` ${`Rsbuild v${"0.7.3"}`}
7231
7425
  `);
7232
7426
  }
7233
7427
 
@@ -7253,8 +7447,8 @@ init_createRsbuild();
7253
7447
  init_config();
7254
7448
  init_mergeConfig();
7255
7449
  init_constants();
7256
- import { logger as logger19 } from "@rsbuild/shared";
7257
- var version = "0.7.2";
7450
+ import { logger as logger20 } from "@rsbuild/shared";
7451
+ var version = "0.7.3";
7258
7452
  export {
7259
7453
  PLUGIN_CSS_NAME,
7260
7454
  PLUGIN_SWC_NAME,
@@ -7263,7 +7457,7 @@ export {
7263
7457
  defineConfig,
7264
7458
  loadConfig,
7265
7459
  loadEnv,
7266
- logger19 as logger,
7460
+ logger20 as logger,
7267
7461
  mergeRsbuildConfig,
7268
7462
  rspack10 as rspack,
7269
7463
  version