@rsbuild/core 1.5.15 → 1.5.17

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
@@ -3088,7 +3088,8 @@ ${section.body}` : section.body).join("\n\n"));
3088
3088
  });
3089
3089
  };
3090
3090
  function formatStatsError(stats, verbose) {
3091
- let fileName, message, fileName1 = function(stats) {
3091
+ var fileName;
3092
+ let message, fileName1 = function(stats) {
3092
3093
  let file = stats.file || stats.moduleName;
3093
3094
  if (file) return file;
3094
3095
  if (stats.moduleIdentifier) {
@@ -3107,7 +3108,7 @@ ${section.body}` : section.body).join("\n\n"));
3107
3108
  let rawTrace = moduleNames.reverse().map((item)=>`\n ${item}`).join('');
3108
3109
  return color.dim(`Import traces (entry → error):${rawTrace}`);
3109
3110
  }(stats, fileName1) ?? '';
3110
- message = `${fileName = fileName1, /:\d+:\d+/.test(fileName) ? `File: ${color.cyan(fileName)}\n` : `File: ${color.cyan(`${fileName}:1:1`)}\n`}${mainMessage}${details}${stack}${moduleTrace}`;
3111
+ message = `${!(fileName = fileName1) ? '' : /:\d+:\d+/.test(fileName) ? `File: ${color.cyan(fileName)}\n` : `File: ${color.cyan(`${fileName}:1:1`)}\n`}${mainMessage}${details}${stack}${moduleTrace}`;
3111
3112
  let innerError = '-- inner error --';
3112
3113
  return !verbose && message.includes(innerError) && (message = message.split(innerError)[0]), (message = (message = ((message)=>{
3113
3114
  let getTips = (moduleName)=>{
@@ -3340,11 +3341,11 @@ ${section.body}` : section.body).join("\n\n"));
3340
3341
  }
3341
3342
  return common.join(external_node_path_.sep);
3342
3343
  }
3343
- let getCompiledPath = (packageName)=>(0, external_node_path_.join)(COMPILED_PATH, packageName, 'index.js'), ensureAbsolutePath = (base, filePath)=>(0, external_node_path_.isAbsolute)(filePath) ? filePath : (0, external_node_path_.join)(base, filePath), getPathnameFromUrl = (publicPath)=>{
3344
+ let getCompiledPath = (packageName)=>(0, external_node_path_.join)(COMPILED_PATH, packageName, 'index.js'), ensureAbsolutePath = (base, filePath)=>(0, external_node_path_.isAbsolute)(filePath) ? filePath : (0, external_node_path_.join)(base, filePath), getPathnameFromUrl = (url)=>{
3344
3345
  try {
3345
- return publicPath ? new URL(publicPath).pathname : publicPath;
3346
+ return url ? new URL(url, 'http://localhost').pathname : url;
3346
3347
  } catch {
3347
- return publicPath;
3348
+ return url;
3348
3349
  }
3349
3350
  }, dedupeNestedPaths = (paths)=>paths.sort((p1, p2)=>p2.length > p1.length ? -1 : 1).reduce((prev, curr)=>prev.find((p)=>curr.startsWith(p) || curr === p) ? prev : prev.concat(curr), []), toPosixPath = (filepath)=>'/' === external_node_path_.sep ? filepath : filepath.replace(/\\/g, '/'), isFileSync = (filePath)=>{
3350
3351
  try {
@@ -3796,13 +3797,14 @@ ${section.body}` : section.body).join("\n\n"));
3796
3797
  async function createContext(options, userConfig) {
3797
3798
  let { cwd } = options, rootPath = userConfig.root ? ensureAbsolutePath(cwd, userConfig.root) : cwd, rsbuildConfig = await withDefaultConfig(rootPath, userConfig), cachePath = (0, external_node_path_.join)(rootPath, 'node_modules', '.cache'), specifiedEnvironments = options.environment && options.environment.length > 0 ? options.environment : void 0, bundlerType = userConfig.provider ? 'webpack' : 'rspack';
3798
3799
  return {
3799
- version: "1.5.15",
3800
+ version: "1.5.17",
3800
3801
  rootPath,
3801
3802
  distPath: '',
3802
3803
  cachePath,
3803
3804
  callerName: options.callerName,
3804
3805
  bundlerType,
3805
3806
  environments: {},
3807
+ publicPathnames: [],
3806
3808
  hooks: {
3807
3809
  onExit: createAsyncHook(),
3808
3810
  onCloseBuild: createAsyncHook(),
@@ -4395,7 +4397,7 @@ ${section.body}` : section.body).join("\n\n"));
4395
4397
  logger.info('build started...'), logRspackVersion();
4396
4398
  }), compiler.hooks.done.tap(HOOK_NAME, (statsInstance)=>{
4397
4399
  let stats = getRsbuildStats(statsInstance, compiler, context.action), hasErrors = statsInstance.hasErrors();
4398
- context.buildState.stats = stats, context.buildState.status = 'done', context.buildState.hasErrors = hasErrors;
4400
+ context.buildState.stats = stats, context.buildState.status = 'done', context.buildState.hasErrors = hasErrors, context.socketServer?.onBuildDone();
4399
4401
  let printTime = (statsItem, index)=>{
4400
4402
  if (statsItem.time) {
4401
4403
  let time = prettyTime(statsItem.time / 1000), { name } = rspackConfigs[index], suffix = name && isMultiCompiler ? color.dim(` (${name})`) : '';
@@ -5352,10 +5354,15 @@ ${section.body}` : section.body).join("\n\n"));
5352
5354
  });
5353
5355
  if (!newUrls) return null;
5354
5356
  if (!Array.isArray(newUrls)) throw Error(`${color.dim('[rsbuild:config]')} "server.printUrls" must return an array, but got ${typeof newUrls}.`);
5355
- urls = newUrls.map((url)=>({
5357
+ urls = newUrls.map((u)=>{
5358
+ let { url, label } = 'string' == typeof u ? {
5359
+ url: u
5360
+ } : u;
5361
+ return {
5356
5362
  url,
5357
- label: getUrlLabel(url)
5358
- }));
5363
+ label: label ?? getUrlLabel(url)
5364
+ };
5365
+ });
5359
5366
  }
5360
5367
  if (0 === urls.length || 0 === routes.length && !useCustomUrl) return null;
5361
5368
  let message = function(urls, routes) {
@@ -5613,16 +5620,17 @@ ${section.body}` : section.body).join("\n\n"));
5613
5620
  resourceHints = [];
5614
5621
  type;
5615
5622
  HTMLCount;
5616
- constructor(options, type, HTMLCount){
5623
+ isDev;
5624
+ constructor(options, type, HTMLCount, isDev){
5617
5625
  this.options = {
5618
5626
  ...HtmlResourceHintsPlugin_defaultOptions,
5619
5627
  ...options
5620
- }, this.type = type, this.HTMLCount = HTMLCount;
5628
+ }, this.type = type, this.HTMLCount = HTMLCount, this.isDev = isDev;
5621
5629
  }
5622
5630
  apply(compiler) {
5623
5631
  compiler.hooks.compilation.tap(this.name, (compilation)=>{
5624
5632
  let pluginHooks = getHTMLPlugin().getCompilationHooks(compilation), pluginName = `HTML${upperFirst(this.type)}Plugin`;
5625
- pluginHooks.beforeAssetTagGeneration.tap(pluginName, (data)=>(this.resourceHints = function(options, type, compilation, data, HTMLCount) {
5633
+ pluginHooks.beforeAssetTagGeneration.tap(pluginName, (data)=>(this.resourceHints = function(options, type, compilation, data, HTMLCount, isDev) {
5626
5634
  let extractedChunks = function(compilation, includeType) {
5627
5635
  let chunks = [
5628
5636
  ...compilation.chunks
@@ -5669,7 +5677,7 @@ ${section.body}` : section.body).join("\n\n"));
5669
5677
  }))).reduce((accumulated, chunk)=>accumulated.concat([
5670
5678
  ...chunk.files,
5671
5679
  ...chunk.auxiliaryFiles || []
5672
- ]), []).filter((file)=>!file.endsWith('.map')))
5680
+ ]), []).filter((file)=>!(isDev && file.endsWith('.hot-update.js')) && !file.endsWith('.map')))
5673
5681
  ], options.include, options.exclude).sort(), links = [], { publicPath, crossOriginLoading } = compilation.outputOptions;
