@rsbuild/core 1.4.6 → 1.4.8

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
@@ -12,12 +12,12 @@ import node_os, { constants as external_node_os_constants } from "node:os";
12
12
  import node_process from "node:process";
13
13
  import rspack_chain from "../compiled/rspack-chain/index.js";
14
14
  import { isPromise, isRegExp } from "node:util/types";
15
- import node_util, { promisify as external_node_util_promisify } from "node:util";
15
+ import { promisify as external_node_util_promisify } from "node:util";
16
16
  import { lookup } from "../compiled/mrmime/index.js";
17
17
  import node_zlib from "node:zlib";
18
18
  import { Buffer as external_node_buffer_Buffer } from "node:buffer";
19
19
  import node_child_process, { execFile } from "node:child_process";
20
- import promises from "node:fs/promises";
20
+ import promises, { constants as promises_constants } from "node:fs/promises";
21
21
  var EsmMode, __webpack_modules__ = {
22
22
  "../../node_modules/.pnpm/clone-deep@4.0.1/node_modules/clone-deep/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
23
23
  let clone = __webpack_require__("../../node_modules/.pnpm/shallow-clone@3.0.1/node_modules/shallow-clone/index.js"), typeOf = __webpack_require__("../../node_modules/.pnpm/kind-of@6.0.3/node_modules/kind-of/index.js"), isPlainObject = __webpack_require__("../../node_modules/.pnpm/is-plain-object@2.0.4/node_modules/is-plain-object/index.js");
@@ -1428,47 +1428,6 @@ class CAC extends EventEmitter {
1428
1428
  }), actionArgs.push(options), command.commandAction.apply(this, actionArgs);
1429
1429
  }
1430
1430
  }
1431
- let RSBUILD_ALL_ENVIRONMENT_SYMBOL = 'RSBUILD_ALL_ENVIRONMENT_SYMBOL', isPluginMatchEnvironment = (pluginEnvironment, currentEnvironment)=>pluginEnvironment === currentEnvironment || pluginEnvironment === RSBUILD_ALL_ENVIRONMENT_SYMBOL;
1432
- async function initPlugins({ getPluginAPI, pluginManager }) {
1433
- logger.debug('init plugins');
1434
- let plugins = ((plugins)=>{
1435
- let allLines = [];
1436
- function getPlugin(name) {
1437
- let targets = plugins.filter((item)=>item.instance.name === name);
1438
- if (!targets.length) throw Error(`${picocolors.dim('[rsbuild:plugin]')} Plugin "${picocolors.yellow(name)}" not existed`);
1439
- return targets;
1440
- }
1441
- for (let plugin of plugins){
1442
- if (plugin.instance.pre) for (let pre of plugin.instance.pre)pre && plugins.some((item)=>item.instance.name === pre) && allLines.push([
1443
- pre,
1444
- plugin.instance.name
1445
- ]);
1446
- if (plugin.instance.post) for (let post of plugin.instance.post)post && plugins.some((item)=>item.instance.name === post) && allLines.push([
1447
- plugin.instance.name,
1448
- post
1449
- ]);
1450
- }
1451
- let zeroEndPoints = plugins.filter((item)=>!allLines.find((l)=>l[1] === item.instance.name)), sortedPoint = [];
1452
- for(; zeroEndPoints.length;){
1453
- let zep = zeroEndPoints.shift();
1454
- sortedPoint.push(...getPlugin(zep.instance.name)), allLines = allLines.filter((l)=>l[0] !== getPlugin(zep.instance.name)[0].instance.name), zeroEndPoints = plugins.filter((item)=>!sortedPoint.find((sp)=>sp.instance.name === item.instance.name)).filter((item)=>!allLines.find((l)=>l[1] === item.instance.name));
1455
- }
1456
- if (allLines.length) {
1457
- let restInRingPoints = {};
1458
- for (let l of allLines)restInRingPoints[l[0]] = !0, restInRingPoints[l[1]] = !0;
1459
- throw Error(`${picocolors.dim('[rsbuild:plugin]')} Plugins dependencies has loop: ${picocolors.yellow(Object.keys(restInRingPoints).join(','))}`);
1460
- }
1461
- return sortedPoint;
1462
- })(pluginManager.getAllPluginsWithMeta()), removedPlugins = plugins.reduce((ret, plugin)=>(plugin.instance.remove && (ret[plugin.environment] ??= [], ret[plugin.environment].push(...plugin.instance.remove)), ret), {});
1463
- for (let plugin of plugins){
1464
- var _removedPlugins_plugin_environment, _removedPlugins_RSBUILD_ALL_ENVIRONMENT_SYMBOL;
1465
- let isGlobalPlugin = 'RSBUILD_ALL_ENVIRONMENT_SYMBOL' === plugin.environment;
1466
- if ((null == (_removedPlugins_plugin_environment = removedPlugins[plugin.environment]) ? void 0 : _removedPlugins_plugin_environment.includes(plugin.instance.name)) || !isGlobalPlugin && (null == (_removedPlugins_RSBUILD_ALL_ENVIRONMENT_SYMBOL = removedPlugins[RSBUILD_ALL_ENVIRONMENT_SYMBOL]) ? void 0 : _removedPlugins_RSBUILD_ALL_ENVIRONMENT_SYMBOL.includes(plugin.instance.name))) continue;
1467
- let { instance, environment } = plugin;
1468
- await instance.setup(getPluginAPI(environment));
1469
- }
1470
- logger.debug('init plugins done');
1471
- }
1472
1431
  function createEnvironmentAsyncHook() {
1473
1432
  let preGroup = [], postGroup = [], defaultGroup = [], tapEnvironment = ({ environment, handler: cb })=>{
1474
1433
  isFunction(cb) ? defaultGroup.push({
@@ -1496,7 +1455,7 @@ function createEnvironmentAsyncHook() {
1496
1455
  ...defaultGroup,
1497
1456
  ...postGroup
1498
1457
  ]){
1499
- if (callback.environment && environment && !isPluginMatchEnvironment(callback.environment, environment)) continue;
1458
+ if (environment && callback.environment && callback.environment !== environment) continue;
1500
1459
  let result = await callback.handler(...params);
1501
1460
  void 0 !== result && (params[0] = result);
1502
1461
  }
@@ -1509,7 +1468,7 @@ function createEnvironmentAsyncHook() {
1509
1468
  ...defaultGroup,
1510
1469
  ...postGroup
1511
1470
  ]){
1512
- if (callback.environment && environment && !isPluginMatchEnvironment(callback.environment, environment)) continue;
1471
+ if (environment && callback.environment && callback.environment !== environment) continue;
1513
1472
  let result = await callback.handler(...params);
1514
1473
  results.push(result);
1515
1474
  }
@@ -1946,6 +1905,57 @@ function exit(exitCode, type) {
1946
1905
  }
1947
1906
  }
1948
1907
  }
