@rslib/core 0.0.18 → 0.1.1

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
@@ -3,11 +3,12 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_fs__ from "node:fs";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises__ from "node:fs/promises";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_node_path__ from "node:path";
5
5
  import * as __WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__ from "../compiled/picocolors/index.js";
6
- import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
7
6
  import * as __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__ from "../compiled/commander/index.js";
7
+ import * as __WEBPACK_EXTERNAL_MODULE__rsbuild_core__ from "@rsbuild/core";
8
8
  import * as __WEBPACK_EXTERNAL_MODULE_tinyglobby__ from "tinyglobby";
9
9
  import * as __WEBPACK_EXTERNAL_MODULE_node_module__ from "node:module";
10
10
  import * as __WEBPACK_EXTERNAL_MODULE_module__ from "module";
11
+ import * as __WEBPACK_EXTERNAL_MODULE__compiled_chokidar_index_js__ from "../compiled/chokidar/index.js";
11
12
  /**
12
13
  * Node.js built-in modules.
13
14
  * Copied from https://github.com/webpack/webpack/blob/dd44b206a9c50f4b4cb4d134e1a0bd0387b159a3/lib/node/NodeTargetPlugin.js#L12-L72
@@ -91,6 +92,9 @@ async function calcLongestCommonPath(absPaths) {
91
92
  if (stats?.isFile()) lca = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(lca);
92
93
  return lca;
93
94
  }
95
+ function getAbsolutePath(base, filepath) {
96
+ return (0, __WEBPACK_EXTERNAL_MODULE_node_path__.isAbsolute)(filepath) ? filepath : (0, __WEBPACK_EXTERNAL_MODULE_node_path__.join)(base, filepath);
97
+ }
94
98
  const readPackageJson = (rootPath)=>{
95
99
  const pkgJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(rootPath, './package.json');
96
100
  if (!__WEBPACK_EXTERNAL_MODULE_node_fs__["default"].existsSync(pkgJsonPath)) {
@@ -118,8 +122,9 @@ function omit(obj, keysObj) {
118
122
  return ret;
119
123
  }, {});
120
124
  }
121
- function isPluginIncluded(config, pluginName) {
122
- return Boolean(config.plugins?.some((plugin)=>{
125
+ function isPluginIncluded(pluginName, plugins) {
126
+ return Boolean(plugins?.some((plugin)=>{
127
+ if (Array.isArray(plugin)) return isPluginIncluded(pluginName, plugin);
123
128
  if ('object' == typeof plugin && null !== plugin && 'name' in plugin) return plugin.name === pluginName;
124
129
  return false;
125
130
  }));
@@ -127,13 +132,25 @@ function isPluginIncluded(config, pluginName) {
127
132
  function checkMFPlugin(config) {
128
133
  if ('mf' !== config.format) return true;
129
134
  // https://github.com/module-federation/core/blob/4e5c4b96ee45899f3ba5904b8927768980d5ad0e/packages/rsbuild-plugin/src/cli/index.ts#L17
130
- const added = isPluginIncluded(config, 'rsbuild:module-federation-enhanced');
135
+ const added = isPluginIncluded('rsbuild:module-federation-enhanced', config.plugins);
131
136
  if (!added) {
132
137
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.warn(`${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].green('format: "mf"')} should be used with ${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].blue('@module-federation/rsbuild-plugin')}", consider installing and adding it to plugins. Check the documentation (https://module-federation.io/guide/basic/rsbuild.html#rslib-module) to get started with "mf" output.`);
133
138
  process.exit(1);
134
139
  }
135
140
  return added;
136
141
  }
142
+ function debounce(func, wait) {
143
+ let timeoutId = null;
144
+ return (...args)=>{
145
+ if (null !== timeoutId) clearTimeout(timeoutId);
146
+ timeoutId = setTimeout(()=>{
147
+ func(...args);
148
+ }, wait);
149
+ };
150
+ }
151
+ /**
152
+ * Check if running in a TTY context
153
+ */ const isTTY = (type = 'stdout')=>('stdin' === type ? process.stdin.isTTY : process.stdout.isTTY) && !process.env.CI;
137
154
  // setup the logger level
138
155
  if (process.env.DEBUG) __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.level = 'verbose';