5674
5682
  for (let file of sortedFilteredFiles){
5675
5683
  let href = ensureAssetPrefix(file, publicPath), attributes = {
@@ -5694,7 +5702,7 @@ ${section.body}` : section.body).join("\n\n"));
5694
5702
  });
5695
5703
  }
5696
5704
  return links;
5697
- }(this.options, this.type, compilation, data, this.HTMLCount), data)), pluginHooks.alterAssetTags.tap(pluginName, (data)=>{
5705
+ }(this.options, this.type, compilation, data, this.HTMLCount, this.isDev), data)), pluginHooks.alterAssetTags.tap(pluginName, (data)=>{
5698
5706
  var resourceHints, scripts;
5699
5707
  return this.resourceHints && (data.assetTags.styles = [
5700
5708
  ...this.options.dedupe ? (resourceHints = this.resourceHints, scripts = data.assetTags.scripts, resourceHints.filter((resourceHint)=>!scripts.find((script)=>script.attributes.src === resourceHint.attributes.href))) : this.resourceHints,
@@ -5851,14 +5859,8 @@ ${section.body}` : section.body).join("\n\n"));
5851
5859
  }
5852
5860
  var on_finished = __webpack_require__("../../node_modules/.pnpm/on-finished@2.4.1/node_modules/on-finished/index.js"), on_finished_default = __webpack_require__.n(on_finished), range_parser = __webpack_require__("../../node_modules/.pnpm/range-parser@1.2.1/node_modules/range-parser/index.js"), range_parser_default = __webpack_require__.n(range_parser);
5853
5861
  let matchHtmlRegExp = /["'&<>]/, external_node_querystring_namespaceObject = require("node:querystring"), UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
5854
- async function getFileFromUrl(url, outputFileSystem, environments) {
5855
- let pathname;
5856
- try {
5857
- let urlObject = new URL(url, 'http://localhost');
5858
- urlObject.pathname && (pathname = (0, external_node_querystring_namespaceObject.unescape)(urlObject.pathname));
5859
- } catch {
5860
- return;
5861
- }
5862
+ async function getFileFromUrl(url, outputFileSystem, context) {
5863
+ let pathname = (0, external_node_querystring_namespaceObject.unescape)(getPathnameFromUrl(url));
5862
5864
  if (!pathname) return;
5863
5865
  if (pathname.includes('\0')) return {
5864
5866
  errorCode: 400
@@ -5866,13 +5868,18 @@ ${section.body}` : section.body).join("\n\n"));
5866
5868
  if (UP_PATH_REGEXP.test(external_node_path_default().normalize(`./${pathname}`))) return {
5867
5869
  errorCode: 403
5868
5870
  };
5869
- let distPaths = new Set(Object.values(environments).map((env)=>env.distPath)), stat = async (filename)=>new Promise((resolve, reject)=>{
5871
+ let stat = async (filename)=>new Promise((resolve, reject)=>{
5870
5872
  outputFileSystem.stat(filename, (err, stats)=>{
5871
5873
  err ? reject(err) : resolve(stats);
5872
5874
  });
5873
- });
5874
- for (let distPath of distPaths){
5875
- let fsStats, filename = external_node_path_default().join(distPath, pathname);
5875
+ }), { environments, publicPathnames } = context, distPaths = Object.values(environments).map((env)=>env.distPath), possibleFilenames = new Set();
5876
+ for (let [index, distPath] of distPaths.entries()){
5877
+ let prefix = publicPathnames[index];
5878
+ prefix && '/' !== prefix && pathname.startsWith(prefix) && possibleFilenames.add(external_node_path_default().join(distPath, pathname.slice(prefix.length)));
5879
+ }
5880
+ for (let distPath of distPaths)possibleFilenames.add(external_node_path_default().join(distPath, pathname));
5881
+ for (let filename of possibleFilenames){
5882
+ let fsStats;
5876
5883
  try {
5877
5884
  fsStats = await stat(filename);
5878
5885
  } catch {
@@ -5944,7 +5951,7 @@ ${section.body}` : section.body).join("\n\n"));
5944
5951
  }), acceptedMethods = [
5945
5952
  'GET',
5946
5953
  'HEAD'
5947
- ], noop = ()=>{}, assets_middleware_require = (0, external_node_module_.createRequire)(__rslib_import_meta_url__), isTsError = (error)=>'message' in error && error.stack?.includes('ts-checker-rspack-plugin'), assetsMiddleware = async ({ config, compiler, context, socketServer, resolvedPort })=>{
5954
+ ], noop = ()=>{}, assets_middleware_require = (0, external_node_module_.createRequire)(__rslib_import_meta_url__), isTsError = (error)=>'message' in error && error.stack?.includes('ts-checker-rspack-plugin'), assets_middleware_assetsMiddleware = async ({ config, compiler, context, socketServer, resolvedPort })=>{
5948
5955
  var config1, environments, context1, ready, outputFileSystem;
5949
5956
  let watching, writeToDiskValues, resolvedHost = await resolveHostname(config.server.host), { environments: environments1 } = context;
5950
5957
  applyToCompiler(compiler, (compiler, index)=>{
@@ -6006,7 +6013,6 @@ ${section.body}` : section.body).join("\n\n"));
6006
6013
  ] : statsErrors), socketServer.sendError(statsErrors, token);
6007
6014
  return;
6008
6015
  }
6009
- socketServer.onBuildDone(token);
6010
6016
  });
6011
6017
  })({
6012
6018
  context,
@@ -6062,7 +6068,6 @@ ${section.body}` : section.body).join("\n\n"));
6062
6068
  }(writeToDisk, compilers), instance = (context1 = context, ready = (callback)=>{
6063
6069
  'done' === context.buildState.status ? callback() : callbacks.push(callback);
6064
6070
  }, outputFileSystem = outputFileSystem1, async function(req, res, next) {
6065
- let { environments } = context1;
6066
6071
  async function goNext() {
6067
6072
  return new Promise((resolve)=>{
6068
6073
  ready(()=>{
@@ -6116,7 +6121,7 @@ ${section.body}` : section.body).join("\n\n"));
6116
6121
  var stat, range, offset, filename, outputFileSystem1, start, end;
6117
6122
  let bufferOrStream, byteLength, end1;
6118
6123
  if (!req.url) return void await goNext();
6119
- let resolved = await getFileFromUrl(req.url, outputFileSystem, environments);
6124
+ let resolved = await getFileFromUrl(req.url, outputFileSystem, context1);
6120
6125
  if (!resolved) return void await goNext();
6121
6126
  if ('errorCode' in resolved) {
6122
6127
  403 === resolved.errorCode && logger.error(`[rsbuild:middleware] Malicious path "${req.url}".`), sendError(resolved.errorCode);
@@ -6268,7 +6273,7 @@ ${section.body}` : section.body).join("\n\n"));
6268
6273
  }, instance;
6269
6274
  };
6270
6275
  var UNKNOWN_FUNCTION = '<unknown>', chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i, chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/, winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i, geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i, geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i, javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i, nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
6271
- let resolveSourceLocation = async (stack, fs, environments)=>{
6276
+ let resolveSourceLocation = async (stack, fs, context)=>{
6272
6277
  let parsed = stack.split('\n').reduce(function(stack, line) {
6273
6278
  var line1, parts, line2, parts1, line3, parts2, parseResult = function(line) {
6274
6279
  var parts = chromeRe.exec(line);
@@ -6318,7 +6323,7 @@ ${section.body}` : section.body).join("\n\n"));
6318
6323
  if (!parsed.length) return;
6319
6324
  let frame = parsed.find((frame)=>null !== frame.file && null !== frame.column && null !== frame.lineNumber && SCRIPT_REGEX.test(frame.file));
6320
6325
  if (!frame) return;
6321
- let { file, column, lineNumber } = frame, sourceMapInfo = await getFileFromUrl(`${file}.map`, fs, environments);
6326
+ let { file, column, lineNumber } = frame, sourceMapInfo = await getFileFromUrl(`${file}.map`, fs, context);
6322
6327
  if (!sourceMapInfo || 'errorCode' in sourceMapInfo) return;
6323
6328
  let readFile = (0, external_node_util_namespaceObject.promisify)(fs.readFile);
6324
6329
  try {
@@ -6334,7 +6339,7 @@ ${section.body}` : section.body).join("\n\n"));
6334
6339
  error instanceof Error && logger.debug(`failed to map source map position: ${error.message}`);
6335
6340
  }
6336
6341
  }, formatErrorLocation = async (stack, context, fs)=>{
6337
- let parsed = await resolveSourceLocation(stack, fs, context.environments);
6342
+ let parsed = await resolveSourceLocation(stack, fs, context);
6338
6343
  if (!parsed) return;
6339
6344
  let { source, line, column } = parsed;
6340
6345
  if (!source) return;
@@ -6420,8 +6425,8 @@ ${section.body}` : section.body).join("\n\n"));
6420
6425
  this.onConnect(socket, query.token);
6421
6426
  });
6422
6427
  }
6423
- onBuildDone(token) {
6424
- this.reportedBrowserLogs.clear(), this.socketsMap.size && this.sendStats({
6428
+ onBuildDone() {
6429
+ if (this.reportedBrowserLogs.clear(), this.socketsMap.size) for (let token of this.socketsMap.keys())this.sendStats({
6425
6430
  token
6426
6431
  });
6427
6432
  }
@@ -6681,16 +6686,15 @@ ${section.body}` : section.body).join("\n\n"));
6681
6686
  }
6682
6687
  }
6683
6688
  class BuildManager {
6684
- middleware;
6689
+ assetsMiddleware;
6685
6690
  outputFileSystem;
6686
6691
  socketServer;
6687
6692
  compiler;
6688
6693
  config;
6689
- publicPaths;
6690
6694
  resolvedPort;
6691
6695
  context;
6692
- constructor({ config, context, compiler, publicPaths, resolvedPort }){
6693
- this.config = config, this.context = context, this.compiler = compiler, this.publicPaths = publicPaths, this.resolvedPort = resolvedPort, this.outputFileSystem = external_node_fs_default(), this.socketServer = new SocketServer(context, config.dev, ()=>this.outputFileSystem);
6696
+ constructor({ config, context, compiler, resolvedPort }){
6697
+ this.config = config, this.context = context, this.compiler = compiler, this.resolvedPort = resolvedPort, this.outputFileSystem = external_node_fs_default(), this.socketServer = new SocketServer(context, config.dev, ()=>this.outputFileSystem), this.context.socketServer = this.socketServer;
6694
6698
  }
6695
6699
  async init() {
6696
6700
  await this.setupCompilationMiddleware(), this.socketServer.prepare();
@@ -6698,11 +6702,11 @@ ${section.body}` : section.body).join("\n\n"));
6698
6702
  this.outputFileSystem = (compiler_isMultiCompiler(compiler) ? compiler.compilers[0].outputFileSystem : compiler.outputFileSystem) || external_node_fs_default();
6699
6703
  }
6700
6704
  watch() {
6701
- this.middleware.watch();
6705
+ this.assetsMiddleware.watch();
6702
6706
  }
6703
6707
  async close() {
6704
- await this.socketServer.close(), this.middleware && await new Promise((resolve)=>{
6705
- this.middleware.close(()=>{
6708
+ await this.socketServer.close(), this.assetsMiddleware && await new Promise((resolve)=>{
6709
+ this.assetsMiddleware.close(()=>{
6706
6710
  resolve();
6707
6711
  });
6708
6712
  }), await new Promise((resolve)=>{
@@ -6713,19 +6717,14 @@ ${section.body}` : section.body).join("\n\n"));
6713
6717
  }
6714
6718
  readFileSync = (fileName)=>'readFileSync' in this.outputFileSystem ? this.outputFileSystem.readFileSync(fileName, 'utf-8') : external_node_fs_default().readFileSync(fileName, 'utf-8');
6715
6719
  async setupCompilationMiddleware() {
6716
- let { config, context, publicPaths } = this, middleware = await assetsMiddleware({
6720
+ let { config, context } = this, middleware = await assets_middleware_assetsMiddleware({
6717
6721
  config,
6718
6722
  context,
6719
6723
  compiler: this.compiler,
6720
6724
  socketServer: this.socketServer,
6721
6725
  resolvedPort: this.resolvedPort
6722
- }), { base } = config.server, assetPrefixes = publicPaths.map(getPathnameFromUrl).map((prefix)=>base && '/' !== base ? stripBase(prefix, base) : prefix), wrapper = (req, res, next)=>{
6723
- let { url } = req, assetPrefix = url && assetPrefixes.find((prefix)=>url.startsWith(prefix));
6724
- assetPrefix && '/' !== assetPrefix ? (req.url = url.slice(assetPrefix.length - 1), middleware(req, res, (...args)=>{
6725
- req.url = url, next(...args);
6726
- })) : middleware(req, res, next);
6727
- };
6728
- wrapper.close = middleware.close, wrapper.watch = middleware.watch, this.middleware = wrapper;
6726
+ });
6727
+ this.assetsMiddleware = middleware;
6729
6728
  }
6730
6729
  }