1908
+ let isEnvironmentMatch = (pluginEnvironment, specifiedEnvironment)=>pluginEnvironment === specifiedEnvironment || void 0 === pluginEnvironment;
1909
+ async function initPlugins({ context, pluginManager }) {
1910
+ logger.debug('init plugins');
1911
+ let plugins = ((plugins)=>{
1912
+ let allLines = [];
1913
+ function getPlugin(name) {
1914
+ let targets = plugins.filter((item)=>item.instance.name === name);
1915
+ if (!targets.length) throw Error(`${picocolors.dim('[rsbuild:plugin]')} Plugin "${picocolors.yellow(name)}" not existed`);
1916
+ return targets;
1917
+ }
1918
+ for (let plugin of plugins){
1919
+ if (plugin.instance.pre) for (let pre of plugin.instance.pre)pre && plugins.some((item)=>item.instance.name === pre) && allLines.push([
1920
+ pre,
1921
+ plugin.instance.name
1922
+ ]);
1923
+ if (plugin.instance.post) for (let post of plugin.instance.post)post && plugins.some((item)=>item.instance.name === post) && allLines.push([
1924
+ plugin.instance.name,
1925
+ post
1926
+ ]);
1927
+ }
1928
+ let zeroEndPoints = plugins.filter((item)=>!allLines.find((l)=>l[1] === item.instance.name)), sortedPoint = [];
1929
+ for(; zeroEndPoints.length;){
1930
+ let zep = zeroEndPoints.shift();
1931
+ sortedPoint.push(...getPlugin(zep.instance.name)), allLines = allLines.filter((l)=>l[0] !== getPlugin(zep.instance.name)[0].instance.name), zeroEndPoints = plugins.filter((item)=>!sortedPoint.find((sp)=>sp.instance.name === item.instance.name)).filter((item)=>!allLines.find((l)=>l[1] === item.instance.name));
1932
+ }
1933
+ if (allLines.length) {
1934
+ let restInRingPoints = {};
1935
+ for (let l of allLines)restInRingPoints[l[0]] = !0, restInRingPoints[l[1]] = !0;
1936
+ throw Error(`${picocolors.dim('[rsbuild:plugin]')} Plugins dependencies has loop: ${picocolors.yellow(Object.keys(restInRingPoints).join(','))}`);
1937
+ }
1938
+ return sortedPoint;
1939
+ })(pluginManager.getAllPluginsWithMeta()), removedPlugins = new Set(), removedEnvPlugins = {};
1940
+ for (let { environment, instance } of plugins)if (instance.remove) if (environment) for (let item of (removedEnvPlugins[environment] ??= new Set(), instance.remove))removedEnvPlugins[environment].add(item);
1941
+ else for (let item of instance.remove)removedPlugins.add(item);
1942
+ for (let { instance, environment } of plugins){
1943
+ var _removedEnvPlugins_environment;
1944
+ let { name, setup } = instance;
1945
+ if (!(removedPlugins.has(name) || environment && (null == (_removedEnvPlugins_environment = removedEnvPlugins[environment]) ? void 0 : _removedEnvPlugins_environment.has(name)))) {
1946
+ if (instance.apply && context.action) {
1947
+ let expected = {
1948
+ build: 'build',
1949
+ dev: 'serve',
1950
+ preview: 'serve'
1951
+ }[context.action];
1952
+ if (expected && instance.apply !== expected) continue;
1953
+ }
1954
+ await setup(context.getPluginAPI(environment));
1955
+ }
1956
+ }
1957
+ logger.debug('init plugins done');
1958
+ }
1949
1959
  let mapProcessAssetsStage = (compiler, stage)=>{
1950
1960
  let { Compilation } = compiler.webpack;
1951
1961
  switch(stage){
@@ -2065,7 +2075,7 @@ async function updateEnvironmentContext(context, configs) {
2065
2075
  async function createContext(options, userConfig) {
2066
2076
  let { cwd } = options, rootPath = userConfig.root ? ensureAbsolutePath(cwd, userConfig.root) : cwd, rsbuildConfig = await withDefaultConfig(rootPath, userConfig), cachePath = join(rootPath, 'node_modules', '.cache'), specifiedEnvironments = options.environment && options.environment.length > 0 ? options.environment : void 0, bundlerType = userConfig.provider ? 'webpack' : 'rspack';
2067
2077
  return {
2068
- version: "1.4.6",
2078
+ version: "1.4.8",
2069
2079
  rootPath,
2070
2080
  distPath: '',
2071
2081
  cachePath,
@@ -2448,7 +2458,7 @@ async function modifyEnvironmentConfig(context, config, name) {
2448
2458
  async function initRsbuildConfig({ context, pluginManager }) {
2449
2459
  if (context.normalizedConfig) return context.normalizedConfig;
2450
2460
  await initPlugins({
2451
- getPluginAPI: context.getPluginAPI,
2461
+ context,
2452
2462
  pluginManager
2453
2463
  }), await modifyRsbuildConfig(context);
2454
2464
  let normalizedBaseConfig = ((config)=>{
@@ -2540,7 +2550,7 @@ async function initRsbuildConfig({ context, pluginManager }) {
2540
2550
  environments
2541
2551
  }, await updateEnvironmentContext(context, environments);
2542
2552
  let distPaths = Object.values(context.environments).map((item)=>item.distPath);
2543
- context.distPath = function(paths) {
2553
+ return context.distPath = function(paths) {
2544
2554
  let uniquePaths = [
2545
2555
  ...new Set(paths)
2546
2556
  ];
@@ -2552,14 +2562,20 @@ async function initRsbuildConfig({ context, pluginManager }) {
2552
2562
  else break;
2553
2563
  }
2554
2564
  return common.join(sep);
2555
- }(distPaths);
2556
- var config = context.normalizedConfig;
2557
- if (config.server.base && !config.server.base.startsWith('/')) throw Error(`${picocolors.dim('[rsbuild:config]')} The ${picocolors.yellow('"server.base"')} option should start with a slash, for example: "/base"`);
2558
- if (config.environments) {
2559
- let names = Object.keys(config.environments), regexp = /^[\w$-]+$/;
2560
- for (let name of names)regexp.test(name) || logger.warn(`${picocolors.dim('[rsbuild:config]')} Environment name "${picocolors.yellow(name)}" contains invalid characters. Only letters, numbers, "-", "_", and "$" are allowed.`);
2561
- }
2562
- return context.normalizedConfig;
2565
+ }(distPaths), ((config)=>{
2566
+ if (config.server.base && !config.server.base.startsWith('/')) throw Error(`${picocolors.dim('[rsbuild:config]')} The ${picocolors.yellow('"server.base"')} option should start with a slash, for example: "/base"`);
2567
+ if (!config.environments) return;
2568
+ let environmentNames = Object.keys(config.environments), environmentNameRegexp = /^[\w$-]+$/, validTargets = [
2569
+ 'web',
2570
+ 'node',
2571
+ 'web-worker'
2572
+ ];
2573
+ for (let name of environmentNames){
2574
+ environmentNameRegexp.test(name) || logger.warn(`${picocolors.dim('[rsbuild:config]')} Environment name "${picocolors.yellow(name)}" contains invalid characters. Only letters, numbers, "-", "_", and "$" are allowed.`);
2575
+ let outputConfig = config.environments[name].output;
2576
+ if (outputConfig.target && !validTargets.includes(outputConfig.target)) throw Error(`${picocolors.dim('[rsbuild:config]')} Invalid value of ${picocolors.yellow('output.target')}: ${picocolors.yellow(`"${outputConfig.target}"`)}, valid values are: ${picocolors.yellow(validTargets.join(', '))}`);
2577
+ }
2578
+ })(context.normalizedConfig), context.normalizedConfig;
2563
2579
  }
2564
2580
  async function initConfigs({ context, pluginManager, rsbuildOptions }) {
2565
2581
  let normalizedConfig = await initRsbuildConfig({
@@ -3032,9 +3048,10 @@ let entryNameSymbol = Symbol('entryName'), VOID_TAGS = [
3032
3048
  }, formatBasicTag = (tag)=>({
3033
3049
  tag: tag.tagName,
3034
3050
  attrs: tag.attributes,
3035
- children: tag.innerHTML
3051
+ children: tag.innerHTML,
3052
+ metadata: tag.meta
3036
3053
  }), fromBasicTag = (tag)=>({
3037
- meta: {},
3054
+ meta: tag.metadata ?? {},
3038
3055
  tagName: tag.tag,
3039
3056
  attributes: tag.attrs ?? {},
3040
3057
  voidTag: VOID_TAGS.includes(tag.tag),
@@ -3263,7 +3280,24 @@ let isWsl = ()=>{
3263
3280
  } catch {
3264
3281
  return !1;
3265
3282
  }
3266
- }, is_wsl = node_process.env.__IS_WSL_TEST__ ? isWsl : isWsl();
3283
+ }, is_wsl = node_process.env.__IS_WSL_TEST__ ? isWsl : isWsl(), wslDrivesMountPoint = (()=>{
3284
+ let mountPoint, defaultMountPoint = '/mnt/';
3285
+ return async function() {
3286
+ if (mountPoint) return mountPoint;
3287
+ let configFilePath = '/etc/wsl.conf', isConfigFileExists = !1;
3288
+ try {
3289
+ await promises.access(configFilePath, promises_constants.F_OK), isConfigFileExists = !0;
3290
+ } catch {}
3291
+ if (!isConfigFileExists) return defaultMountPoint;
3292
+ let configContent = await promises.readFile(configFilePath, {
3293
+ encoding: 'utf8'
3294
+ }), configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
3295
+ return configMountPoint ? mountPoint = (mountPoint = configMountPoint.groups.mountPoint.trim()).endsWith('/') ? mountPoint : `${mountPoint}/` : defaultMountPoint;
3296
+ };
3297
+ })(), powerShellPathFromWsl = async ()=>{
3298
+ let mountPoint = await wslDrivesMountPoint();
3299
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
3300
+ }, powerShellPath = async ()=>is_wsl ? powerShellPathFromWsl() : `${node_process.env.SYSTEMROOT || node_process.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
3267
3301
  function defineLazyProperty(object, propertyName, valueGetter) {
3268
3302
  let define = (value)=>Object.defineProperty(object, propertyName, {
3269
3303
  value,
@@ -3382,26 +3416,9 @@ async function default_browser_defaultBrowser() {
3382
3416
  if ('win32' === node_process.platform) return defaultBrowser();
3383
3417
  throw Error('Only macOS, Linux, and Windows are supported');
3384
3418
  }
3385
- let open_execFile = node_util.promisify(node_child_process.execFile), open_dirname = node_path.dirname(fileURLToPath(import.meta.url)), localXdgOpenPath = node_path.join(open_dirname, 'xdg-open'), { platform, arch } = node_process, getWslDrivesMountPoint = (()=>{
3386
- let mountPoint, defaultMountPoint = '/mnt/';
3387
- return async function() {
3388
- if (mountPoint) return mountPoint;
3389
- let configFilePath = '/etc/wsl.conf', isConfigFileExists = !1;
3390
- try {
3391
- await promises.access(configFilePath, external_node_fs_constants.F_OK), isConfigFileExists = !0;
3392
- } catch {}
3393
- if (!isConfigFileExists) return defaultMountPoint;
3394
- let configContent = await promises.readFile(configFilePath, {
3395
- encoding: 'utf8'
3396
- }), configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
3397
- return configMountPoint ? mountPoint = (mountPoint = configMountPoint.groups.mountPoint.trim()).endsWith('/') ? mountPoint : `${mountPoint}/` : defaultMountPoint;
3398
- };
3399
- })(), getPowershellPathFromWsl = async ()=>{
3400
- let mountPoint = await getWslDrivesMountPoint();
3401
- return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
3402
- };
3419
+ let open_execFile = external_node_util_promisify(node_child_process.execFile), open_dirname = node_path.dirname(fileURLToPath(import.meta.url)), localXdgOpenPath = node_path.join(open_dirname, 'xdg-open'), { platform, arch } = node_process;
3403
3420
  async function getWindowsDefaultBrowserFromWsl() {
3404
- let powershellPath = await getPowershellPathFromWsl(), encodedCommand = external_node_buffer_Buffer.from('(Get-ItemProperty -Path "HKCU:\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice").ProgId', 'utf16le').toString('base64'), { stdout } = await open_execFile(powershellPath, [
3421
+ let powershellPath = await powerShellPath(), rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`, encodedCommand = external_node_buffer_Buffer.from(rawCommand, 'utf16le').toString('base64'), { stdout } = await open_execFile(powershellPath, [
3405
3422
  '-NoProfile',
3406
3423
  '-NonInteractive',
3407
3424
  '-ExecutionPolicy',
@@ -3412,6 +3429,7 @@ async function getWindowsDefaultBrowserFromWsl() {
3412
3429
  encoding: 'utf8'
3413
3430
  }), progId = stdout.trim(), browserMap = {
3414
3431
  ChromeHTML: 'com.google.chrome',
3432
+ BraveHTML: 'com.brave.Browser',
3415
3433
  MSEdgeHTM: 'com.microsoft.edge',
3416
3434
  FirefoxURL: 'org.mozilla.firefox'
3417
3435
  };
@@ -3453,6 +3471,7 @@ let pTryEach = async (array, mapper)=>{
3453
3471
  let ids = {
3454
3472
  'com.google.chrome': 'chrome',
3455
3473
  'google-chrome.desktop': 'chrome',
3474
+ 'com.brave.Browser': 'brave',
3456
3475
  'org.mozilla.firefox': 'firefox',
3457
3476
  'firefox.desktop': 'firefox',
3458
3477
  'com.microsoft.msedge': 'edge',
@@ -3464,6 +3483,7 @@ let pTryEach = async (array, mapper)=>{
3464
3483
  let browserName = ids[browser.id];
3465
3484
  return 'browserPrivate' === app && appArguments.push({
3466
3485
  chrome: '--incognito',
3486
+ brave: '--incognito',
3467
3487
  firefox: '--private-window',
3468
3488
  edge: '--inPrivate'
3469
3489
  }[browserName]), baseOpen({
@@ -3489,7 +3509,7 @@ let pTryEach = async (array, mapper)=>{
3489
3509
  }
3490
3510
  appArguments.length > 0 && cliArguments.push(...appArguments), options.wait || (childProcessOptions.stdio = 'ignore', childProcessOptions.detached = !0);
3491
3511
  } else {
3492
- command = is_wsl ? await getPowershellPathFromWsl() : `${node_process.env.SYSTEMROOT || node_process.env.windir || 'C:\\Windows'}\\System32\\WindowsPowerShell\\v1.0\\powershell`, cliArguments.push('-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand'), is_wsl || (childProcessOptions.windowsVerbatimArguments = !0);
3512
+ command = await powerShellPath(), cliArguments.push('-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand'), is_wsl || (childProcessOptions.windowsVerbatimArguments = !0);
3493
3513
  let encodedArguments = [
3494
3514
  'Start'
3495
3515
  ];
@@ -3532,9 +3552,24 @@ defineLazyProperty(apps, 'chrome', ()=>detectPlatformBinary({
3532
3552
  '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'
3533
3553
  ]
3534
3554
  }
3555
+ })), defineLazyProperty(apps, 'brave', ()=>detectPlatformBinary({
3556
+ darwin: 'brave browser',
3557
+ win32: 'brave',
3558
+ linux: [
3559
+ 'brave-browser',
3560
+ 'brave'
3561
+ ]
3562
+ }, {
3563
+ wsl: {
3564
+ ia32: '/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe',
3565
+ x64: [
3566
+ '/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe',
3567
+ '/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe'
3568
+ ]
3569
+ }
3535
3570
  })), defineLazyProperty(apps, 'firefox', ()=>detectPlatformBinary({
3536
3571
  darwin: 'firefox',
3537
- win32: 'C:\\Program Files\\Mozilla Firefox\\firefox.exe',
3572
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
3538
3573
  linux: 'firefox'
3539
3574
  }, {
3540
3575
  wsl: '/mnt/c/Program Files/Mozilla Firefox/firefox.exe'
@@ -3589,13 +3624,13 @@ function printServerURLs({ urls: originalUrls, port, routes, protocol, printUrls
3589
3624
  if (routes.length <= 1) {
3590
3625
  let pathname = routes.length ? routes[0].pathname : '';
3591
3626
  return urls.map(({ label, url })=>{
3592
- let normalizedPathname = normalizeUrl(`${url}${pathname}`), prefix = `\u{279C} ${picocolors.dim(label.padEnd(10))}`;
3627
+ let normalizedPathname = normalizeUrl(`${url}${pathname}`), prefix = `\u{279C} ${picocolors.dim(label.padEnd(10))}`;
3593
3628
  return ` ${prefix}${picocolors.cyan(normalizedPathname)}\n`;
3594
3629
  }).join('');
3595
3630
  }
3596
3631
  let message = '', maxNameLength = Math.max(...routes.map((r)=>r.entryName.length));
3597
3632
  return urls.forEach(({ label, url }, index)=>{
3598
- for (let r of (index > 0 && (message += '\n'), message += ` ${`\u{279C} ${label}`}\n`, routes))message += ` ${picocolors.dim('-')} ${picocolors.dim(r.entryName.padEnd(maxNameLength + 4))}${picocolors.cyan(normalizeUrl(`${url}${r.pathname}`))}\n`;
3633
+ for (let r of (index > 0 && (message += '\n'), message += ` ${`\u{279C} ${label}`}\n`, routes))message += ` ${picocolors.dim('-')} ${picocolors.dim(r.entryName.padEnd(maxNameLength + 4))}${picocolors.cyan(normalizeUrl(`${url}${r.pathname}`))}\n`;
3599
3634
  }), message;
3600
3635
  }(urls, routes);
3601
3636
  return !1 === trailingLineBreak && message.endsWith('\n') && (message = message.slice(0, -1)), logger.log(message), message;
@@ -4110,7 +4145,7 @@ async function setupCliShortcuts({ help = !0, openPage, closeServer, printUrls,
4110
4145
  }
4111
4146
  ].filter(Boolean);
4112
4147
  if (customShortcuts && !Array.isArray(shortcuts = customShortcuts(shortcuts))) throw Error(`${picocolors.dim('[rsbuild:config]')} ${picocolors.yellow('dev.cliShortcuts')} option must return an array of shortcuts.`);
4113
- help && logger.log(!0 === help ? ` \u{279C} ${picocolors.dim('press')} ${picocolors.bold('h + enter')} ${picocolors.dim('to show shortcuts')}\n` : ` \u{279C} ${help}\n`);
4148
+ help && logger.log(!0 === help ? ` \u{279C} ${picocolors.dim('press')} ${picocolors.bold('h + enter')} ${picocolors.dim('to show shortcuts')}\n` : ` \u{279C} ${help}\n`);
4114
4149
  let { createInterface } = await import("node:readline"), rl = createInterface({
4115
4150
  input: process.stdin
4116
4151
  });
@@ -5257,15 +5292,22 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
5257
5292
  port,
5258
5293
  https
5259
5294
  };
5260
- let waitFirstCompileDone = runCompile ? new Promise((resolve)=>{
5261
- context.hooks.onDevCompileDone.tap(({ stats, isFirstCompile })=>{
5262
- lastStats = 'stats' in stats ? stats.stats : [
5263
- stats
5264
- ], isFirstCompile && resolve();
5265
- });
5266
- }) : Promise.resolve(), startCompile = async ()=>{
5295
+ let waitLastCompileDoneResolve = null, waitLastCompileDone = new Promise((resolve)=>{
5296
+ waitLastCompileDoneResolve = resolve;
5297
+ });
5298
+ context.hooks.onDevCompileDone.tap(({ stats })=>{
5299
+ lastStats = 'stats' in stats ? stats.stats : [
5300
+ stats
5301
+ ], waitLastCompileDoneResolve && (waitLastCompileDoneResolve(), waitLastCompileDoneResolve = null);
5302
+ });
5303
+ let startCompile = async ()=>{
5267
5304
  let compiler = customCompiler || await createCompiler();
5268
5305
  if (!compiler) throw Error(`${picocolors.dim('[rsbuild:server]')} Failed to get compiler instance.`);
5306
+ null == compiler || compiler.hooks.watchRun.tap('rsbuild:watchRun', ()=>{
5307
+ lastStats && (waitLastCompileDoneResolve && (waitLastCompileDoneResolve(), waitLastCompileDoneResolve = null), waitLastCompileDone = new Promise((resolve)=>{
5308
+ waitLastCompileDoneResolve = resolve;
5309
+ }));
5310
+ });
5269
5311
  let publicPaths = helpers_isMultiCompiler(compiler) ? compiler.compilers.map(getPublicPathFromCompiler) : [
5270
5312
  getPublicPathFromCompiler(compiler)
5271
5313
  ], compilationManager = new CompilationManager({
@@ -5323,19 +5365,19 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
5323
5365
  {
5324
5366
  getStats: async ()=>{
5325
5367
  if (!compilationManager) throw Error(`${picocolors.dim('[rsbuild:server]')} Can not call ${picocolors.yellow('getStats')} when ${picocolors.yellow('runCompile')} is false`);
5326
- return await waitFirstCompileDone, lastStats[environment.index];
5368
+ return await waitLastCompileDone, lastStats[environment.index];
5327
5369
  },
5328
5370
  context: environment,
5329
5371
  loadBundle: async (entryName)=>{
5330
5372
  if (!compilationManager) throw Error(`${picocolors.dim('[rsbuild:server]')} Can not call ${picocolors.yellow('loadBundle')} when ${picocolors.yellow('runCompile')} is false`);
5331
- return await waitFirstCompileDone, cacheableLoadBundle(lastStats[environment.index], entryName, {
5373
+ return await waitLastCompileDone, cacheableLoadBundle(lastStats[environment.index], entryName, {
5332
5374
  readFileSync: compilationManager.readFileSync,
5333
5375
  environment
5334
5376
  });
5335
5377
  },
5336
5378
  getTransformedHtml: async (entryName)=>{
5337
5379
  if (!compilationManager) throw Error(`${picocolors.dim('[rsbuild:server]')} Can not call ${picocolors.yellow('getTransformedHtml')} when ${picocolors.yellow('runCompile')} is false`);
5338
- return await waitFirstCompileDone, cacheableTransformedHtml(lastStats[environment.index], entryName, {
5380
+ return await waitLastCompileDone, cacheableTransformedHtml(lastStats[environment.index], entryName, {
5339
5381
  readFileSync: compilationManager.readFileSync,
5340
5382
  environment
5341
5383
  });
@@ -5691,7 +5733,7 @@ async function applyDefaultPlugins(pluginManager, context) {
5691
5733
  buildDependencies
5692
5734
  });
5693
5735
  }), api.onAfterCreateCompiler(()=>{
5694
- cacheEnabled && 'rspack' === api.context.bundlerType && logger.info(`Rspack persistent cache enabled ${picocolors.dim('(experimental)')}`);
5736
+ cacheEnabled && 'rspack' === api.context.bundlerType && logger.debug('Rspack persistent cache enabled');
5695
5737
  });
5696
5738
  }
5697
5739
  },
@@ -7001,10 +7043,11 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
7001
7043
  },
7002
7044
  {
7003
7045
  name: 'rsbuild:lazy-compilation',
7046
+ apply: 'serve',
7004
7047
  setup (api) {
7005
- api.modifyBundlerChain((chain, { environment, isProd, target })=>{
7048
+ api.modifyBundlerChain((chain, { environment, target })=>{
7006
7049
  var _config_dev;
7007
- if (isProd || 'web' !== target) return;
7050
+ if ('web' !== target) return;
7008
7051
  let { config } = environment, options = null == (_config_dev = config.dev) ? void 0 : _config_dev.lazyCompilation;
7009
7052
  if (options) {
7010
7053
  if (!0 === options && Object.keys(chain.entryPoints.entries() || {}).length <= 1) return void chain.experiments({
@@ -7121,12 +7164,10 @@ async function createRsbuild(options = {}) {
7121
7164
  ...options,
7122
7165
  rsbuildConfig: config
7123
7166
  }, pluginManager = (plugins = [], {
7124
- getPlugins: (options = {
7125
- environment: RSBUILD_ALL_ENVIRONMENT_SYMBOL
7126
- })=>plugins.filter((p)=>isPluginMatchEnvironment(p.environment, options.environment)).map((p)=>p.instance),
7167
+ getPlugins: (options = {})=>plugins.filter((plugin)=>isEnvironmentMatch(plugin.environment, options.environment)).map(({ instance })=>instance),
7127
7168
  getAllPluginsWithMeta: ()=>plugins,
7128
7169
  addPlugins: (newPlugins, options)=>{
7129
- let { before, environment = RSBUILD_ALL_ENVIRONMENT_SYMBOL } = options || {};
7170
+ let { before, environment } = options || {};
7130
7171
  for (let newPlugin of newPlugins)if (newPlugin) {
7131
7172
  let type = typeof newPlugin;
7132
7173
  if ('object' !== type || null === newPlugin) throw Error(`${picocolors.dim('[rsbuild:plugin]')} Expect Rsbuild plugin instance to be an object, but got ${picocolors.yellow(type)}.`);
@@ -7167,9 +7208,7 @@ async function createRsbuild(options = {}) {
7167
7208
  removePlugins: (pluginNames, options = {})=>{
7168
7209
  plugins = plugins.filter((plugin)=>!(pluginNames.includes(plugin.instance.name) && (!options.environment || plugin.environment === options.environment)));
7169
7210
  },
7170
- isPluginExists: (pluginName, options = {
7171
- environment: RSBUILD_ALL_ENVIRONMENT_SYMBOL
7172
- })=>!!plugins.find((plugin)=>plugin.instance.name === pluginName && isPluginMatchEnvironment(plugin.environment, options.environment))
7211
+ isPluginExists: (pluginName, options = {})=>plugins.some((plugin)=>plugin.instance.name === pluginName && isEnvironmentMatch(plugin.environment, options.environment))
7173
7212
  }), context = await createContext(resolvedOptions, config), getPluginAPI = function({ context, pluginManager }) {
7174
7213
  let { hooks } = context, publicContext = function(context) {
7175
7214
  let exposedKeys = [
@@ -7223,7 +7262,7 @@ async function createRsbuild(options = {}) {
7223
7262
  let pluginName = 'RsbuildCorePlugin';
7224
7263
  chain.plugin(pluginName).use(class {
7225
7264
  apply(compiler) {
7226
- for (let { handler, environment: pluginEnvironment } of (compiler.__rsbuildTransformer = transformer, resolveFns))(!pluginEnvironment || isPluginMatchEnvironment(pluginEnvironment, environment.name)) && compiler.hooks.compilation.tap(pluginName, (compilation, { normalModuleFactory })=>{
7265
+ for (let { handler, environment: pluginEnvironment } of (compiler.__rsbuildTransformer = transformer, resolveFns))(!pluginEnvironment || isEnvironmentMatch(pluginEnvironment, environment.name)) && compiler.hooks.compilation.tap(pluginName, (compilation, { normalModuleFactory })=>{
7227
7266
  normalModuleFactory.hooks.resolve.tapPromise(pluginName, async (resolveData)=>handler({
7228
7267
  compiler,
7229
7268
  compilation,
@@ -7236,7 +7275,7 @@ async function createRsbuild(options = {}) {
7236
7275
  childCompiler.__rsbuildTransformer = transformer;
7237
7276
  });
7238
7277
  let { sources } = compiler.webpack;
7239
- for (let { descriptor, handler, environment: pluginEnvironment } of processAssetsFns)(!descriptor.targets || descriptor.targets.includes(target)) && (!descriptor.environments || descriptor.environments.includes(environment.name)) && (!pluginEnvironment || isPluginMatchEnvironment(pluginEnvironment, environment.name)) && compilation.hooks.processAssets.tapPromise({
7278
+ for (let { descriptor, handler, environment: pluginEnvironment } of processAssetsFns)(!descriptor.targets || descriptor.targets.includes(target)) && (!descriptor.environments || descriptor.environments.includes(environment.name)) && (!pluginEnvironment || isEnvironmentMatch(pluginEnvironment, environment.name)) && compilation.hooks.processAssets.tapPromise({
7240
7279
  name: pluginName,
7241
7280
  stage: mapProcessAssetsStage(compiler, descriptor.stage)
7242
7281
  }, async (assets)=>handler({
@@ -7647,11 +7686,11 @@ async function runCLI() {
7647
7686
  ].includes(level) && (logger.level = level);
7648
7687
  }
7649
7688
  let { npm_execpath } = process.env;
7650
- (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) && logger.log(), logger.greet(` Rsbuild v1.4.6\n`);
7689
+ (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) && logger.log(), logger.greet(` Rsbuild v1.4.8\n`);
7651
7690
  try {
7652
7691
  !function() {
7653
7692
  let cli = ((name = "")=>new CAC(name))('rsbuild');
7654
- cli.help(), cli.version("1.4.6"), cli.option('--base <base>', 'specify the base path of the server').option('-c, --config <config>', 'specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'specify the loader to load the config file, can be `jiti` or `native`', {
7693
+ cli.help(), cli.version("1.4.8"), cli.option('--base <base>', 'specify the base path of the server').option('-c, --config <config>', 'specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'specify the loader to load the config file, can be `jiti` or `native`', {
7655
7694
  default: 'jiti'
7656
7695
  }).option('-r, --root <root>', 'specify the project root directory, can be an absolute path or a path relative to cwd').option('-m, --mode <mode>', 'specify the build mode, can be `development`, `production` or `none`').option('--log-level <level>', 'specify the log level, can be `info`, `warn`, `error` or `silent`').option('--env-mode <mode>', 'specify the env mode to load the `.env.[mode]` file').option('--environment <name>', 'specify the name of environment to build', {
7657
7696
  type: [
@@ -7709,5 +7748,5 @@ async function runCLI() {
7709
7748
  logger.error('Failed to start Rsbuild CLI.'), logger.error(err);
7710
7749
  }
7711
7750
  }
7712
- let src_version = "1.4.6";
7751
+ let src_version = "1.4.8";
7713
7752
  export { PLUGIN_CSS_NAME, PLUGIN_SWC_NAME, createRsbuild, defaultAllowedOrigins, defineConfig, ensureAssetPrefix, loadConfig_loadConfig as loadConfig, loadEnv, logger, mergeRsbuildConfig, rspack, runCLI, src_version as version };
@@ -19,4 +19,4 @@ export { type Logger, logger } from './logger';
19
19
  export { mergeRsbuildConfig } from './mergeConfig';
20
20
  export type { RsbuildDevServer } from './server/devServer';
21
21
  export type { StartServerResult } from './server/helper';
22
- export type { AliasStrategy, AppIcon, AppIconItem, Build, BuildOptions, BundlerPluginInstance, Charset, CleanDistPath, CleanDistPathObject, ClientConfig, CliShortcut, CompressOptions, ConfigChain, ConfigChainWithContext, ConsoleType, CreateCompiler, CreateRsbuildOptions, CrossOrigin, CSSLoaderOptions, CSSModules, CSSModulesLocalsConvention, DataUriLimit, Decorators, DevConfig, DistPathConfig, EnvironmentConfig, EnvironmentContext, FilenameConfig, HistoryApiFallbackContext, HistoryApiFallbackOptions, HtmlBasicTag, HtmlConfig, HtmlFallback, HtmlRspackPlugin, HtmlTagContext, HtmlTagDescriptor, HtmlTagHandler, InlineChunkConfig, InlineChunkTest, InlineChunkTestFunction, InspectConfigOptions, InspectConfigResult, InternalContext, LegalComments, LogLevel, ManifestConfig, ManifestData, ManifestObjectConfig, MergedEnvironmentConfig, MetaAttrs, MetaOptions, Minify, ModifyBundlerChainFn, ModifyBundlerChainUtils, ModifyChainUtils, ModifyEnvironmentConfigFn, ModifyEnvironmentConfigUtils, ModifyHTMLContext, ModifyHTMLFn, ModifyHTMLTagsContext, ModifyHTMLTagsFn, ModifyRsbuildConfigFn, ModifyRsbuildConfigUtils, ModifyRspackConfigFn, ModifyRspackConfigUtils, ModifyWebpackChainFn, ModifyWebpackChainUtils, ModifyWebpackConfigFn, ModifyWebpackConfigUtils, ModuleFederationConfig, NormalizedConfig, NormalizedDevConfig, NormalizedEnvironmentConfig, NormalizedHtmlConfig, NormalizedModuleFederationConfig, NormalizedOutputConfig, NormalizedPerformanceConfig, NormalizedSecurityConfig, NormalizedServerConfig, NormalizedSourceConfig, NormalizedToolsConfig, OnAfterBuildFn, OnAfterCreateCompilerFn, OnAfterEnvironmentCompileFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, OnBeforeEnvironmentCompileFn, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseBuildFn, OnCloseDevServerFn, OnDevCompileDoneFn, OnExitFn, OutputConfig, OutputStructure, PerformanceConfig, PluginManager, Polyfill, PostCSSLoaderOptions, PostCSSOptions, PostCSSPlugin, PreconnectOption, PreviewOptions, PrintUrls, ProcessAssetsDescriptor, ProcessAssetsHandler, ProcessAssetsHook, ProgressBarConfig, ProxyBypass, ProxyConfig, ProxyFilter, ProxyOptions, PublicDir, PublicDirOptions, RequestHandler, ResolvedCreateRsbuildOptions, ResolveHandler, ResolveHook, ResourceHintsIncludeType, RsbuildConfig, RsbuildContext, RsbuildEntry, RsbuildEntryDescription, RsbuildInstance, RsbuildMode, RsbuildPlugin, RsbuildPluginAPI, RsbuildPlugins, RsbuildProvider, RsbuildProviderHelpers, RsbuildTarget, RspackChain, RspackRule, ScriptInject, ScriptLoading, SecurityConfig, ServerConfig, SetupMiddlewaresContext, SetupMiddlewaresFn, SourceConfig, SourceMap, SplitChunks, SriAlgorithm, SriOptions, StartDevServerOptions, StyleLoaderOptions, ToolsConfig, TransformContext, TransformDescriptor, TransformHandler, TransformHook, TransformImport, WatchFiles, } from './types';
22
+ export type { AliasStrategy, AppIcon, AppIconItem, Build, BuildOptions, BundlerPluginInstance, Charset, CleanDistPath, CleanDistPathObject, ClientConfig, CliShortcut, CompressOptions, ConfigChain, ConfigChainWithContext, ConsoleType, CreateCompiler, CreateRsbuildOptions, CrossOrigin, CSSLoaderOptions, CSSModules, CSSModulesLocalsConvention, DataUriLimit, Decorators, DevConfig, DistPathConfig, EnvironmentConfig, EnvironmentContext, FilenameConfig, HistoryApiFallbackContext, HistoryApiFallbackOptions, HtmlBasicTag, HtmlConfig, HtmlFallback, HtmlRspackPlugin, HtmlTag, HtmlTagContext, HtmlTagDescriptor, HtmlTagHandler, InlineChunkConfig, InlineChunkTest, InlineChunkTestFunction, InspectConfigOptions, InspectConfigResult, InternalContext, LegalComments, LogLevel, ManifestConfig, ManifestData, ManifestObjectConfig, MergedEnvironmentConfig, MetaAttrs, MetaOptions, Minify, ModifyBundlerChainFn, ModifyBundlerChainUtils, ModifyChainUtils, ModifyEnvironmentConfigFn, ModifyEnvironmentConfigUtils, ModifyHTMLContext, ModifyHTMLFn, ModifyHTMLTagsContext, ModifyHTMLTagsFn, ModifyRsbuildConfigFn, ModifyRsbuildConfigUtils, ModifyRspackConfigFn, ModifyRspackConfigUtils, ModifyWebpackChainFn, ModifyWebpackChainUtils, ModifyWebpackConfigFn, ModifyWebpackConfigUtils, ModuleFederationConfig, NormalizedConfig, NormalizedDevConfig, NormalizedEnvironmentConfig, NormalizedHtmlConfig, NormalizedModuleFederationConfig, NormalizedOutputConfig, NormalizedPerformanceConfig, NormalizedSecurityConfig, NormalizedServerConfig, NormalizedSourceConfig, NormalizedToolsConfig, OnAfterBuildFn, OnAfterCreateCompilerFn, OnAfterEnvironmentCompileFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, OnBeforeEnvironmentCompileFn, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseBuildFn, OnCloseDevServerFn, OnDevCompileDoneFn, OnExitFn, OutputConfig, OutputStructure, PerformanceConfig, PluginManager, Polyfill, PostCSSLoaderOptions, PostCSSOptions, PostCSSPlugin, PreconnectOption, PreviewOptions, PrintUrls, ProcessAssetsDescriptor, ProcessAssetsHandler, ProcessAssetsHook, ProgressBarConfig, ProxyBypass, ProxyConfig, ProxyFilter, ProxyOptions, PublicDir, PublicDirOptions, RequestHandler, ResolvedCreateRsbuildOptions, ResolveHandler, ResolveHook, ResourceHintsIncludeType, RsbuildConfig, RsbuildContext, RsbuildEntry, RsbuildEntryDescription, RsbuildInstance, RsbuildMode, RsbuildPlugin, RsbuildPluginAPI, RsbuildPlugins, RsbuildProvider, RsbuildProviderHelpers, RsbuildTarget, RspackChain, RspackRule, ScriptInject, ScriptLoading, SecurityConfig, ServerConfig, SetupMiddlewaresContext, SetupMiddlewaresFn, SourceConfig, SourceMap, SplitChunks, SriAlgorithm, SriOptions, StartDevServerOptions, StyleLoaderOptions, ToolsConfig, TransformContext, TransformDescriptor, TransformHandler, TransformHook, TransformImport, WatchFiles, } from './types';
@@ -23,7 +23,7 @@ export type LoadEnvOptions = {
23
23
  };
24
24
  export type LoadEnvResult = {
25
25
  /**
26
- * All env variables in the .env file
26
+ * All environment variables in the .env file
27
27
  */
28
28
  parsed: Record<string, string>;
29
29
  /**
@@ -31,7 +31,7 @@ export type LoadEnvResult = {
31
31
  */
32
32
  filePaths: string[];
33
33
  /**
34
- * Env variables that start with prefixes.
34
+ * Environment variables that start with prefixes.
35
35
  *
36
36
  * @example
37
37
  * ```ts
@@ -42,7 +42,7 @@ export type LoadEnvResult = {
42
42
  **/
43
43
  rawPublicVars: Record<string, string | undefined>;
44
44
  /**
45
- * Formatted env variables that start with prefixes.
45
+ * Formatted environment variables that start with prefixes.
46
46
  * The keys contain the prefixes `process.env.*` and `import.meta.env.*`.
47
47
  * The values are processed by `JSON.stringify`.
48
48
  *
@@ -56,7 +56,7 @@ export type LoadEnvResult = {
56
56
  **/
57
57
  publicVars: Record<string, string>;
58
58
  /**
59
- * Clear the env variables mounted on `process.env`
59
+ * Clear the environment variables mounted on `process.env`
60
60
  */
61
61
  cleanup: () => void;
62
62
  };
@@ -1,9 +1,12 @@
1
- import type { PluginManager, PluginMeta, RsbuildPluginAPI } from './types';
2
- export declare const RSBUILD_ALL_ENVIRONMENT_SYMBOL = "RSBUILD_ALL_ENVIRONMENT_SYMBOL";
3
- export declare const isPluginMatchEnvironment: (pluginEnvironment: string, currentEnvironment: string) => boolean;
1
+ import type { InternalContext, PluginManager, PluginMeta } from './types';
2
+ /**
3
+ * Determines whether the plugin is registered in the specified environment.
4
+ * If the pluginEnvironment is undefined, it means it can match any environment.
5
+ */
6
+ export declare const isEnvironmentMatch: (pluginEnvironment?: string, specifiedEnvironment?: string) => boolean;
4
7
  export declare function createPluginManager(): PluginManager;
5
8
  export declare const pluginDagSort: (plugins: PluginMeta[]) => PluginMeta[];
6
- export declare function initPlugins({ getPluginAPI, pluginManager, }: {
7
- getPluginAPI: (environment?: string) => RsbuildPluginAPI;
9
+ export declare function initPlugins({ context, pluginManager, }: {
10
+ context: InternalContext;
8
11
  pluginManager: PluginManager;
9
12
  }): Promise<void>;
@@ -1146,6 +1146,12 @@ export type HtmlBasicTag = {
1146
1146
  * HTML escaping, so ensure it's safe to prevent XSS vulnerabilities.
1147
1147
  */
1148
1148
  children?: string;
1149
+ /**
1150
+ * The metadata object for tags, used to store additional information about tags.
1151
+ * `metadata` does not affect the generated HTML content.
1152
+ * @default undefined
1153
+ */
1154
+ metadata?: Record<string, any>;
1149
1155
  };
1150
1156
  export type HtmlTag = HtmlBasicTag & {
1151
1157
  /**
@@ -6,7 +6,7 @@ import type { Logger } from '../logger';
6
6
  import type { ModifyRspackConfigUtils, NarrowedRspackConfig, NormalizedConfig, NormalizedEnvironmentConfig, RsbuildConfig, RspackMerge } from './config';
7
7
  import type { RsbuildContext } from './context';
8
8
  import type { EnvironmentContext, ModifyBundlerChainFn, ModifyChainUtils, ModifyEnvironmentConfigFn, ModifyHTMLFn, ModifyHTMLTagsFn, ModifyRsbuildConfigFn, OnAfterBuildFn, OnAfterCreateCompilerFn, OnAfterEnvironmentCompileFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, OnBeforeEnvironmentCompileFn, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseBuildFn, OnCloseDevServerFn, OnDevCompileDoneFn, OnExitFn } from './hooks';
9
- import type { RsbuildInstance, RsbuildTarget } from './rsbuild';
9
+ import type { AddPluginsOptions, RsbuildInstance, RsbuildTarget } from './rsbuild';
10
10
  import type { Rspack } from './rspack';
11
11
  import type { HtmlRspackPlugin } from './thirdParty';
12
12
  import type { Falsy, MaybePromise } from './utils';
@@ -117,13 +117,14 @@ export type ModifyWebpackConfigUtils = ModifyWebpackChainUtils & {
117
117
  export type ModifyWebpackChainFn = (chain: RspackChain, utils: ModifyWebpackChainUtils) => Promise<void> | void;
118
118
  export type ModifyWebpackConfigFn = (config: WebpackConfig, utils: ModifyWebpackConfigUtils) => Promise<WebpackConfig | void> | WebpackConfig | void;
119
119
  export type PluginMeta = {
120
- environment: string;
120
+ environment?: AddPluginsOptions['environment'];
121
121
  instance: RsbuildPlugin;
122
122
  };
123
123
  export type PluginManager = Pick<RsbuildInstance, 'getPlugins' | 'addPlugins' | 'isPluginExists' | 'removePlugins'> & {
124
124
  /** Get all plugins with environment info */
125
125
  getAllPluginsWithMeta: () => PluginMeta[];
126
126
  };
127
+ export type RsbuildPluginApply = 'serve' | 'build';
127
128
  /**
128
129
  * The type of the Rsbuild plugin object.
129
130
  */
@@ -132,6 +133,13 @@ export type RsbuildPlugin = {
132
133
  * The name of the plugin, a unique identifier.
133
134
  */
134
135
  name: string;
136
+ /**
137
+ * Conditional apply the plugin during serve or build.
138
+ * - `'serve'`: Apply the plugin when starting the dev server or preview server.
139
+ * - `'build'`: Apply the plugin during build.
140
+ * - If not specified, the plugin will be applied during both serve and build.
141
+ */
142
+ apply?: RsbuildPluginApply;
135
143
  /**
136
144
  * The setup function of the plugin, which can be an async function.
137
145
  * This function is called once when the plugin is initialized.