139
156
  function initNodeEnv() {
@@ -150,7 +167,7 @@ function prepareCli() {
150
167
  // Some package managers automatically output a blank line, some do not.
151
168
  const { npm_execpath } = process.env;
152
169
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
153
- __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.greet(` Rslib v0.0.18\n`);
170
+ __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.greet(` Rslib v0.1.1\n`);
154
171
  }
155
172
  const DEFAULT_CONFIG_NAME = 'rslib.config';
156
173
  const DEFAULT_CONFIG_EXTENSIONS = [
@@ -162,6 +179,10 @@ const DEFAULT_CONFIG_EXTENSIONS = [
162
179
  '.cts'
163
180
  ];
164
181
  const SWC_HELPERS = '@swc/helpers';
182
+ const RSLIB_ENTRY_QUERY = '__rslib_entry__';
183
+ const SHEBANG_PREFIX = '#!';
184
+ const SHEBANG_REGEX = /#!.*[\s\n\r]*$/;
185
+ const REACT_DIRECTIVE_REGEX = /^['"]use (client|server)['"](;?)[\s\n\r]*$/;
165
186
  const JS_EXTENSIONS = [
166
187
  'js',
167
188
  'mjs',
@@ -258,9 +279,9 @@ function cssExternalHandler(request, callback, jsExtension, auto, isStyleRedirec
258
279
  }
259
280
  return false;
260
281
  }
261
- const cssConfig_pluginName = 'rsbuild:lib-css';
282
+ const PLUGIN_NAME = 'rsbuild:lib-css';
262
283
  const pluginLibCss = (rootDir)=>({
263
- name: cssConfig_pluginName,
284
+ name: PLUGIN_NAME,
264
285
  setup (api) {
265
286
  api.modifyBundlerChain((config, { CHAIN_ID })=>{
266
287
  let isUsingCssExtract = false;
@@ -305,12 +326,14 @@ const composeCssConfig = (rootDir, bundle = true)=>{
305
326
  }
306
327
  };
307
328
  };
308
- const importMetaUrlShim = `/*#__PURE__*/ (function () {
329
+ // The shim will be injected in PostEntryPlugin.
330
+ const importMetaUrlShim = `const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
309
331
  return typeof document === 'undefined'
310
- ? new (module.require('url'.replace('', '')).URL)('file:' + __filename).href
332
+ ? new (require('url'.replace('', '')).URL)('file:' + __filename).href
311
333
  : (document.currentScript && document.currentScript.src) ||
312
334
  new URL('main.js', document.baseURI).href;
313
- })()`;
335
+ })();
336
+ `;
314
337
  // This Rsbuild plugin will shim `import.meta.url` for CommonJS modules.
315
338
  // - Replace `import.meta.url` with `importMetaUrl`.
316
339
  // - Inject `importMetaUrl` to the end of the module (can't inject at the beginning because of `"use strict";`).
@@ -321,7 +344,7 @@ const pluginCjsImportMetaUrlShim = ()=>({
321
344
  api.modifyEnvironmentConfig((config)=>{
322
345
  config.source.define = {
323
346
  ...config.source.define,
324
- 'import.meta.url': importMetaUrlShim
347
+ 'import.meta.url': '__rslib_import_meta_url__'
325
348
  };
326
349
  });
327
350
  }
@@ -345,6 +368,125 @@ const pluginEsmRequireShim = ()=>({
345
368
  });
346
369
  }
347
370
  });
371
+ const EntryChunkPlugin_require = (0, __WEBPACK_EXTERNAL_MODULE_node_module__.createRequire)(import.meta.url);
372
+ const EntryChunkPlugin_PLUGIN_NAME = 'rsbuild:lib-entry-chunk';
373
+ const LOADER_NAME = 'rsbuild:lib-entry-module';
374
+ const matchFirstLine = (source, regex)=>{
375
+ const lineBreakPos = source.match(/(\r\n|\n)/);
376
+ const firstLineContent = source.slice(0, lineBreakPos?.index);
377
+ const matched = regex.exec(firstLineContent);
378
+ if (!matched) return false;
379
+ return matched[0];
380
+ };
381
+ class EntryChunkPlugin {
382
+ reactDirectives = {};
383
+ shebangChmod = 493;
384
+ shebangEntries = {};
385
+ shebangInjectedAssets = new Set();
386
+ enabledImportMetaUrlShim;
387
+ constructor({ enabledImportMetaUrlShim = true }){
388
+ this.enabledImportMetaUrlShim = enabledImportMetaUrlShim;
389
+ }
390
+ apply(compiler) {
391
+ compiler.hooks.entryOption.tap(EntryChunkPlugin_PLUGIN_NAME, (_context, entries)=>{
392
+ for(const name in entries){
393
+ const entry = entries[name];
394
+ if (!entry) continue;
395
+ let first;
396
+ if (Array.isArray(entry)) first = entry[0];
397
+ else if (Array.isArray(entry.import)) first = entry.import[0];
398
+ else if ('string' == typeof entry) first = entry;
399
+ if ('string' != typeof first) continue;
400
+ const filename = first.split('?')[0];
401
+ const isJs = JS_EXTENSIONS_PATTERN.test(filename);
402
+ if (!isJs) continue;
403
+ const content = compiler.inputFileSystem.readFileSync(filename, {
404
+ encoding: 'utf-8'
405
+ });
406
+ // Shebang
407
+ if (content.startsWith(SHEBANG_PREFIX)) {
408
+ const shebangMatch = matchFirstLine(content, SHEBANG_REGEX);
409
+ if (shebangMatch) this.shebangEntries[name] = shebangMatch;
410
+ }
411
+ // React directive
412
+ const reactDirective = matchFirstLine(content, REACT_DIRECTIVE_REGEX);
413
+ if (reactDirective) this.reactDirectives[name] = reactDirective;
414
+ }
415
+ });
416
+ compiler.hooks.thisCompilation.tap(EntryChunkPlugin_PLUGIN_NAME, (compilation)=>{
417
+ compilation.hooks.chunkAsset.tap(EntryChunkPlugin_PLUGIN_NAME, (chunk, filename)=>{
418
+ const isJs = JS_EXTENSIONS_PATTERN.test(filename);
419
+ if (!isJs) return;
420
+ const name = chunk.name;
421
+ if (!name) return;
422
+ const shebangEntry = this.shebangEntries[name];
423
+ if (shebangEntry) this.shebangEntries[filename] = shebangEntry;
424
+ const reactDirective = this.reactDirectives[name];
425
+ if (reactDirective) this.reactDirectives[filename] = reactDirective;
426
+ });
427
+ });
428
+ compiler.hooks.make.tap(EntryChunkPlugin_PLUGIN_NAME, (compilation)=>{
429
+ compilation.hooks.processAssets.tap(EntryChunkPlugin_PLUGIN_NAME, (assets)=>{
430
+ if (!this.enabledImportMetaUrlShim) return;
431
+ const chunkAsset = Object.keys(assets).filter((name)=>JS_EXTENSIONS_PATTERN.test(name));
432
+ for (const name of chunkAsset)compilation.updateAsset(name, (old)=>{
433
+ const oldSource = old.source().toString();
434
+ const replaceSource = new __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.sources.ReplaceSource(old);
435
+ if (oldSource.startsWith('use strict;') || oldSource.startsWith('"use strict";')) replaceSource.replace(0, 11, `"use strict";\n${importMetaUrlShim}`);
436
+ else replaceSource.insert(0, importMetaUrlShim);
437
+ return replaceSource;
438
+ });
439
+ });
440
+ compilation.hooks.processAssets.tap({
441
+ name: EntryChunkPlugin_PLUGIN_NAME,
442
+ // Just after minify stage, to avoid from being minified.
443
+ stage: __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1
444
+ }, (assets)=>{
445
+ const chunkAsset = Object.keys(assets);
446
+ for (const name of chunkAsset){
447
+ const shebangValue = this.shebangEntries[name];
448
+ const reactDirectiveValue = this.reactDirectives[name];
449
+ if (shebangValue || reactDirectiveValue) compilation.updateAsset(name, (old)=>{
450
+ const replaceSource = new __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.sources.ReplaceSource(old);
451
+ // Shebang
452
+ if (shebangValue) {
453
+ replaceSource.insert(0, `${shebangValue}\n`);
454
+ this.shebangInjectedAssets.add(name);
455
+ }
456
+ // React directives
457
+ if (reactDirectiveValue) replaceSource.insert(0, `${reactDirectiveValue}\n`);
458
+ return replaceSource;
459
+ });
460
+ }
461
+ });
462
+ });
463
+ compiler.hooks.assetEmitted.tap(EntryChunkPlugin_PLUGIN_NAME, (file, { targetPath })=>{
464
+ if (this.shebangInjectedAssets.has(file)) (0, __WEBPACK_EXTERNAL_MODULE_node_fs__.chmodSync)(targetPath, this.shebangChmod);
465
+ });
466
+ }
467
+ }
468
+ const entryModuleLoaderRsbuildPlugin = ()=>({
469
+ name: EntryChunkPlugin_PLUGIN_NAME,
470
+ setup (api) {
471
+ api.modifyBundlerChain((config, { CHAIN_ID })=>{
472
+ config.module.rule(CHAIN_ID.RULE.JS).use(LOADER_NAME).loader(EntryChunkPlugin_require.resolve('./entryModuleLoader.js'));
473
+ });
474
+ }
475
+ });
476
+ const composeEntryChunkConfig = ({ enabledImportMetaUrlShim })=>({
477
+ plugins: [
478
+ entryModuleLoaderRsbuildPlugin()
479
+ ],
480
+ tools: {
481
+ rspack: {
482
+ plugins: [
483
+ new EntryChunkPlugin({
484
+ enabledImportMetaUrlShim
485
+ })
486
+ ]
487
+ }
488
+ }
489
+ });
348
490
  const getDefaultExtension = (options)=>{
349
491
  const { format, pkgJson, autoExtension } = options;
350
492
  let jsExtension = '.js';
@@ -1305,7 +1447,10 @@ async function loadConfig({ cwd = process.cwd(), path, envMode }) {
1305
1447
  path: configFilePath,
1306
1448
  envMode
1307
1449
  });
1308
- return content;
1450
+ return {
1451
+ content: content,
1452
+ filePath: configFilePath
1453
+ };
1309
1454
  }
1310
1455
  const composeExternalsWarnConfig = (format, ...externalsArray)=>{
1311
1456
  if ('esm' !== format) return {};
@@ -1564,7 +1709,10 @@ async function createConstantRsbuildConfig() {
1564
1709
  target: 'node',
1565
1710
  filenameHash: false,
1566
1711
  distPath: {
1567
- js: './'
1712
+ js: './',
1713
+ jsAsync: './',
1714
+ css: './',
1715
+ cssAsync: './'
1568
1716
  }
1569
1717
  }
1570
1718
  });