6731
6730
  let isCliShortcutsEnabled = (config)=>config.dev.cliShortcuts && isTTY('stdin');
@@ -7304,18 +7303,18 @@ ${section.body}` : section.body).join("\n\n"));
7304
7303
  let startCompile = async ()=>{
7305
7304
  let compiler = customCompiler || await createCompiler();
7306
7305
  if (!compiler) throw Error(`${color.dim('[rsbuild:server]')} Failed to get compiler instance.`);
7307
- compiler?.hooks.watchRun.tap('rsbuild:watchRun', ()=>{
7306
+ let publicPaths = compiler_isMultiCompiler(compiler) ? compiler.compilers.map(getPublicPathFromCompiler) : [
7307
+ getPublicPathFromCompiler(compiler)
7308
+ ], { base } = config.server;
7309
+ context.publicPathnames = publicPaths.map(getPathnameFromUrl).map((prefix)=>base && '/' !== base ? stripBase(prefix, base) : prefix), compiler?.hooks.watchRun.tap('rsbuild:watchRun', ()=>{
7308
7310
  lastStats && (waitLastCompileDoneResolve && (waitLastCompileDoneResolve(), waitLastCompileDoneResolve = null), waitLastCompileDone = new Promise((resolve)=>{
7309
7311
  waitLastCompileDoneResolve = resolve;
7310
7312
  }));
7311
7313
  });
7312
- let publicPaths = compiler_isMultiCompiler(compiler) ? compiler.compilers.map(getPublicPathFromCompiler) : [
7313
- getPublicPathFromCompiler(compiler)
7314
- ], buildManager = new BuildManager({
7314
+ let buildManager = new BuildManager({
7315
7315
  context,
7316
7316
  config,
7317
7317
  compiler,
7318
- publicPaths: publicPaths,
7319
7318
  resolvedPort: port
7320
7319
  });
7321
7320
  return await buildManager.init(), buildManager;
@@ -7544,12 +7543,12 @@ ${section.body}` : section.body).join("\n\n"));
7544
7543
  }
7545
7544
  })({
7546
7545
  environments: devServerAPI.environments
7547
- })), buildManager && (middlewares.push(buildManager.middleware), upgradeEvents.push(buildManager.socketServer.upgrade), middlewares.push((req, res, next)=>{
7546
+ })), buildManager && (middlewares.push(buildManager.assetsMiddleware), upgradeEvents.push(buildManager.socketServer.upgrade), middlewares.push((req, res, next)=>{
7548
7547
  req.url?.endsWith('.hot-update.json') && 'OPTIONS' !== req.method ? (res.statusCode = 404, res.end()) : next();
7549
7548
  })), buildManager && middlewares.push((({ distPath, buildManager })=>async (req, res, next)=>{
7550
7549
  if (!maybeHTMLRequest(req)) return void next();
7551
7550
  let pathname = req.url.replace(postfixRE, ''), rewrite = (newUrl)=>{
7552
- req.url = newUrl, buildManager.middleware(req, res, (...args)=>{
7551
+ req.url = newUrl, buildManager.assetsMiddleware(req, res, (...args)=>{
7553
7552
  next(...args);
7554
7553
  });
7555
7554
  };
@@ -7565,11 +7564,11 @@ ${section.body}` : section.body).join("\n\n"));
7565
7564
  buildManager,
7566
7565
  distPath: context.distPath
7567
7566
  })), normalizePublicDirs(server?.publicDir))){
7568
- let sirv = requireCompiledPackage('sirv'), { name } = publicDir, assetMiddleware = sirv((0, external_node_path_.isAbsolute)(name) ? name : (0, external_node_path_.join)(pwd, name), {
7567
+ let sirv = requireCompiledPackage('sirv'), { name } = publicDir, servePublicDirMiddleware = sirv((0, external_node_path_.isAbsolute)(name) ? name : (0, external_node_path_.join)(pwd, name), {
7569
7568
  etag: !0,
7570
7569
  dev: !0
7571
7570
  });
7572
- middlewares.push(assetMiddleware);
7571
+ middlewares.push(servePublicDirMiddleware);
7573
7572
  }
7574
7573
  for (let callback of postCallbacks)callback();
7575
7574
  return buildManager && middlewares.push((({ htmlFallback, distPath, buildManager })=>async (req, res, next)=>{
@@ -7577,7 +7576,7 @@ ${section.body}` : section.body).join("\n\n"));
7577
7576
  let filePath = external_node_path_default().join(distPath, 'index.html');
7578
7577
  if (await middlewares_isFileExists(filePath, buildManager.outputFileSystem)) {
7579
7578
  let newUrl = '/index.html';
7580
- 'verbose' === logger.level && logger.debug(` ${req.method} ${req.url} ${color.yellow('fallback to')} ${newUrl}`), req.url = newUrl, buildManager.middleware(req, res, (...args)=>{
7579
+ 'verbose' === logger.level && logger.debug(` ${req.method} ${req.url} ${color.yellow('fallback to')} ${newUrl}`), req.url = newUrl, buildManager.assetsMiddleware(req, res, (...args)=>{
7581
7580
  next(...args);
7582
7581
  });
7583
7582
  return;
@@ -7587,7 +7586,7 @@ ${section.body}` : section.body).join("\n\n"));
7587
7586
  buildManager,
7588
7587
  distPath: context.distPath,
7589
7588
  htmlFallback: server.htmlFallback
7590
- })), server.historyApiFallback && (middlewares.push(historyApiFallbackMiddleware(!0 === server.historyApiFallback ? {} : server.historyApiFallback)), buildManager?.middleware && middlewares.push(buildManager.middleware)), middlewares.push(faviconFallbackMiddleware), {
7589
+ })), server.historyApiFallback && (middlewares.push(historyApiFallbackMiddleware(!0 === server.historyApiFallback ? {} : server.historyApiFallback)), buildManager?.assetsMiddleware && middlewares.push(buildManager.assetsMiddleware)), middlewares.push(faviconFallbackMiddleware), {
7591
7590
  onUpgrade: (...args)=>{
7592
7591
  for (let cb of upgradeEvents)cb(...args);
7593
7592
  }
@@ -7714,7 +7713,7 @@ ${section.body}` : section.body).join("\n\n"));
7714
7713
  })), this.applyStaticAssetMiddleware(), historyApiFallback && (this.middlewares.use(historyApiFallbackMiddleware(!0 === historyApiFallback ? {} : historyApiFallback)), this.applyStaticAssetMiddleware()), this.middlewares.use(faviconFallbackMiddleware), this.middlewares.use(optionsFallbackMiddleware), this.middlewares.use(notFoundMiddleware);
7715
7714
  }
