@rsbuild/core 2.2.0-beta.1 → 2.2.0-beta.2

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/626.js CHANGED
@@ -2996,7 +2996,7 @@ let withDefaultConfig = async (rootPath, userConfig)=>{
2996
2996
  await isFileExists(tsconfigPath) && (config.source.tsconfigPath = tsconfigPath);
2997
2997
  }
2998
2998
  return config;
2999
- }, exitHook_callbacks = new Set(), isCalled = !1, isRegistered = !1;
2999
+ }, restartPorts = new WeakMap(), exitHook_callbacks = new Set(), isCalled = !1, isRegistered = !1;
3000
3000
  function exit(exitCode, type) {
3001
3001
  if (!isCalled) {
3002
3002
  for (let callback of (isCalled = !0, exitHook_callbacks))callback(exitCode);
@@ -3425,7 +3425,7 @@ function createPublicContext(context) {
3425
3425
  async function createContext(options, userConfig, logger, loadConfigResult) {
3426
3426
  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, hooks = initHooks();
3427
3427
  return {
3428
- version: "2.2.0-beta.1",
3428
+ version: "2.2.0-beta.2",
3429
3429
  rootPath,
3430
3430
  configFile: loadConfigResult?.filePath ?? userConfig._privateMeta?.configFilePath,
3431
3431
  configFileDependencies: loadConfigResult?.dependencies ?? userConfig._privateMeta?.configFileDependencies ?? [],
@@ -3439,9 +3439,16 @@ async function createContext(options, userConfig, logger, loadConfigResult) {
3439
3439
  publicPathnames: [],
3440
3440
  hooks,
3441
3441
  restartManager: (({ onRestart, restart })=>{
3442
- let cleanups = new Set();
3442
+ let port, cleanups = new Set();
3443
3443
  return {
3444
3444
  canRestart: !!restart,
3445
+ setPort (nextPort) {
3446
+ port = nextPort;
3447
+ },
3448
+ inheritPort (options) {
3449
+ let inheritedPort = options ? restartPorts.get(options) : void 0;
3450
+ return options && restartPorts.delete(options), inheritedPort;
3451
+ },
3445
3452
  registerCleanup: (cleanup)=>(cleanups.add(cleanup), ()=>{
3446
3453
  cleanups.delete(cleanup);
3447
3454
  }),
@@ -3462,7 +3469,13 @@ async function createContext(options, userConfig, logger, loadConfigResult) {
3462
3469
  hasError || (hasError = !0, firstError = error);
3463
3470
  }
3464
3471
  if (hasError) throw firstError;
3465
- return restart(context);
3472
+ if ('dev' !== context.action || void 0 === port) return restart(context);
3473
+ restartPorts.set(context.options, port);
3474
+ try {
3475
+ return await restart(context);
3476
+ } finally{
3477
+ restartPorts.delete(context.options);
3478
+ }
3466
3479
  }
3467
3480
  };
3468
3481
  })({
@@ -5846,6 +5859,10 @@ let getPort = async ({ host, port, strictPort, tryLimits = 20 })=>{
5846
5859
  port,
5847
5860
  host
5848
5861
  }, ()=>{
5862
+ if (0 === port) {
5863
+ let address = server.address();
5864
+ address && 'string' != typeof address && (port = address.port);
5865
+ }
5849
5866
  found = !0, server.close(resolve);
5850
5867
  });
5851
5868
  });
@@ -5854,14 +5871,14 @@ let getPort = async ({ host, port, strictPort, tryLimits = 20 })=>{
5854
5871
  port++, attempts++;
5855
5872
  }
5856
5873
  if (!found) throw Error(`${color.dim('[rsbuild:server]')} Failed to find an available port after ${tryLimits + 1} attempts, starting from ${color.yellow(original)}.`);
5857
- if (port !== original && strictPort) throw Error(`${color.dim('[rsbuild:server]')} Port ${color.yellow(original)} is occupied, please choose another one.`);
5874
+ if (0 !== original && port !== original && strictPort) throw Error(`${color.dim('[rsbuild:server]')} Port ${color.yellow(original)} is occupied, please choose another one.`);
5858
5875
  return port;
5859
- }, resolvePort = async (config)=>{
5860
- let { host, port: originalPort, strictPort } = config.server, port = await getPort({
5876
+ }, resolvePort = async (config, lastPort)=>{
5877
+ let { host, port: originalPort, strictPort } = config.server, preferredPort = 0 === originalPort ? lastPort : void 0, port = await getPort({
5861
5878
  host,
5862
- port: originalPort,
5863
- strictPort
5864
- }), portTip = port !== originalPort ? `port ${originalPort} is in use, ${color.yellow(`using port ${port}.`)}` : void 0;
5879
+ port: preferredPort ?? originalPort,
5880
+ strictPort: void 0 === preferredPort && strictPort
5881
+ }), portTip = 0 !== originalPort && port !== originalPort ? `port ${originalPort} is in use, ${color.yellow(`using port ${port}.`)}` : void 0;
5865
5882
  return {
5866
5883
  port,
5867
5884
  portTip
@@ -6017,7 +6034,7 @@ async function open_open({ port, routes, config, protocol, clearCache, logger })
6017
6034
  })(config);
6018
6035
  clearCache && (openedURLs = []);
6019
6036
  let urls = [], host = await getHostInUrl(config.server.host), baseUrl = `${protocol}://${host}:${port}`;
6020
- for (let url of (targets.length ? urls.push(...targets.map((target)=>resolveUrl(replacePortPlaceholder(target, port), baseUrl))) : routes.length ? urls.push(`${baseUrl}${routes[0].pathname}`) : urls.push(baseUrl), before && await before(), urls))openedURLs.includes(url) || (openBrowser(url, logger), openedURLs.push(url));
6037
+ for (let url of (targets.length ? urls.push(...targets.map((target)=>resolveUrl(replacePortPlaceholder(target, port), baseUrl))) : routes.length ? urls.push(`${baseUrl}${routes[0].pathname}`) : urls.push(baseUrl), before && await before(), urls))openedURLs.includes(url) || (await openBrowser(url, logger), openedURLs.push(url));
6021
6038
  }
6022
6039
  let getServerUrlFromClientConfig = async (config, context)=>{
6023
6040
  let { assetPrefix } = config.dev;
@@ -6072,7 +6089,7 @@ function pluginModuleFederation() {
6072
6089
  let { moduleFederation } = config;
6073
6090
  if (moduleFederation?.options && moduleFederation.options.exposes) {
6074
6091
  let userConfig = api.getRsbuildConfig('original');
6075
- config.dev ||= {}, config.server ||= {}, userConfig.server?.cors === void 0 && (config.server.cors = !0), config.server?.port && !config.dev.client?.port && (config.dev.client ||= {}, config.dev.client.port = config.server.port), userConfig.dev?.assetPrefix === void 0 && config.dev.assetPrefix === config.server?.base && (config.dev.assetPrefix = !0);
6092
+ config.dev ||= {}, config.server ||= {}, userConfig.server?.cors === void 0 && (config.server.cors = !0), config.server?.port === void 0 || config.dev.client?.port || (config.dev.client ||= {}, config.dev.client.port = 0 === config.server.port ? '<port>' : config.server.port), userConfig.dev?.assetPrefix === void 0 && config.dev.assetPrefix === config.server?.base && (config.dev.assetPrefix = !0);
6076
6093
  }
6077
6094
  }), api.modifyEnvironmentConfig((config)=>{
6078
6095
  config.moduleFederation?.options && (config.source.include = [
@@ -8174,7 +8191,9 @@ async function devServer_createDevServer(options, createCompiler, config, devSer
8174
8191
  ])
8175
8192
  }, { context } = options, { logger } = context;
8176
8193
  logger.debug('create dev server');
8177
- let { port, portTip } = await resolvePort(config), { middlewareMode, host } = config.server, isHttps = !!config.server.https, routes = getRoutes(context), fallbackPathname = 0 === routes.length && context.environmentList.some((item)=>'web' === item.config.output.target) ? config.server.base : void 0;
8194
+ let isDynamicPort = 0 === config.server.port, lastPort = isDynamicPort ? context.restartManager.inheritPort(devServerOptions) : void 0, { port, portTip } = await resolvePort(config, lastPort);
8195
+ isDynamicPort && context.restartManager.setPort(port);
8196
+ let { middlewareMode, host } = config.server, isHttps = !!config.server.https, routes = getRoutes(context), fallbackPathname = 0 === routes.length && context.environmentList.some((item)=>'web' === item.config.output.target) ? config.server.base : void 0;
8178
8197
  context.devServer = {
8179
8198
  hostname: host,
8180
8199
  port,
@@ -8321,14 +8340,24 @@ async function devServer_createDevServer(options, createCompiler, config, devSer
8321
8340
  listen: async ()=>{
8322
8341
  if (!httpServer) throw Error(`${color.dim('[rsbuild:server]')} Can not listen dev server as ${color.yellow('server.middlewareMode')} is enabled.`);
8323
8342
  let serverTerminator = getServerTerminator(httpServer);
8324
- return logger.debug('listen dev server'), context.hooks.onCloseDevServer.tap(serverTerminator), httpServer.listen({
8325
- host,
8326
- port
8327
- }), await once(httpServer, 'listening'), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware), state.devMiddlewares && httpServer.on('upgrade', state.devMiddlewares.onUpgrade), logger.debug('listen dev server done'), await devServer.afterListen(), {
8328
- port,
8329
- urls: urls.map((item)=>item.url),
8330
- server: devServer
8331
- };
8343
+ logger.debug('listen dev server'), context.hooks.onCloseDevServer.tap(serverTerminator);
8344
+ try {
8345
+ return httpServer.listen({
8346
+ host,
8347
+ port
8348
+ }), await once(httpServer, 'listening'), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware), state.devMiddlewares && httpServer.on('upgrade', state.devMiddlewares.onUpgrade), logger.debug('listen dev server done'), await devServer.afterListen(), {
8349
+ port,
8350
+ urls: urls.map((item)=>item.url),
8351
+ server: devServer
8352
+ };
8353
+ } catch (error) {
8354
+ try {
8355
+ await closeServer();
8356
+ } catch (closeError) {
8357
+ logger.error('Failed to close dev server after startup error.'), logger.error(closeError);
8358
+ }
8359
+ throw error;
8360
+ }
8332
8361
  },
8333
8362
  afterListen: async ()=>{
8334
8363
  await context.hooks.onAfterStartDevServer.callBatch({
@@ -8446,32 +8475,42 @@ async function startPreviewServer(context, config, { getPortSilently } = {}) {
8446
8475
  for (let callback of (base && '/' !== base && middlewares.use(getBaseUrlMiddleware({
8447
8476
  base
8448
8477
  })), middlewares.use(assetsMiddleware), middlewares.use(getHtmlCompletionMiddleware(htmlMiddlewareOptions)), historyApiFallback && (middlewares.use(historyApiFallback_historyApiFallbackMiddleware(logger, !0 === historyApiFallback ? {} : historyApiFallback)), middlewares.use(assetsMiddleware)), postSetupCallbacks))await callback();
8449
- if (serverConfig.htmlFallback && middlewares.use(getHtmlFallbackMiddleware({
8478
+ serverConfig.htmlFallback && middlewares.use(getHtmlFallbackMiddleware({
8450
8479
  ...htmlMiddlewareOptions,
8451
8480
  logger
8452
- })), middlewares.use(faviconFallbackMiddleware), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware), httpServer.listen({
8453
- host,
8454
- port
8455
- }), await once(httpServer, 'listening'), await context.hooks.onAfterStartPreviewServer.callBatch({
8456
- port,
8457
- routes,
8458
- environments: context.environments
8459
- }), registerCleanup(closeServer), printUrls(), cliShortcutsEnabled) {
8460
- let shortcutsOptions = 'boolean' == typeof config.dev.cliShortcuts ? {} : config.dev.cliShortcuts;
8461
- await setupCliShortcuts({
8462
- openPage,
8463
- closeServer,
8464
- printUrls,
8465
- help: shortcutsOptions.help,
8466
- customShortcuts: shortcutsOptions.custom,
8467
- logger
8468
- });
8481
+ })), middlewares.use(faviconFallbackMiddleware), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware);
8482
+ try {
8483
+ if (httpServer.listen({
8484
+ host,
8485
+ port
8486
+ }), await once(httpServer, 'listening'), await context.hooks.onAfterStartPreviewServer.callBatch({
8487
+ port,
8488
+ routes,
8489
+ environments: context.environments
8490
+ }), registerCleanup(closeServer), printUrls(), cliShortcutsEnabled) {
8491
+ let shortcutsOptions = 'boolean' == typeof config.dev.cliShortcuts ? {} : config.dev.cliShortcuts;
8492
+ await setupCliShortcuts({
8493
+ openPage,
8494
+ closeServer,
8495
+ printUrls,
8496
+ help: shortcutsOptions.help,
8497
+ customShortcuts: shortcutsOptions.custom,
8498
+ logger
8499
+ });
8500
+ }
8501
+ return !getPortSilently && portTip && logger.info(portTip), {
8502
+ port,
8503
+ urls: urls.map((item)=>item.url),
8504
+ server: previewServer
8505
+ };
8506
+ } catch (error) {
8507
+ try {
8508
+ await closeServer();
8509
+ } catch (closeError) {
8510
+ logger.error('Failed to close preview server after startup error.'), logger.error(closeError);
8511
+ }
8512
+ throw error;
8469
8513
  }
8470
- return !getPortSilently && portTip && logger.info(portTip), {
8471
- port,
8472
- urls: urls.map((item)=>item.url),
8473
- server: previewServer
8474
- };
8475
8514
  }
8476
8515
  function applyDefaultPlugins(pluginManager, context) {
8477
8516
  pluginManager.addPlugins([
@@ -8486,7 +8525,6 @@ function applyDefaultPlugins(pluginManager, context) {
8486
8525
  aggregateTimeout: 0
8487
8526
  }), chain.performance.hints(!1), chain.experiments({
8488
8527
  ...chain.get('experiments'),
8489
- nativeWatcher: !0,
8490
8528
  sourceImport: !0
8491
8529
  }), chain.module.parser.merge({
8492
8530
  javascript: {
@@ -9336,7 +9374,19 @@ try {
9336
9374
  javascript: {
9337
9375
  dynamicImportMode: 'eager'
9338
9376
  }
9339
- }), isServer || isWebWorker) {
9377
+ }), isServer) {
9378
+ if (!1 === splitChunks) chain.optimization.splitChunks(!1);
9379
+ else {
9380
+ let { preset = 'none', ...rest } = splitChunks;
9381
+ chain.optimization.splitChunks({
9382
+ chunks: 'all',
9383
+ ...getSplitChunksByPreset(config, preset),
9384
+ ...rest
9385
+ });
9386
+ }
9387
+ return;
9388
+ }
9389
+ if (isWebWorker) {
9340
9390
  if (!1 === splitChunks || 0 === Object.keys(splitChunks).length) chain.optimization.splitChunks(!1);
9341
9391
  else {
9342
9392
  let { preset = 'none', ...rest } = splitChunks;
@@ -9534,11 +9584,11 @@ try {
9534
9584
  {
9535
9585
  name: 'rsbuild:server',
9536
9586
  setup (api) {
9537
- let onStartServer = ({ port, routes })=>{
9587
+ let onStartServer = async ({ port, routes })=>{
9538
9588
  let config = api.getNormalizedConfig();
9539
9589
  if (config.server.open) {
9540
9590
  let protocol = config.server.https ? 'https' : 'http';
9541
- open_open({
9591
+ await open_open({
9542
9592
  port,
9543
9593
  routes,
9544
9594
  config,
@@ -9845,9 +9895,7 @@ async function createRsbuild(options = {}) {
9845
9895
  context,
9846
9896
  pluginManager,
9847
9897
  rsbuildOptions: resolvedOptions
9848
- }, createCompiler, config, {
9849
- ...options
9850
- })).listen();
9898
+ }, createCompiler, config, options)).listen();
9851
9899
  }, createDevServer = async (options)=>{
9852
9900
  context.action = 'dev', process.env.NODE_ENV || setNodeEnv('development');
9853
9901
  let config = await initRsbuildConfig({
@@ -10088,7 +10136,7 @@ let cliState = {
10088
10136
  loader: options.configLoader,
10089
10137
  command
10090
10138
  }), { content: config } = result;
10091
- if (config.dev ||= {}, config.source ||= {}, config.server ||= {}, options.base && (config.server.base = options.base), options.root && (config.root = root), options.mode && (config.mode = options.mode), options.logLevel && (config.logLevel = options.logLevel), options.open && !config.server?.open && (config.server.open = options.open), void 0 !== options.host && (config.server.host = options.host), options.port && (config.server.port = options.port), void 0 !== options.strictPort && (config.server.strictPort = options.strictPort), void 0 !== options.distPath) {
10139
+ if (config.dev ||= {}, config.source ||= {}, config.server ||= {}, options.base && (config.server.base = options.base), options.root && (config.root = root), options.mode && (config.mode = options.mode), options.logLevel && (config.logLevel = options.logLevel), options.open && !config.server?.open && (config.server.open = options.open), void 0 !== options.host && (config.server.host = options.host), void 0 !== options.port && (config.server.port = options.port), void 0 !== options.strictPort && (config.server.strictPort = options.strictPort), void 0 !== options.distPath) {
10092
10140
  config.output ||= {};
10093
10141
  let { distPath } = config.output;
10094
10142
  config.output.distPath = distPath && 'object' == typeof distPath ? {
@@ -10135,7 +10183,7 @@ let applyServerOptions = (command)=>{
10135
10183
  };
10136
10184
  function setupCommands(argv) {
10137
10185
  let cli = ((name = "")=>new CAC(name))('rsbuild');
10138
- cli.version("2.2.0-beta.1"), 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)', {
10186
+ cli.version("2.2.0-beta.2"), 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)', {
10139
10187
  default: 'auto'
10140
10188
  }).option('--dist-path <dir>', 'Set the root directory of output files').option('--source-map', 'Enable source map').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', {
10141
10189
  type: [
@@ -10200,7 +10248,7 @@ function setupCommands(argv) {
10200
10248
  }
10201
10249
  function showGreeting() {
10202
10250
  let { npm_execpath, npm_lifecycle_event, NODE_RUN_SCRIPT_NAME } = process.env, isBun = npm_execpath?.includes('.bun');
10203
- src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.2.0-beta.1\n`);
10251
+ src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.2.0-beta.2\n`);
10204
10252
  }
10205
10253
  function setupLogLevel(argv) {
10206
10254
  if (argv.length <= 3) return;
@@ -10222,5 +10270,5 @@ function runCLI({ argv = process.argv } = {}) {
10222
10270
  src_logger.error('Failed to start Rsbuild CLI.'), src_logger.error(err), process.exit(1);
10223
10271
  }
10224
10272
  }
10225
- let src_version = "2.2.0-beta.1";
10273
+ let src_version = "2.2.0-beta.2";
10226
10274
  export { PLUGIN_CSS_NAME, PLUGIN_SWC_NAME, core_rspack as rspack, createRsbuild, defaultAllowedOrigins, defineConfig, ensureAssetPrefix, loadConfig_loadConfig as loadConfig, loadEnv, logger_createLogger as createLogger, mergeRsbuildConfig, mrmime_lookup, runCLI, src_logger as logger, src_version as version };
@@ -3,6 +3,8 @@ import type { MaybePromise } from '../types/utils.js';
3
3
  type Cleanup = () => MaybePromise<void>;
4
4
  export type RestartManager = {
5
5
  /** Whether a restart executor is available. */ readonly canRestart: boolean;
6
+ /** Store the dynamic port for the next restart. */ setPort(port: number): void;
7
+ /** Consume the dynamic port associated with restart options. */ inheritPort(options?: object): number | undefined;
6
8
  /** Register a cleanup callback and return a function that unregisters it. */ registerCleanup(cleanup: Cleanup): () => void;
7
9
  /** Handle a restart request and return whether the restart succeeded. */ requestRestart(context: RestartContext): Promise<boolean>;
8
10
  };
@@ -60,7 +60,7 @@ export declare function printServerURLs({ urls: originalUrls, port, routes, prot
60
60
  strictPort: boolean;
61
61
  tryLimits?: number;
62
62
  }) => Promise<number>;
63
- export declare const resolvePort: (config: NormalizedConfig) => Promise<{
63
+ export declare const resolvePort: (config: NormalizedConfig, lastPort?: number) => Promise<{
64
64
  port: number;
65
65
  portTip: string | undefined;
66
66
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsbuild/core",
3
- "version": "2.2.0-beta.1",
3
+ "version": "2.2.0-beta.2",
4
4
  "description": "The Rspack-based build tool.",
5
5
  "homepage": "https://rsbuild.rs",
6
6
  "bugs": {