@@ -1675,9 +1823,9 @@ const composeFormatConfig = ({ format, bundle = true, umdName, pkgJson })=>{
1675
1823
  },
1676
1824
  // can not set nodeEnv to false, because mf format should build shared module.
1677
1825
  // If nodeEnv is false, the process.env.NODE_ENV in third-party packages's will not be replaced
1678
- // now we have not provide dev mode for users, so we can always set nodeEnv as 'production'
1679
1826
  optimization: {
1680
- nodeEnv: 'production'
1827
+ nodeEnv: 'production',
1828
+ moduleIds: 'deterministic'
1681
1829
  }
1682
1830
  }
1683
1831
  },
@@ -1700,9 +1848,20 @@ const composeShimsConfig = (format, shims)=>{
1700
1848
  require: shims?.esm?.require ?? false
1701
1849
  }
1702
1850
  };
1851
+ const enabledShims = {
1852
+ cjs: 'cjs' === format ? resolvedShims.cjs : {
1853
+ 'import.meta.url': false
1854
+ },
1855
+ esm: 'esm' === format ? resolvedShims.esm : {
1856
+ __filename: false,
1857
+ __dirname: false,
1858
+ require: false
1859
+ }
1860
+ };
1861
+ let rsbuildConfig = {};
1703
1862
  switch(format){
1704
1863
  case 'esm':
1705
- return {
1864
+ rsbuildConfig = {
1706
1865
  tools: {
1707
1866
  rspack: {
1708
1867
  node: {
@@ -1716,19 +1875,24 @@ const composeShimsConfig = (format, shims)=>{
1716
1875
  resolvedShims.esm.require && pluginEsmRequireShim()
1717
1876
  ].filter(Boolean)
1718
1877
  };
1878
+ break;
1719
1879
  case 'cjs':
1720
- return {
1880
+ rsbuildConfig = {
1721
1881
  plugins: [
1722
1882
  resolvedShims.cjs['import.meta.url'] && pluginCjsImportMetaUrlShim()
1723
1883
  ].filter(Boolean)
1724
1884
  };
1885
+ break;
1725
1886
  case 'umd':
1726
- return {};
1727
1887
  case 'mf':
1728
- return {};
1888
+ break;
1729
1889
  default:
1730
1890
  throw new Error(`Unsupported format: ${format}`);
1731
1891
  }
1892
+ return {
1893
+ rsbuildConfig,
1894
+ enabledShims
1895
+ };
1732
1896
  };
1733
1897
  const composeModuleImportWarn = (request)=>`The externalized commonjs request ${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].green(`"${request}"`)} will use ${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].blue('"module"')} external type in ESM format. If you want to specify other external type, considering set the request and type with ${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].blue('"output.externals"')}.`;
1734
1898
  const composeExternalsConfig = (format, externals)=>{
@@ -1737,7 +1901,7 @@ const composeExternalsConfig = (format, externals)=>{
1737
1901
  // should to be unified and merged together in the future.
1738
1902
  const externalsTypeMap = {
1739
1903
  esm: 'module-import',
1740
- cjs: 'commonjs',
1904
+ cjs: 'commonjs-import',
1741
1905
  umd: 'umd',
1742
1906
  // If use 'var', when projects import an external package like '@pkg', this will cause a syntax error such as 'var pkg = @pkg'.
1743
1907
  // If use 'umd', the judgement conditions may be affected by other packages that define variables like 'define'.
@@ -1769,16 +1933,18 @@ const composeAutoExtensionConfig = (config, autoExtension, pkgJson)=>{
1769
1933
  pkgJson,
1770
1934
  autoExtension
1771
1935
  });
1772
- return {
1773
- config: {
1774
- output: {
1775
- filename: {
1776
- js: `[name]${jsExtension}`,
1777
- ...config.output?.filename
1778
- }
1936
+ const updatedConfig = {
1937
+ output: {
1938
+ filename: {
1939
+ js: `[name]${jsExtension}`,
1940
+ ...config.output?.filename
1779
1941
  }
1780
- },
1781
- jsExtension,
1942
+ }
1943
+ };
1944
+ const updatedJsExtension = 'string' == typeof updatedConfig.output?.filename?.js && updatedConfig.output?.filename?.js ? (0, __WEBPACK_EXTERNAL_MODULE_node_path__.extname)(updatedConfig.output.filename.js) : jsExtension;
1945
+ return {
1946
+ config: updatedConfig,
1947
+ jsExtension: updatedJsExtension,
1782
1948
  dtsExtension
1783
1949
  };
1784
1950
  };
@@ -1809,6 +1975,18 @@ const composeSyntaxConfig = (target, syntax)=>{
1809
1975
  }
1810
1976
  };
1811
1977
  };
1978
+ const appendEntryQuery = (entry)=>{
1979
+ const newEntry = {};
1980
+ for (const [key, value] of Object.entries(entry)){
1981
+ let result = value;
1982
+ result = 'string' == typeof value ? `${value}?${RSLIB_ENTRY_QUERY}` : Array.isArray(value) ? value.map((item)=>`${item}?${RSLIB_ENTRY_QUERY}`) : {
1983
+ ...value,
1984
+ import: 'string' == typeof value.import ? `${value.import}?${RSLIB_ENTRY_QUERY}` : value.import.map((item)=>`${item}?${RSLIB_ENTRY_QUERY}`)
1985
+ };
1986
+ newEntry[key] = result;
1987
+ }
1988
+ return newEntry;
1989
+ };
1812
1990
  const composeEntryConfig = async (entries, bundle, root, cssModulesAuto)=>{
1813
1991
  if (!entries) return {
1814
1992
  entryConfig: {},
@@ -1817,7 +1995,7 @@ const composeEntryConfig = async (entries, bundle, root, cssModulesAuto)=>{
1817
1995
  if (false !== bundle) return {
1818
1996
  entryConfig: {
1819
1997
  source: {
1820
- entry: entries
1998
+ entry: appendEntryQuery(entries)
1821
1999
  }
1822
2000
  },
1823
2001
  lcp: null
@@ -1864,7 +2042,7 @@ const composeEntryConfig = async (entries, bundle, root, cssModulesAuto)=>{
1864
2042
  const lcp = await calcLongestCommonPath(Object.values(resolvedEntries));
1865
2043
  const entryConfig = {
1866
2044
  source: {
1867
- entry: resolvedEntries
2045
+ entry: appendEntryQuery(resolvedEntries)
1868
2046
  }
1869
2047
  };
1870
2048
  return {
@@ -1897,7 +2075,8 @@ const composeBundleConfig = (jsExtension, redirect, cssModulesAuto, bundle)=>{
1897
2075
  if (!JS_EXTENSIONS_PATTERN.test(request)) // If it does not match jsExtensionsPattern, we should do nothing, eg: ./foo.png
1898
2076
  return callback();
1899
2077
  request = request.replace(/\.[^.]+$/, jsExtension);
1900
- } else request = `${request}${jsExtension}`;
2078
+ } else // TODO: add redirect.extension option
2079
+ request = `${request}${jsExtension}`;
1901
2080
  }
1902
2081
  return callback(null, request);
1903
2082
  }
@@ -1908,7 +2087,7 @@ const composeBundleConfig = (jsExtension, redirect, cssModulesAuto, bundle)=>{
1908
2087
  };
1909
2088
  };
1910
2089
  const composeDtsConfig = async (libConfig, dtsExtension)=>{
1911
- const { output, autoExternal, banner, footer } = libConfig;
2090
+ const { autoExternal, banner, footer } = libConfig;
1912
2091
  let { dts } = libConfig;
1913
2092
  if (false === dts || void 0 === dts) return {};
1914
2093
  // DTS default to bundleless whether js is bundle or not
@@ -1920,10 +2099,10 @@ const composeDtsConfig = async (libConfig, dtsExtension)=>{
1920
2099
  plugins: [
1921
2100
  pluginDts({
1922
2101
  // Only setting ⁠dts.bundle to true will generate the bundled d.ts.
1923
- bundle: dts?.bundle ?? false,
1924
- distPath: dts?.distPath ?? output?.distPath?.root ?? './dist',
1925
- build: dts?.build ?? false,
1926
- abortOnError: dts?.abortOnError ?? true,
2102
+ bundle: dts?.bundle,
2103
+ distPath: dts?.distPath,
2104
+ build: dts?.build,
2105
+ abortOnError: dts?.abortOnError,
1927
2106
  dtsExtension: dts?.autoExtension ? dtsExtension : '.d.ts',
1928
2107
  autoExternal,
1929
2108
  banner: banner?.dts,
@@ -2010,14 +2189,15 @@ const composeExternalHelpersConfig = (externalHelpers, pkgJson)=>{
2010
2189
  }
2011
2190
  return defaultConfig;
2012
2191
  };
2013
- async function composeLibRsbuildConfig(config, configPath) {
2192
+ async function composeLibRsbuildConfig(config) {
2014
2193
  checkMFPlugin(config);
2015
- const rootPath = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath);
2194
+ // Get the absolute path of the root directory to align with Rsbuild's default behavior
2195
+ const rootPath = config.root ? getAbsolutePath(process.cwd(), config.root) : process.cwd();
2016
2196
  const pkgJson = readPackageJson(rootPath);
2017
2197
  const { compilerOptions } = await loadTsconfig(rootPath, config.source?.tsconfigPath);
2018
2198
  const cssModulesAuto = config.output?.cssModules?.auto ?? true;
2019
2199
  const { format, shims, bundle = true, banner = {}, footer = {}, autoExtension = true, autoExternal = true, externalHelpers = false, redirect = {}, umdName } = config;
2020
- const shimsConfig = composeShimsConfig(format, shims);
2200
+ const { rsbuildConfig: shimsConfig, enabledShims } = composeShimsConfig(format, shims);
2021
2201
  const formatConfig = composeFormatConfig({
2022
2202
  format: format,
2023
2203
  pkgJson: pkgJson,
@@ -2035,25 +2215,27 @@ async function composeLibRsbuildConfig(config, configPath) {
2035
2215
  pkgJson,
2036
2216
  userExternals: config.output?.externals
2037
2217
  });
2038
- const { entryConfig, lcp } = await composeEntryConfig(config.source?.entry, config.bundle, (0, __WEBPACK_EXTERNAL_MODULE_node_path__.dirname)(configPath), cssModulesAuto);
2218
+ const { entryConfig, lcp } = await composeEntryConfig(config.source?.entry, config.bundle, rootPath, cssModulesAuto);
2039
2219
  const cssConfig = composeCssConfig(lcp, config.bundle);
2220
+ const entryChunkConfig = composeEntryChunkConfig({
2221
+ enabledImportMetaUrlShim: enabledShims.cjs['import.meta.url']
2222
+ });
2040
2223
  const dtsConfig = await composeDtsConfig(config, dtsExtension);
2041
2224
  const externalsWarnConfig = composeExternalsWarnConfig(format, autoExternalConfig?.output?.externals, externalsConfig?.output?.externals);
2042
2225
  const minifyConfig = composeMinifyConfig(config);
2043
2226
  const bannerFooterConfig = composeBannerFooterConfig(banner, footer);
2044
2227
  const decoratorsConfig = composeDecoratorsConfig(compilerOptions, config.source?.decorators?.version);
2045
- return (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(formatConfig, shimsConfig, externalHelpersConfig, externalsWarnConfig, externalsConfig, autoExternalConfig, autoExtensionConfig, syntaxConfig, bundleConfig, targetConfig, entryConfig, cssConfig, minifyConfig, dtsConfig, bannerFooterConfig, decoratorsConfig);
2228
+ return (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(formatConfig, shimsConfig, externalHelpersConfig, externalsWarnConfig, externalsConfig, autoExternalConfig, autoExtensionConfig, syntaxConfig, bundleConfig, targetConfig, entryConfig, cssConfig, entryChunkConfig, minifyConfig, dtsConfig, bannerFooterConfig, decoratorsConfig);
2046
2229
  }
2047
- async function composeCreateRsbuildConfig(rslibConfig, path) {
2230
+ async function composeCreateRsbuildConfig(rslibConfig) {
2048
2231
  const constantRsbuildConfig = await createConstantRsbuildConfig();
2049
- const configPath = path ?? rslibConfig._privateMeta?.configFilePath;
2050
2232
  const { lib: libConfigsArray, ...sharedRsbuildConfig } = rslibConfig;
2051
2233
  if (!libConfigsArray) throw new Error(`Expect lib field to be an array, but got ${libConfigsArray}.`);
2052
2234
  const libConfigPromises = libConfigsArray.map(async (libConfig)=>{
2053
2235
  const userConfig = (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(sharedRsbuildConfig, libConfig);
2054
2236
  // Merge the configuration of each environment based on the shared Rsbuild
2055
2237
  // configuration and Lib configuration in the settings.
2056
- const libRsbuildConfig = await composeLibRsbuildConfig(userConfig, configPath);
2238
+ const libRsbuildConfig = await composeLibRsbuildConfig(userConfig);
2057
2239
  // Reset certain fields because they will be completely overridden by the upcoming merge.
2058
2240
  // We don't want to retain them in the final configuration.
2059
2241
  // The reset process should occur after merging the library configuration.
@@ -2062,7 +2244,7 @@ async function composeCreateRsbuildConfig(rslibConfig, path) {
2062
2244
  // Already manually sort and merge the externals configuration.
2063
2245
  userConfig.output ??= {};
2064
2246
  delete userConfig.output.externals;
2065
- return {
2247
+ const config = {
2066
2248
  format: libConfig.format,
2067
2249
  // The merge order represents the priority of the configuration
2068
2250
  // The priorities from high to low are as follows:
@@ -2073,6 +2255,7 @@ async function composeCreateRsbuildConfig(rslibConfig, path) {
2073
2255
  // In compose process of 2, we may read some config from 1, and reassemble the related config,
2074
2256
  // so before final mergeRsbuildConfig, we reset some specified fields
2075
2257
  config: (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(constantRsbuildConfig, libRsbuildConfig, omit(userConfig, {
2258
+ id: true,
2076
2259
  bundle: true,
2077
2260
  format: true,
2078
2261
  autoExtension: true,
@@ -2087,43 +2270,117 @@ async function composeCreateRsbuildConfig(rslibConfig, path) {
2087
2270
  umdName: true
2088
2271
  }))
2089
2272
  };
2273
+ if ('string' == typeof libConfig.id) config.id = libConfig.id;
2274
+ return config;
2090
2275
  });
2091
2276
  const composedRsbuildConfig = await Promise.all(libConfigPromises);
2092
2277
  return composedRsbuildConfig;
2093
2278
  }
2094
2279
  async function composeRsbuildEnvironments(rslibConfig) {
2095
- const rsbuildConfigObject = await composeCreateRsbuildConfig(rslibConfig);
2280
+ const rsbuildConfigWithLibInfo = await composeCreateRsbuildConfig(rslibConfig);
2281
+ // User provided ids should take precedence over generated ids.
2282
+ const usedIds = rsbuildConfigWithLibInfo.map(({ id })=>id).filter(Boolean);
2096
2283
  const environments = {};
2097
- const formatCount = rsbuildConfigObject.reduce((acc, { format })=>{
2284
+ const formatCount = rsbuildConfigWithLibInfo.reduce((acc, { format })=>{
2098
2285
  acc[format] = (acc[format] ?? 0) + 1;
2099
2286
  return acc;
2100
2287
  }, {});
2101
- const formatIndex = {
2102
- esm: 0,
2103
- cjs: 0,
2104
- umd: 0,
2105
- mf: 0
2288
+ const composeDefaultId = (format)=>{
2289
+ const nextDefaultId = (format, index)=>`${format}${1 === formatCount[format] && 0 === index ? '' : index}`;
2290
+ let index = 0;
2291
+ let candidateId = nextDefaultId(format, index);
2292
+ while(-1 !== usedIds.indexOf(candidateId))candidateId = nextDefaultId(format, ++index);
2293
+ usedIds.push(candidateId);
2294
+ return candidateId;
2106
2295
  };
2107
- for (const { format, config } of rsbuildConfigObject){
2108
- const currentFormatCount = formatCount[format];
2109
- const currentFormatIndex = formatIndex[format]++;
2110
- environments[1 === currentFormatCount ? format : `${format}${currentFormatIndex}`] = config;
2296
+ for (const { format, id, config } of rsbuildConfigWithLibInfo){
2297
+ const libId = 'string' == typeof id ? id : composeDefaultId(format);
2298
+ environments[libId] = config;
2111
2299
  }
2300
+ const conflictIds = usedIds.filter((id, index)=>usedIds.indexOf(id) !== index);
2301
+ if (conflictIds.length) throw new Error(`The following ids are duplicated: ${conflictIds.map((id)=>`"${id}"`).join(', ')}. Please change the "lib.id" to be unique.`);
2112
2302
  return environments;
2113
2303
  }
2114
2304
  const pruneEnvironments = (environments, libs)=>{
2115
2305
  if (!libs) return environments;
2116
2306
  return Object.fromEntries(Object.entries(environments).filter(([name])=>libs.includes(name)));
2117
2307
  };
2118
- async function build(config, options) {
2308
+ async function watchFilesForRestart(files, restart) {
2309
+ if (!files.length) return;
2310
+ const watcher = __WEBPACK_EXTERNAL_MODULE__compiled_chokidar_index_js__["default"].watch(files, {
2311
+ ignoreInitial: true,
2312
+ // If watching fails due to read permissions, the errors will be suppressed silently.
2313
+ ignorePermissionErrors: true,
2314
+ ignored: [
2315
+ '**/node_modules/**',
2316
+ '**/.git/**',
2317
+ '**/.DS_Store/**'
2318
+ ]
2319
+ });
2320
+ const callback = debounce(async (filePath)=>{
2321
+ watcher.close();
2322
+ await beforeRestart({
2323
+ filePath
2324
+ });
2325
+ await restart();
2326
+ }, 300);
2327
+ watcher.on('add', callback);
2328
+ watcher.on('change', callback);
2329
+ watcher.on('unlink', callback);
2330
+ }
2331
+ let cleaners = [];
2332
+ /**
2333
+ * Add a cleaner to handle side effects
2334
+ */ const onBeforeRestart = (cleaner)=>{
2335
+ cleaners.push(cleaner);
2336
+ };
2337
+ const clearConsole = ()=>{
2338
+ if (isTTY() && !process.env.DEBUG) process.stdout.write('\x1B[H\x1B[2J');
2339
+ };
2340
+ const beforeRestart = async ({ filePath, clear = true } = {})=>{
2341
+ if (clear) clearConsole();
2342
+ if (filePath) {
2343
+ const filename = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].basename(filePath);
2344
+ __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.info(`Restart because ${__WEBPACK_EXTERNAL_MODULE__compiled_picocolors_index_js__["default"].yellow(filename)} is changed.\n`);
2345
+ } else __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.info('Restarting...\n');
2346
+ for (const cleaner of cleaners)await cleaner();
2347
+ cleaners = [];
2348
+ };
2349
+ async function build(config, options = {}) {
2119
2350
  const environments = await composeRsbuildEnvironments(config);
2120
2351
  const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2121
2352
  rsbuildConfig: {
2122
- environments: pruneEnvironments(environments, options?.lib)
2353
+ environments: pruneEnvironments(environments, options.lib)
2123
2354
  }
2124
2355
  });
2125
- await rsbuildInstance.build({
2126
- watch: options?.watch
2356
+ const buildInstance = await rsbuildInstance.build({
2357
+ watch: options.watch
2358
+ });
2359
+ if (options.watch) onBeforeRestart(buildInstance.close);
2360
+ else await buildInstance.close();
2361
+ return rsbuildInstance;
2362
+ }
2363
+ async function loadRslibConfig(options) {
2364
+ const cwd = process.cwd();
2365
+ const root = options.root ? getAbsolutePath(cwd, options.root) : cwd;
2366
+ return loadConfig({
2367
+ cwd: root,
2368
+ path: options.config,
2369
+ envMode: options.envMode
2370
+ });
2371
+ }
2372
+ async function inspect(config, options = {}) {
2373
+ const environments = await composeRsbuildEnvironments(config);
2374
+ const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2375
+ rsbuildConfig: {
2376
+ environments: pruneEnvironments(environments, options.lib)
2377
+ }
2378
+ });
2379
+ await rsbuildInstance.inspectConfig({
2380
+ mode: options.mode,
2381
+ verbose: options.verbose,
2382
+ outputPath: options.output,
2383
+ writeToDisk: true
2127
2384
  });
2128
2385
  return rsbuildInstance;
2129
2386
  }
@@ -2140,7 +2397,8 @@ async function initMFRsbuild(rslibConfig) {
2140
2397
  const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2141
2398
  rsbuildConfig: mfRsbuildConfig.config
2142
2399
  });
2143
- await rsbuildInstance.startDevServer();
2400
+ const devServer = await rsbuildInstance.startDevServer();
2401
+ onBeforeRestart(devServer.server.close);
2144
2402
  return rsbuildInstance;
2145
2403
  }
2146
2404
  function changeEnvToDev(rsbuildConfig) {
@@ -2152,20 +2410,21 @@ function changeEnvToDev(rsbuildConfig) {
2152
2410
  tools: {
2153
2411
  rspack: {
2154
2412
  optimization: {
2155
- nodeEnv: 'development'
2413
+ nodeEnv: 'development',
2414
+ moduleIds: 'named'
2156
2415
  }
2157
2416
  }
2158
2417
  }
2159
2418
  });
2160
2419
  }
2161
2420
  const applyCommonOptions = (command)=>{
2162
- command.option('-c --config <config>', 'specify the configuration file, can be a relative or absolute path').option('--env-mode <mode>', 'specify the env mode to load the `.env.[mode]` file');
2421
+ command.option('-c --config <config>', 'specify the configuration file, can be a relative or absolute path').option('-r --root <root>', 'specify the project root directory, can be an absolute path or a path relative to cwd').option('--env-mode <mode>', 'specify the env mode to load the `.env.[mode]` file');
2163
2422
  };
2164
2423
  const repeatableOption = (value, previous)=>(previous ?? []).concat([
2165
2424
  value
2166
2425
  ]);
2167
2426
  function runCli() {
2168
- __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.name('rslib').usage('<command> [options]').version("0.0.18");
2427
+ __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.name('rslib').usage('<command> [options]').version("0.1.1");
2169
2428
  const buildCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('build');
2170
2429
  const inspectCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('inspect');
2171
2430
  const mfDevCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('mf dev');
@@ -2174,37 +2433,33 @@ function runCli() {
2174
2433
  inspectCommand,
2175
2434
  mfDevCommand
2176
2435
  ].forEach(applyCommonOptions);
2177
- buildCommand.option('--lib <name>', 'build the specified library (may be repeated)', repeatableOption).option('-w --watch', 'turn on watch mode, watch for changes and rebuild').description('build the library for production').action(async (options)=>{
2436
+ buildCommand.option('--lib <id>', 'build the specified library (may be repeated)', repeatableOption).option('-w --watch', 'turn on watch mode, watch for changes and rebuild').description('build the library for production').action(async (options)=>{
2178
2437
  try {
2179
- const rslibConfig = await loadConfig({
2180
- path: options.config,
2181
- envMode: options.envMode
2182
- });
2183
- await build(rslibConfig, options);
2438
+ const cliBuild = async ()=>{
2439
+ const { content: rslibConfig, filePath } = await loadRslibConfig(options);
2440
+ await build(rslibConfig, options);
2441
+ if (options.watch) watchFilesForRestart([
2442
+ filePath
2443
+ ], async ()=>{
2444
+ await cliBuild();
2445
+ });
2446
+ };
2447
+ await cliBuild();
2184
2448
  } catch (err) {
2185
2449
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error('Failed to build.');
2186
2450
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error(err);
2187
2451
  process.exit(1);
2188
2452
  }
2189
2453
  });
2190
- inspectCommand.description('inspect the Rsbuild / Rspack configs of Rslib projects').option('--lib <name>', 'inspect the specified library (may be repeated)', repeatableOption).option('--output <output>', 'specify inspect content output path', '.rsbuild').option('--verbose', 'show full function definitions in output').action(async (options)=>{
2454
+ inspectCommand.description('inspect the Rsbuild / Rspack configs of Rslib projects').option('--lib <id>', 'inspect the specified library (may be repeated)', repeatableOption).option('--output <output>', 'specify inspect content output path', '.rsbuild').option('--verbose', 'show full function definitions in output').action(async (options)=>{
2191
2455
  try {
2192
2456
  // TODO: inspect should output Rslib's config
2193
- const rslibConfig = await loadConfig({
2194
- path: options.config,
2195
- envMode: options.envMode
2196
- });
2197
- const environments = await composeRsbuildEnvironments(rslibConfig);
2198
- const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2199
- rsbuildConfig: {
2200
- environments: pruneEnvironments(environments, options.lib)
2201
- }
2202
- });
2203
- await rsbuildInstance.inspectConfig({
2457
+ const { content: rslibConfig } = await loadRslibConfig(options);
2458
+ await inspect(rslibConfig, {
2459
+ lib: options.lib,
2204
2460
  mode: options.mode,
2205
- verbose: options.verbose,
2206
- outputPath: options.output,
2207
- writeToDisk: true
2461
+ output: options.output,
2462
+ verbose: options.verbose
2208
2463
  });
2209
2464
  } catch (err) {
2210
2465
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error('Failed to inspect config.');
@@ -2214,11 +2469,17 @@ function runCli() {
2214
2469
  });
2215
2470
  mfDevCommand.description('start Rsbuild dev server of Module Federation format').action(async (options)=>{
2216
2471
  try {
2217
- const rslibConfig = await loadConfig({
2218
- path: options.config,
2219
- envMode: options.envMode
2220
- });
2221
- await startMFDevServer(rslibConfig);
2472
+ const cliMfDev = async ()=>{
2473
+ const { content: rslibConfig, filePath } = await loadRslibConfig(options);
2474
+ // TODO: support lib option in mf dev server
2475
+ await startMFDevServer(rslibConfig);
2476
+ watchFilesForRestart([
2477
+ filePath
2478
+ ], async ()=>{
2479
+ await cliMfDev();
2480
+ });
2481
+ };
2482
+ await cliMfDev();
2222
2483
  } catch (err) {
2223
2484
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error('Failed to start mf dev.');
2224
2485
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error(err);
@@ -2227,6 +2488,6 @@ function runCli() {
2227
2488
  });
2228
2489
  __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.parse();
2229
2490
  }
2230
- const src_version = "0.0.18";
2491
+ const src_rslib_entry_version = "0.1.1";
2231
2492
  var __webpack_exports__logger = __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger;
2232
- export { build, defineConfig, loadConfig, prepareCli, runCli, composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig, src_version as version, __webpack_exports__logger as logger };
2493
+ export { build, defineConfig, inspect, loadConfig, prepareCli, runCli, startMFDevServer, composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig, src_rslib_entry_version as version, __webpack_exports__logger as logger };