7716
7715
  applyStaticAssetMiddleware() {
7717
- let { output: { path, assetPrefixes }, serverConfig: { htmlFallback } } = this.options, assetMiddleware = requireCompiledPackage('sirv')(path, {
7716
+ let { output: { path, assetPrefixes }, serverConfig: { htmlFallback } } = this.options, assetsMiddleware = requireCompiledPackage('sirv')(path, {
7718
7717
  etag: !0,
7719
7718
  dev: !0,
7720
7719
  ignores: [
@@ -7724,9 +7723,9 @@ ${section.body}` : section.body).join("\n\n"));
7724
7723
  });
7725
7724
  this.middlewares.use((req, res, next)=>{
7726
7725
  let url = req.url, assetPrefix = url && assetPrefixes.find((prefix)=>url.startsWith(prefix));
7727
- assetPrefix && url?.startsWith(assetPrefix) ? (req.url = url.slice(assetPrefix.length), assetMiddleware(req, res, (...args)=>{
7726
+ assetPrefix && url?.startsWith(assetPrefix) ? (req.url = url.slice(assetPrefix.length), assetsMiddleware(req, res, (...args)=>{
7728
7727
  req.url = url, next(...args);
7729
- })) : assetMiddleware(req, res, next);
7728
+ })) : assetsMiddleware(req, res, next);
7730
7729
  });
7731
7730
  }
7732
7731
  async close() {}
@@ -9261,7 +9260,7 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9261
9260
  headTags,
9262
9261
  bodyTags
9263
9262
  };
9264
- }), api.modifyBundlerChain((chain, { CHAIN_ID, environment })=>{
9263
+ }), api.modifyBundlerChain((chain, { CHAIN_ID, environment, isDev })=>{
9265
9264
  let { config, htmlPaths } = environment;
9266
9265
  if (0 === Object.keys(htmlPaths).length) return;
9267
9266
  let { performance: { preload, prefetch } } = config, HTMLCount = chain.entryPoints.values().length, excludes = ((config)=>{
@@ -9279,7 +9278,8 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9279
9278
  ] : excludes), chain.plugin(CHAIN_ID.PLUGIN.HTML_PREFETCH).use(HtmlResourceHintsPlugin, [
9280
9279
  options,
9281
9280
  'prefetch',
9282
- HTMLCount
9281
+ HTMLCount,
9282
+ isDev
9283
9283
  ]);
9284
9284
  }
9285
9285
  if (preload) {
@@ -9290,7 +9290,8 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9290
9290
  ] : excludes), chain.plugin(CHAIN_ID.PLUGIN.HTML_PRELOAD).use(HtmlResourceHintsPlugin, [
9291
9291
  options,
9292
9292
  'preload',
9293
- HTMLCount
9293
+ HTMLCount,
9294
+ isDev
9294
9295
  ]);
9295
9296
  }
9296
9297
  });
@@ -9873,11 +9874,11 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9873
9874
  }
9874
9875
  !function() {
9875
9876
  let { npm_execpath, npm_lifecycle_event, NODE_RUN_SCRIPT_NAME } = process.env, isBun = npm_execpath?.includes('.bun');
9876
- logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v1.5.15\n`);
9877
+ logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v1.5.17\n`);
9877
9878
  }();
9878
9879
  try {
9879
9880
  let cli, devDescription, devCommand, buildCommand, previewCommand, inspectCommand;
9880
- (cli = ((name = "")=>new CAC(name))('rsbuild')).version("1.5.15"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
9881
+ (cli = ((name = "")=>new CAC(name))('rsbuild')).version("1.5.17"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
9881
9882
  default: 'jiti'
9882
9883
  }).option('--env-dir <dir>', 'Set the directory for loading `.env` files').option('--env-mode <mode>', 'Set the env mode to load the `.env.[mode]` file').option('--environment <name>', 'Set the environment name(s) to build', {
9883
9884
  type: [
@@ -9934,7 +9935,7 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9934
9935
  logger.error('Failed to start Rsbuild CLI.'), logger.error(err);
9935
9936
  }
9936
9937
  }
9937
- let src_version = "1.5.15";
9938
+ let src_version = "1.5.17";
9938
9939
  })(), exports.PLUGIN_CSS_NAME = __webpack_exports__.PLUGIN_CSS_NAME, exports.PLUGIN_SWC_NAME = __webpack_exports__.PLUGIN_SWC_NAME, exports.createRsbuild = __webpack_exports__.createRsbuild, exports.defaultAllowedOrigins = __webpack_exports__.defaultAllowedOrigins, exports.defineConfig = __webpack_exports__.defineConfig, exports.ensureAssetPrefix = __webpack_exports__.ensureAssetPrefix, exports.loadConfig = __webpack_exports__.loadConfig, exports.loadEnv = __webpack_exports__.loadEnv, exports.logger = __webpack_exports__.logger, exports.mergeRsbuildConfig = __webpack_exports__.mergeRsbuildConfig, exports.rspack = __webpack_exports__.rspack, exports.runCLI = __webpack_exports__.runCLI, exports.version = __webpack_exports__.version, __webpack_exports__)-1 === [
9939
9940
  "PLUGIN_CSS_NAME",
9940
9941
  "PLUGIN_SWC_NAME",
package/dist/index.js CHANGED
@@ -2996,7 +2996,7 @@ function formatStatsError(stats, verbose) {
2996
2996
  let rawTrace = moduleNames.reverse().map((item)=>`\n ${item}`).join('');
2997
2997
  return color.dim(`Import traces (entry → error):${rawTrace}`);
2998
2998
  }(stats, fileName) ?? '';
2999
- message = `${/:\d+:\d+/.test(fileName) ? `File: ${color.cyan(fileName)}\n` : `File: ${color.cyan(`${fileName}:1:1`)}\n`}${mainMessage}${details}${stack}${moduleTrace}`;
2999
+ message = `${!fileName ? '' : /:\d+:\d+/.test(fileName) ? `File: ${color.cyan(fileName)}\n` : `File: ${color.cyan(`${fileName}:1:1`)}\n`}${mainMessage}${details}${stack}${moduleTrace}`;
3000
3000
  let innerError = '-- inner error --';
3001
3001
  return !verbose && message.includes(innerError) && (message = message.split(innerError)[0]), (message = (message = ((message)=>{
3002
3002
  let getTips = (moduleName)=>{
@@ -3226,11 +3226,11 @@ function getCommonParentPath(paths) {
3226
3226
  }
3227
3227
  return common.join(external_node_path_.sep);
3228
3228
  }
3229
- let getCompiledPath = (packageName)=>(0, external_node_path_.join)(COMPILED_PATH, packageName, 'index.js'), ensureAbsolutePath = (base, filePath)=>(0, external_node_path_.isAbsolute)(filePath) ? filePath : (0, external_node_path_.join)(base, filePath), getPathnameFromUrl = (publicPath)=>{
3229
+ let getCompiledPath = (packageName)=>(0, external_node_path_.join)(COMPILED_PATH, packageName, 'index.js'), ensureAbsolutePath = (base, filePath)=>(0, external_node_path_.isAbsolute)(filePath) ? filePath : (0, external_node_path_.join)(base, filePath), getPathnameFromUrl = (url)=>{
3230
3230
  try {
3231
- return publicPath ? new URL(publicPath).pathname : publicPath;
3231
+ return url ? new URL(url, 'http://localhost').pathname : url;
3232
3232
  } catch {
3233
- return publicPath;
3233
+ return url;
3234
3234
  }
3235
3235
  }, dedupeNestedPaths = (paths)=>paths.sort((p1, p2)=>p2.length > p1.length ? -1 : 1).reduce((prev, curr)=>prev.find((p)=>curr.startsWith(p) || curr === p) ? prev : prev.concat(curr), []), toPosixPath = (filepath)=>'/' === external_node_path_.sep ? filepath : filepath.replace(/\\/g, '/'), isFileSync = (filePath)=>{
3236
3236
  try {
@@ -3678,13 +3678,14 @@ async function updateEnvironmentContext(context, configs) {
3678
3678
  async function createContext(options, userConfig) {
3679
3679
  let { cwd } = options, rootPath = userConfig.root ? ensureAbsolutePath(cwd, userConfig.root) : cwd, rsbuildConfig = await withDefaultConfig(rootPath, userConfig), cachePath = (0, external_node_path_.join)(rootPath, 'node_modules', '.cache'), specifiedEnvironments = options.environment && options.environment.length > 0 ? options.environment : void 0, bundlerType = userConfig.provider ? 'webpack' : 'rspack';
3680
3680
  return {
3681
- version: "1.5.15",
3681
+ version: "1.5.17",
3682
3682
  rootPath,
3683
3683
  distPath: '',
3684
3684
  cachePath,
3685
3685
  callerName: options.callerName,
3686
3686
  bundlerType,
3687
3687
  environments: {},
3688
+ publicPathnames: [],
3688
3689
  hooks: {
3689
3690
  onExit: createAsyncHook(),
3690
3691
  onCloseBuild: createAsyncHook(),
@@ -4271,7 +4272,7 @@ async function createCompiler_createCompiler(options) {
4271
4272
  logger.info('build started...'), logRspackVersion();
4272
4273
  }), compiler.hooks.done.tap(HOOK_NAME, (statsInstance)=>{
4273
4274
  let stats = getRsbuildStats(statsInstance, compiler, context.action), hasErrors = statsInstance.hasErrors();
4274
- context.buildState.stats = stats, context.buildState.status = 'done', context.buildState.hasErrors = hasErrors;
4275
+ context.buildState.stats = stats, context.buildState.status = 'done', context.buildState.hasErrors = hasErrors, context.socketServer?.onBuildDone();
4275
4276
  let printTime = (statsItem, index)=>{
4276
4277
  if (statsItem.time) {
4277
4278
  let time = prettyTime(statsItem.time / 1000), { name } = rspackConfigs[index], suffix = name && isMultiCompiler ? color.dim(` (${name})`) : '';
@@ -5222,10 +5223,15 @@ function printServerURLs({ urls: originalUrls, port, routes, protocol, printUrls
5222
5223
  });
5223
5224
  if (!newUrls) return null;
5224
5225
  if (!Array.isArray(newUrls)) throw Error(`${color.dim('[rsbuild:config]')} "server.printUrls" must return an array, but got ${typeof newUrls}.`);
5225
- urls = newUrls.map((url)=>({
5226
+ urls = newUrls.map((u)=>{
5227
+ let { url, label } = 'string' == typeof u ? {
5228
+ url: u
5229
+ } : u;
5230
+ return {
5226
5231
  url,
5227
- label: getUrlLabel(url)
5228
- }));
5232
+ label: label ?? getUrlLabel(url)
5233
+ };
5234
+ });
5229
5235
  }
5230
5236
  if (0 === urls.length || 0 === routes.length && !useCustomUrl) return null;
5231
5237
  let message = function(urls, routes) {
@@ -5482,16 +5488,17 @@ class HtmlResourceHintsPlugin {
5482
5488
  resourceHints = [];
5483
5489
  type;
5484
5490
  HTMLCount;
5485
- constructor(options, type, HTMLCount){
5491
+ isDev;
5492
+ constructor(options, type, HTMLCount, isDev){
5486
5493
  this.options = {
5487
5494
  ...HtmlResourceHintsPlugin_defaultOptions,
5488
5495
  ...options
5489
- }, this.type = type, this.HTMLCount = HTMLCount;
5496
+ }, this.type = type, this.HTMLCount = HTMLCount, this.isDev = isDev;
5490
5497
  }
5491
5498
  apply(compiler) {
5492
5499
  compiler.hooks.compilation.tap(this.name, (compilation)=>{
5493
5500
  let pluginHooks = getHTMLPlugin().getCompilationHooks(compilation), pluginName = `HTML${upperFirst(this.type)}Plugin`;
5494
- pluginHooks.beforeAssetTagGeneration.tap(pluginName, (data)=>(this.resourceHints = function(options, type, compilation, data, HTMLCount) {
5501
+ pluginHooks.beforeAssetTagGeneration.tap(pluginName, (data)=>(this.resourceHints = function(options, type, compilation, data, HTMLCount, isDev) {
5495
5502
  let extractedChunks = function(compilation, includeType) {
5496
5503
  let chunks = [
5497
5504
  ...compilation.chunks
@@ -5538,7 +5545,7 @@ class HtmlResourceHintsPlugin {
5538
5545
  }))).reduce((accumulated, chunk)=>accumulated.concat([
5539
5546
  ...chunk.files,
5540
5547
  ...chunk.auxiliaryFiles || []
5541
- ]), []).filter((file)=>!file.endsWith('.map')))
5548
+ ]), []).filter((file)=>!(isDev && file.endsWith('.hot-update.js')) && !file.endsWith('.map')))
5542
5549
  ], options.include, options.exclude).sort(), links = [], { publicPath, crossOriginLoading } = compilation.outputOptions;
5543
5550
  for (let file of sortedFilteredFiles){
5544
5551
  let href = ensureAssetPrefix(file, publicPath), attributes = {
@@ -5563,7 +5570,7 @@ class HtmlResourceHintsPlugin {
5563
5570
  });
5564
5571
  }
5565
5572
  return links;
5566
- }(this.options, this.type, compilation, data, this.HTMLCount), data)), pluginHooks.alterAssetTags.tap(pluginName, (data)=>{
5573
+ }(this.options, this.type, compilation, data, this.HTMLCount, this.isDev), data)), pluginHooks.alterAssetTags.tap(pluginName, (data)=>{
5567
5574
  var resourceHints, scripts;
5568
5575
  return this.resourceHints && (data.assetTags.styles = [
5569
5576
  ...this.options.dedupe ? (resourceHints = this.resourceHints, scripts = data.assetTags.scripts, resourceHints.filter((resourceHint)=>!scripts.find((script)=>script.attributes.src === resourceHint.attributes.href))) : this.resourceHints,
@@ -5717,14 +5724,8 @@ async function resolveHostname(host = 'localhost') {
5717
5724
  }
5718
5725
  var on_finished = __webpack_require__("../../node_modules/.pnpm/on-finished@2.4.1/node_modules/on-finished/index.js"), on_finished_default = __webpack_require__.n(on_finished), range_parser = __webpack_require__("../../node_modules/.pnpm/range-parser@1.2.1/node_modules/range-parser/index.js"), range_parser_default = __webpack_require__.n(range_parser);
5719
5726
  let matchHtmlRegExp = /["'&<>]/, UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
5720
- async function getFileFromUrl(url, outputFileSystem, environments) {
5721
- let pathname;
5722
- try {
5723
- let urlObject = new URL(url, 'http://localhost');
5724
- urlObject.pathname && (pathname = external_node_querystring_unescape(urlObject.pathname));
5725
- } catch {
5726
- return;
5727
- }
5727
+ async function getFileFromUrl(url, outputFileSystem, context) {
5728
+ let pathname = external_node_querystring_unescape(getPathnameFromUrl(url));
5728
5729
  if (!pathname) return;
5729
5730
  if (pathname.includes('\0')) return {
5730
5731
  errorCode: 400
@@ -5732,13 +5733,18 @@ async function getFileFromUrl(url, outputFileSystem, environments) {
5732
5733
  if (UP_PATH_REGEXP.test(external_node_path_.default.normalize(`./${pathname}`))) return {
5733
5734
  errorCode: 403
5734
5735
  };
5735
- let distPaths = new Set(Object.values(environments).map((env)=>env.distPath)), stat = async (filename)=>new Promise((resolve, reject)=>{
5736
+ let stat = async (filename)=>new Promise((resolve, reject)=>{
5736
5737
  outputFileSystem.stat(filename, (err, stats)=>{
5737
5738
  err ? reject(err) : resolve(stats);
5738
5739
  });
5739
- });
5740
- for (let distPath of distPaths){
5741
- let fsStats, filename = external_node_path_.default.join(distPath, pathname);
5740
+ }), { environments, publicPathnames } = context, distPaths = Object.values(environments).map((env)=>env.distPath), possibleFilenames = new Set();
5741
+ for (let [index, distPath] of distPaths.entries()){
5742
+ let prefix = publicPathnames[index];
5743
+ prefix && '/' !== prefix && pathname.startsWith(prefix) && possibleFilenames.add(external_node_path_.default.join(distPath, pathname.slice(prefix.length)));
5744
+ }
5745
+ for (let distPath of distPaths)possibleFilenames.add(external_node_path_.default.join(distPath, pathname));
5746
+ for (let filename of possibleFilenames){
5747
+ let fsStats;
5742
5748
  try {
5743
5749
  fsStats = await stat(filename);
5744
5750
  } catch {
@@ -5810,7 +5816,7 @@ let CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/, statuses =
5810
5816
  }), acceptedMethods = [
5811
5817
  'GET',
5812
5818
  'HEAD'
5813
- ], noop = ()=>{}, assets_middleware_require = (0, external_node_module_.createRequire)(import.meta.url), isTsError = (error)=>'message' in error && error.stack?.includes('ts-checker-rspack-plugin'), assetsMiddleware = async ({ config, compiler, context, socketServer, resolvedPort })=>{
5819
+ ], noop = ()=>{}, assets_middleware_require = (0, external_node_module_.createRequire)(import.meta.url), isTsError = (error)=>'message' in error && error.stack?.includes('ts-checker-rspack-plugin'), assets_middleware_assetsMiddleware = async ({ config, compiler, context, socketServer, resolvedPort })=>{
5814
5820
  var config1, ready;
5815
5821
  let watching, writeToDiskValues, resolvedHost = await resolveHostname(config.server.host), { environments } = context;
5816
5822
  applyToCompiler(compiler, (compiler, index)=>{
@@ -5872,7 +5878,6 @@ let CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/, statuses =
5872
5878
  ] : statsErrors), socketServer.sendError(statsErrors, token);
5873
5879
  return;
5874
5880
  }
5875
- socketServer.onBuildDone(token);
5876
5881
  });
5877
5882
  })({
5878
5883
  context,
@@ -5928,7 +5933,6 @@ let CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/, statuses =
5928
5933
  }(writeToDisk, compilers), instance = (ready = (callback)=>{
5929
5934
  'done' === context.buildState.status ? callback() : callbacks.push(callback);
5930
5935
  }, async function(req, res, next) {
5931
- let { environments } = context;
5932
5936
  async function goNext() {
5933
5937
  return new Promise((resolve)=>{
5934
5938
  ready(()=>{
@@ -5982,7 +5986,7 @@ let CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/, statuses =
5982
5986
  var range, offset;
5983
5987
  let bufferOrStream, byteLength, end;
5984
5988
  if (!req.url) return void await goNext();
5985
- let resolved = await getFileFromUrl(req.url, outputFileSystem, environments);
5989
+ let resolved = await getFileFromUrl(req.url, outputFileSystem, context);
5986
5990
  if (!resolved) return void await goNext();
5987
5991
  if ('errorCode' in resolved) {
5988
5992
  403 === resolved.errorCode && logger.error(`[rsbuild:middleware] Malicious path "${req.url}".`), sendError(resolved.errorCode);
@@ -6130,7 +6134,7 @@ let CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/, statuses =
6130
6134
  }, instance;
6131
6135
  };
6132
6136
  var UNKNOWN_FUNCTION = '<unknown>', chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i, chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/, winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i, geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i, geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i, javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i, nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
6133
- let resolveSourceLocation = async (stack, fs, environments)=>{
6137
+ let resolveSourceLocation = async (stack, fs, context)=>{
6134
6138
  let parsed = stack.split('\n').reduce(function(stack, line) {
6135
6139
  var line1, parts, line2, parts1, line3, parts2, parseResult = function(line) {
6136
6140
  var parts = chromeRe.exec(line);
@@ -6180,7 +6184,7 @@ let resolveSourceLocation = async (stack, fs, environments)=>{
6180
6184
  if (!parsed.length) return;
6181
6185
  let frame = parsed.find((frame)=>null !== frame.file && null !== frame.column && null !== frame.lineNumber && SCRIPT_REGEX.test(frame.file));
6182
6186
  if (!frame) return;
6183
- let { file, column, lineNumber } = frame, sourceMapInfo = await getFileFromUrl(`${file}.map`, fs, environments);
6187
+ let { file, column, lineNumber } = frame, sourceMapInfo = await getFileFromUrl(`${file}.map`, fs, context);
6184
6188
  if (!sourceMapInfo || 'errorCode' in sourceMapInfo) return;
6185
6189
  let readFile = external_node_util_promisify(fs.readFile);
6186
6190
  try {
@@ -6196,7 +6200,7 @@ let resolveSourceLocation = async (stack, fs, environments)=>{
6196
6200
  error instanceof Error && logger.debug(`failed to map source map position: ${error.message}`);
6197
6201
  }
6198
6202
  }, formatErrorLocation = async (stack, context, fs)=>{
6199
- let parsed = await resolveSourceLocation(stack, fs, context.environments);
6203
+ let parsed = await resolveSourceLocation(stack, fs, context);
6200
6204
  if (!parsed) return;
6201
6205
  let { source, line, column } = parsed;
6202
6206
  if (!source) return;
@@ -6282,8 +6286,8 @@ class SocketServer {
6282
6286
  this.onConnect(socket, query.token);
6283
6287
  });
6284
6288
  }
6285
- onBuildDone(token) {
6286
- this.reportedBrowserLogs.clear(), this.socketsMap.size && this.sendStats({
6289
+ onBuildDone() {
6290
+ if (this.reportedBrowserLogs.clear(), this.socketsMap.size) for (let token of this.socketsMap.keys())this.sendStats({
6287
6291
  token
6288
6292
  });
6289
6293
  }
@@ -6541,16 +6545,15 @@ class SocketServer {
6541
6545
  }
6542
6546
  }
6543
6547
  class BuildManager {
6544
- middleware;
6548
+ assetsMiddleware;
6545
6549
  outputFileSystem;
6546
6550
  socketServer;
6547
6551
  compiler;
6548
6552
  config;
6549
- publicPaths;
6550
6553
  resolvedPort;
6551
6554
  context;
6552
- constructor({ config, context, compiler, publicPaths, resolvedPort }){
6553
- this.config = config, this.context = context, this.compiler = compiler, this.publicPaths = publicPaths, this.resolvedPort = resolvedPort, this.outputFileSystem = node_fs, this.socketServer = new SocketServer(context, config.dev, ()=>this.outputFileSystem);
6555
+ constructor({ config, context, compiler, resolvedPort }){
6556
+ this.config = config, this.context = context, this.compiler = compiler, this.resolvedPort = resolvedPort, this.outputFileSystem = node_fs, this.socketServer = new SocketServer(context, config.dev, ()=>this.outputFileSystem), this.context.socketServer = this.socketServer;
6554
6557
  }
6555
6558
  async init() {
6556
6559
  await this.setupCompilationMiddleware(), this.socketServer.prepare();
@@ -6558,11 +6561,11 @@ class BuildManager {
6558
6561
  this.outputFileSystem = (compiler_isMultiCompiler(compiler) ? compiler.compilers[0].outputFileSystem : compiler.outputFileSystem) || node_fs;
6559
6562
  }
6560
6563
  watch() {
6561
- this.middleware.watch();
6564
+ this.assetsMiddleware.watch();
6562
6565
  }
6563
6566
  async close() {
6564
- await this.socketServer.close(), this.middleware && await new Promise((resolve)=>{
6565
- this.middleware.close(()=>{
6567
+ await this.socketServer.close(), this.assetsMiddleware && await new Promise((resolve)=>{
6568
+ this.assetsMiddleware.close(()=>{
6566
6569
  resolve();
6567
6570
  });
6568
6571
  }), await new Promise((resolve)=>{
@@ -6573,19 +6576,14 @@ class BuildManager {
6573
6576
  }
6574
6577
  readFileSync = (fileName)=>'readFileSync' in this.outputFileSystem ? this.outputFileSystem.readFileSync(fileName, 'utf-8') : node_fs.readFileSync(fileName, 'utf-8');
6575
6578
  async setupCompilationMiddleware() {
6576
- let { config, context, publicPaths } = this, middleware = await assetsMiddleware({
6579
+ let { config, context } = this, middleware = await assets_middleware_assetsMiddleware({
6577
6580
  config,
6578
6581
  context,
6579
6582
  compiler: this.compiler,
6580
6583
  socketServer: this.socketServer,
6581
6584
  resolvedPort: this.resolvedPort
6582
- }), { base } = config.server, assetPrefixes = publicPaths.map(getPathnameFromUrl).map((prefix)=>base && '/' !== base ? stripBase(prefix, base) : prefix), wrapper = (req, res, next)=>{
6583
- let { url } = req, assetPrefix = url && assetPrefixes.find((prefix)=>url.startsWith(prefix));
6584
- assetPrefix && '/' !== assetPrefix ? (req.url = url.slice(assetPrefix.length - 1), middleware(req, res, (...args)=>{
6585
- req.url = url, next(...args);
6586
- })) : middleware(req, res, next);
6587
- };
6588
- wrapper.close = middleware.close, wrapper.watch = middleware.watch, this.middleware = wrapper;
6585
+ });
6586
+ this.assetsMiddleware = middleware;
6589
6587
  }
6590
6588
  }
6591
6589
  let isCliShortcutsEnabled = (config)=>config.dev.cliShortcuts && isTTY('stdin');
@@ -7159,18 +7157,18 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
7159
7157
  let startCompile = async ()=>{
7160
7158
  let compiler = customCompiler || await createCompiler();
7161
7159
  if (!compiler) throw Error(`${color.dim('[rsbuild:server]')} Failed to get compiler instance.`);
7162
- compiler?.hooks.watchRun.tap('rsbuild:watchRun', ()=>{
7160
+ let publicPaths = compiler_isMultiCompiler(compiler) ? compiler.compilers.map(getPublicPathFromCompiler) : [
7161
+ getPublicPathFromCompiler(compiler)
7162
+ ], { base } = config.server;
7163
+ context.publicPathnames = publicPaths.map(getPathnameFromUrl).map((prefix)=>base && '/' !== base ? stripBase(prefix, base) : prefix), compiler?.hooks.watchRun.tap('rsbuild:watchRun', ()=>{
7163
7164
  lastStats && (waitLastCompileDoneResolve && (waitLastCompileDoneResolve(), waitLastCompileDoneResolve = null), waitLastCompileDone = new Promise((resolve)=>{
7164
7165
  waitLastCompileDoneResolve = resolve;
7165
7166
  }));
7166
7167
  });
7167
- let publicPaths = compiler_isMultiCompiler(compiler) ? compiler.compilers.map(getPublicPathFromCompiler) : [
7168
- getPublicPathFromCompiler(compiler)
7169
- ], buildManager = new BuildManager({
7168
+ let buildManager = new BuildManager({
7170
7169
  context,
7171
7170
  config,
7172
7171
  compiler,
7173
- publicPaths: publicPaths,
7174
7172
  resolvedPort: port
7175
7173
  });
7176
7174
  return await buildManager.init(), buildManager;
@@ -7399,12 +7397,12 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
7399
7397
  }
7400
7398
  })({
7401
7399
  environments: devServerAPI.environments
7402
- })), buildManager && (middlewares.push(buildManager.middleware), upgradeEvents.push(buildManager.socketServer.upgrade), middlewares.push((req, res, next)=>{
7400
+ })), buildManager && (middlewares.push(buildManager.assetsMiddleware), upgradeEvents.push(buildManager.socketServer.upgrade), middlewares.push((req, res, next)=>{
7403
7401
  req.url?.endsWith('.hot-update.json') && 'OPTIONS' !== req.method ? (res.statusCode = 404, res.end()) : next();
7404
7402
  })), buildManager && middlewares.push((({ distPath, buildManager })=>async (req, res, next)=>{
7405
7403
  if (!maybeHTMLRequest(req)) return void next();
7406
7404
  let pathname = req.url.replace(postfixRE, ''), rewrite = (newUrl)=>{
7407
- req.url = newUrl, buildManager.middleware(req, res, (...args)=>{
7405
+ req.url = newUrl, buildManager.assetsMiddleware(req, res, (...args)=>{
7408
7406
  next(...args);
7409
7407
  });
7410
7408
  };
@@ -7420,11 +7418,11 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
7420
7418
  buildManager,
7421
7419
  distPath: context.distPath
7422
7420
  })), normalizePublicDirs(server?.publicDir))){
7423
- let sirv = requireCompiledPackage('sirv'), { name } = publicDir, assetMiddleware = sirv((0, external_node_path_.isAbsolute)(name) ? name : (0, external_node_path_.join)(pwd, name), {
7421
+ let sirv = requireCompiledPackage('sirv'), { name } = publicDir, servePublicDirMiddleware = sirv((0, external_node_path_.isAbsolute)(name) ? name : (0, external_node_path_.join)(pwd, name), {
7424
7422
  etag: !0,
7425
7423
  dev: !0
7426
7424
  });
7427
- middlewares.push(assetMiddleware);
7425
+ middlewares.push(servePublicDirMiddleware);
7428
7426
  }
7429
7427
  for (let callback of postCallbacks)callback();
7430
7428
  return buildManager && middlewares.push((({ htmlFallback, distPath, buildManager })=>async (req, res, next)=>{
@@ -7432,7 +7430,7 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
7432
7430
  let filePath = external_node_path_.default.join(distPath, 'index.html');
7433
7431
  if (await middlewares_isFileExists(filePath, buildManager.outputFileSystem)) {
7434
7432
  let newUrl = '/index.html';
7435
- 'verbose' === logger.level && logger.debug(` ${req.method} ${req.url} ${color.yellow('fallback to')} ${newUrl}`), req.url = newUrl, buildManager.middleware(req, res, (...args)=>{
7433
+ 'verbose' === logger.level && logger.debug(` ${req.method} ${req.url} ${color.yellow('fallback to')} ${newUrl}`), req.url = newUrl, buildManager.assetsMiddleware(req, res, (...args)=>{
7436
7434
  next(...args);
7437
7435
  });
7438
7436
  return;
@@ -7442,7 +7440,7 @@ async function devServer_createDevServer(options, createCompiler, config, { comp
7442
7440
  buildManager,
7443
7441
  distPath: context.distPath,
7444
7442
  htmlFallback: server.htmlFallback
7445
- })), server.historyApiFallback && (middlewares.push(historyApiFallbackMiddleware(!0 === server.historyApiFallback ? {} : server.historyApiFallback)), buildManager?.middleware && middlewares.push(buildManager.middleware)), middlewares.push(faviconFallbackMiddleware), {
7443
+ })), server.historyApiFallback && (middlewares.push(historyApiFallbackMiddleware(!0 === server.historyApiFallback ? {} : server.historyApiFallback)), buildManager?.assetsMiddleware && middlewares.push(buildManager.assetsMiddleware)), middlewares.push(faviconFallbackMiddleware), {
7446
7444
  onUpgrade: (...args)=>{
7447
7445
  for (let cb of upgradeEvents)cb(...args);
7448
7446
  }
@@ -7569,7 +7567,7 @@ class RsbuildProdServer {
7569
7567
  })), this.applyStaticAssetMiddleware(), historyApiFallback && (this.middlewares.use(historyApiFallbackMiddleware(!0 === historyApiFallback ? {} : historyApiFallback)), this.applyStaticAssetMiddleware()), this.middlewares.use(faviconFallbackMiddleware), this.middlewares.use(optionsFallbackMiddleware), this.middlewares.use(notFoundMiddleware);
7570
7568
  }
7571
7569
  applyStaticAssetMiddleware() {
7572
- let { output: { path, assetPrefixes }, serverConfig: { htmlFallback } } = this.options, assetMiddleware = requireCompiledPackage('sirv')(path, {
7570
+ let { output: { path, assetPrefixes }, serverConfig: { htmlFallback } } = this.options, assetsMiddleware = requireCompiledPackage('sirv')(path, {
7573
7571
  etag: !0,
7574
7572
  dev: !0,
7575
7573
  ignores: [
@@ -7579,9 +7577,9 @@ class RsbuildProdServer {
7579
7577
  });
7580
7578
  this.middlewares.use((req, res, next)=>{
7581
7579
  let url = req.url, assetPrefix = url && assetPrefixes.find((prefix)=>url.startsWith(prefix));
7582
- assetPrefix && url?.startsWith(assetPrefix) ? (req.url = url.slice(assetPrefix.length), assetMiddleware(req, res, (...args)=>{
7580
+ assetPrefix && url?.startsWith(assetPrefix) ? (req.url = url.slice(assetPrefix.length), assetsMiddleware(req, res, (...args)=>{
7583
7581
  req.url = url, next(...args);
7584
- })) : assetMiddleware(req, res, next);
7582
+ })) : assetsMiddleware(req, res, next);
7585
7583
  });
7586
7584
  }
7587
7585
  async close() {}
@@ -9109,7 +9107,7 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9109
9107
  headTags,
9110
9108
  bodyTags
9111
9109
  };
9112
- }), api.modifyBundlerChain((chain, { CHAIN_ID, environment })=>{
9110
+ }), api.modifyBundlerChain((chain, { CHAIN_ID, environment, isDev })=>{
9113
9111
  let { config, htmlPaths } = environment;
9114
9112
  if (0 === Object.keys(htmlPaths).length) return;
9115
9113
  let { performance: { preload, prefetch } } = config, HTMLCount = chain.entryPoints.values().length, excludes = ((config)=>{
@@ -9127,7 +9125,8 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9127
9125
  ] : excludes), chain.plugin(CHAIN_ID.PLUGIN.HTML_PREFETCH).use(HtmlResourceHintsPlugin, [
9128
9126
  options,
9129
9127
  'prefetch',
9130
- HTMLCount
9128
+ HTMLCount,
9129
+ isDev
9131
9130
  ]);
9132
9131
  }
9133
9132
  if (preload) {
@@ -9138,7 +9137,8 @@ throw new Error('Failed to load Node.js addon: "${name}"\\n' + error);
9138
9137
  ] : excludes), chain.plugin(CHAIN_ID.PLUGIN.HTML_PRELOAD).use(HtmlResourceHintsPlugin, [
9139
9138
  options,
9140
9139
  'preload',
9141
- HTMLCount
9140
+ HTMLCount,
9141
+ isDev
9142
9142
  ]);
9143
9143
  }
9144
9144
  });
@@ -9720,11 +9720,11 @@ function runCLI() {
9720
9720
  }
9721
9721
  !function() {
9722
9722
  let { npm_execpath, npm_lifecycle_event, NODE_RUN_SCRIPT_NAME } = process.env, isBun = npm_execpath?.includes('.bun');
9723
- logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v1.5.15\n`);
9723
+ logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v1.5.17\n`);
9724
9724
  }();
9725
9725
  try {
9726
9726
  let cli, devDescription, devCommand, buildCommand, previewCommand, inspectCommand;
9727
- (cli = ((name = "")=>new CAC(name))('rsbuild')).version("1.5.15"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
9727
+ (cli = ((name = "")=>new CAC(name))('rsbuild')).version("1.5.17"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
9728
9728
  default: 'jiti'
9729
9729
  }).option('--env-dir <dir>', 'Set the directory for loading `.env` files').option('--env-mode <mode>', 'Set the env mode to load the `.env.[mode]` file').option('--environment <name>', 'Set the environment name(s) to build', {
9730
9730
  type: [
@@ -9781,5 +9781,5 @@ function runCLI() {
9781
9781
  logger.error('Failed to start Rsbuild CLI.'), logger.error(err);
9782
9782
  }
9783
9783
  }
9784
- let src_version = "1.5.15";
9784
+ let src_version = "1.5.17";
9785
9785
  export { PLUGIN_CSS_NAME, PLUGIN_SWC_NAME, createRsbuild, defaultAllowedOrigins, defineConfig, ensureAssetPrefix, loadConfig_loadConfig as loadConfig, loadEnv, logger, mergeRsbuildConfig, rspack_rspack as rspack, runCLI, src_version as version };
@@ -8,7 +8,7 @@ export declare const getCompiledPath: (packageName: string) => string;
8
8
  * @returns Resolved absolute file path.
9
9
  */
10
10
  export declare const ensureAbsolutePath: (base: string, filePath: string) => string;
11
- export declare const getPathnameFromUrl: (publicPath: string) => string;
11
+ export declare const getPathnameFromUrl: (url: string) => string;
12
12
  /** dedupe and remove nested paths */
13
13
  export declare const dedupeNestedPaths: (paths: string[]) => string[];
14
14
  /**
@@ -24,7 +24,8 @@ export declare class HtmlResourceHintsPlugin implements RspackPluginInstance {
24
24
  resourceHints: HtmlRspackPlugin.HtmlTagObject[];
25
25
  type: LinkType;
26
26
  HTMLCount: number;
27
- constructor(options: ResourceHintsOptions, type: LinkType, HTMLCount: number);
27
+ isDev: boolean;
28
+ constructor(options: ResourceHintsOptions, type: LinkType, HTMLCount: number, isDev: boolean);
28
29
  apply(compiler: Compiler): void;
29
30
  }
30
31
  export {};
@@ -1,7 +1,11 @@
1
1
  import type { Stats as FSStats } from 'node:fs';
2
- import type { EnvironmentContext } from '../../types';
2
+ import type { InternalContext } from '../../types';
3
3
  import type { OutputFileSystem } from './index';
4
- export declare function getFileFromUrl(url: string, outputFileSystem: OutputFileSystem, environments: Record<string, EnvironmentContext>): Promise<{
4
+ /**
5
+ * Resolves URL to file path with security checks and retrieves file from
6
+ * the build output directories.
7
+ */
8
+ export declare function getFileFromUrl(url: string, outputFileSystem: OutputFileSystem, context: InternalContext): Promise<{
5
9
  filename: string;
6
10
  fsStats: FSStats;
7
11
  } | {
@@ -5,7 +5,6 @@ type Options = {
5
5
  context: InternalContext;
6
6
  config: NormalizedConfig;
7
7
  compiler: Rspack.Compiler | Rspack.MultiCompiler;
8
- publicPaths: string[];
9
8
  resolvedPort: number;
10
9
  };
11
10
  /**
@@ -14,15 +13,14 @@ type Options = {
14
13
  * 2. establish webSocket connect
15
14
  */
16
15
  export declare class BuildManager {
17
- middleware: AssetsMiddleware;
16
+ assetsMiddleware: AssetsMiddleware;
18
17
  outputFileSystem: Rspack.OutputFileSystem;
19
18
  socketServer: SocketServer;
20
19
  compiler: Rspack.Compiler | Rspack.MultiCompiler;
21
20
  private config;
22
- private publicPaths;
23
21
  private resolvedPort;
24
22
  private context;
25
- constructor({ config, context, compiler, publicPaths, resolvedPort, }: Options);
23
+ constructor({ config, context, compiler, resolvedPort }: Options);
26
24
  init(): Promise<void>;
27
25
  /**
28
26
  * Call `compiler.watch()` to start compiling.
@@ -49,7 +49,7 @@ export declare class SocketServer {
49
49
  private checkSockets;
50
50
  private clearHeartbeatTimer;
51
51
  prepare(): void;
52
- onBuildDone(token: string): void;
52
+ onBuildDone(): void;
53
53
  /**
54
54
  * Send error messages to the client and render error overlay
55
55
  */
@@ -277,7 +277,10 @@ export type PrintUrls = boolean | ((params: {
277
277
  port: number;
278
278
  routes: Routes;
279
279
  protocol: string;
280
- }) => string[] | void);
280
+ }) => (string | {
281
+ url: string;
282
+ label?: string;
283
+ })[] | void);
281
284
  export type PublicDirOptions = {
282
285
  /**
283
286
  * The name of the public directory, can be set as a relative path or an absolute path.
@@ -1,4 +1,5 @@
1
1
  import type { Hooks } from '../hooks';
2
+ import type { SocketServer } from '../server/socketServer';
2
3
  import type { NormalizedConfig, RsbuildConfig } from './config';
3
4
  import type { EnvironmentContext } from './hooks';
4
5
  import type { RsbuildPluginAPI } from './plugin';
@@ -95,4 +96,11 @@ export type InternalContext = RsbuildContext & {
95
96
  specifiedEnvironments?: string[];
96
97
  /** Build state information */
97
98
  buildState: BuildState;
99
+ /** The socket server instance. */
100
+ socketServer?: SocketServer;
101
+ /**
102
+ * Pathnames derived from public paths, stripped of `server.base`.
103
+ * Used for static asset serving.
104
+ */
105
+ publicPathnames: string[];
98
106
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsbuild/core",
3
- "version": "1.5.15",
3
+ "version": "1.5.17",
4
4
  "description": "The Rspack-based build tool.",
5
5
  "homepage": "https://rsbuild.rs",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "@rspack/core": "1.5.8",
50
50
  "@rspack/lite-tapable": "~1.0.1",
51
51
  "@swc/helpers": "^0.5.17",
52
- "core-js": "~3.45.1",
52
+ "core-js": "~3.46.0",
53
53
  "jiti": "^2.6.1"
54
54
  },
55
55
  "devDependencies": {