@rslib/core 0.1.4 → 0.2.0

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
@@ -8,10 +8,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
- /**
12
- * Node.js built-in modules.
13
- * Copied from https://github.com/webpack/webpack/blob/dd44b206a9c50f4b4cb4d134e1a0bd0387b159a3/lib/node/NodeTargetPlugin.js#L12-L72
14
- */ const nodeBuiltInModules = [
11
+ const nodeBuiltInModules = [
15
12
  'assert',
16
13
  'assert/strict',
17
14
  'async_hooks',
@@ -67,15 +64,10 @@ import * as __WEBPACK_EXTERNAL_MODULE_module__ from "module";
67
64
  'worker_threads',
68
65
  'zlib',
69
66
  /^node:/,
70
- // cspell:word pnpapi
71
- // Yarn PnP adds pnpapi as "builtin"
72
67
  'pnpapi'
73
68
  ];
74
69
  async function calcLongestCommonPath(absPaths) {
75
70
  if (0 === absPaths.length) return null;
76
- // we support two cases
77
- // 1. /packages-a/src/index.ts
78
- // 2. D:/packages-a/src/index.ts
79
71
  const sep = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep;
80
72
  const splitPaths = absPaths.map((p)=>p.split(sep));
81
73
  let lcaFragments = splitPaths[0];
@@ -130,7 +122,6 @@ function isPluginIncluded(pluginName, plugins) {
130
122
  }
131
123
  function checkMFPlugin(config, sharedPlugins) {
132
124
  if ('mf' !== config.format) return true;
133
- // https://github.com/module-federation/core/blob/4e5c4b96ee45899f3ba5904b8927768980d5ad0e/packages/rsbuild-plugin/src/cli/index.ts#L17
134
125
  const added = isPluginIncluded('rsbuild:module-federation-enhanced', [
135
126
  ...sharedPlugins || [],
136
127
  ...config.plugins || []
@@ -150,11 +141,12 @@ function debounce(func, wait) {
150
141
  }, wait);
151
142
  };
152
143
  }
153
- /**
154
- * Check if running in a TTY context
155
- */ const isTTY = (type = 'stdout')=>('stdin' === type ? process.stdin.isTTY : process.stdout.isTTY) && !process.env.CI;
144
+ const isTTY = (type = 'stdout')=>('stdin' === type ? process.stdin.isTTY : process.stdout.isTTY) && !process.env.CI;
156
145
  const isIntermediateOutputFormat = (format)=>'cjs' === format || 'esm' === format;
157
- // setup the logger level
146
+ const windowsSlashRegex = /\\/g;
147
+ function normalizeSlash(p) {
148
+ return p.replace(windowsSlashRegex, '/');
149
+ }
158
150
  if (process.env.DEBUG) __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.level = 'verbose';
159
151
  function initNodeEnv() {
160
152
  if (!process.env.NODE_ENV) {
@@ -166,12 +158,20 @@ function initNodeEnv() {
166
158
  }
167
159
  function prepareCli() {
168
160
  initNodeEnv();
169
- // Print a blank line to keep the greet log nice.
170
- // Some package managers automatically output a blank line, some do not.
171
161
  const { npm_execpath } = process.env;
172
162
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
173
- __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.greet(` Rslib v0.1.4\n`);
163
+ __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.greet(` Rslib v0.2.0\n`);
174
164
  }
165
+ const composeAssetConfig = (bundle, format)=>{
166
+ if ('esm' === format || 'cjs' === format) {
167
+ return {
168
+ output: {
169
+ dataUriLimit: 0
170
+ }
171
+ };
172
+ }
173
+ return {};
174
+ };
175
175
  const DEFAULT_CONFIG_NAME = 'rslib.config';
176
176
  const DEFAULT_CONFIG_EXTENSIONS = [
177
177
  '.js',
@@ -213,23 +213,64 @@ const ENTRY_EXTENSIONS = [
213
213
  const JS_EXTENSIONS_PATTERN = new RegExp(`\\.(${JS_EXTENSIONS.join('|')})$`);
214
214
  const CSS_EXTENSIONS_PATTERN = new RegExp(`\\.(${CSS_EXTENSIONS.join('|')})$`);
215
215
  const ENTRY_EXTENSIONS_PATTERN = new RegExp(`\\.(${ENTRY_EXTENSIONS.join('|')})$`);
216
- const RemoveCssExtractAssetPlugin_pluginName = 'REMOVE_CSS_EXTRACT_ASSET_PLUGIN';
217
- class RemoveCssExtractAssetPlugin {
218
- name = RemoveCssExtractAssetPlugin_pluginName;
216
+ const BASE_URI = 'webpack://';
217
+ const AUTO_PUBLIC_PATH = '__mini_css_extract_plugin_public_path_auto__';
218
+ const ABSOLUTE_PUBLIC_PATH = `${BASE_URI}/mini-css-extract-plugin/`;
219
+ const SINGLE_DOT_PATH_SEGMENT = '__mini_css_extract_plugin_single_dot_path_segment__';
220
+ function getUndoPath(filename, outputPathArg, enforceRelative) {
221
+ let depth = -1;
222
+ let append = '';
223
+ let outputPath = outputPathArg.replace(/[\\/]$/, '');
224
+ for (const part of filename.split(/[/\\]+/))if ('..' === part) {
225
+ if (depth > -1) depth--;
226
+ else {
227
+ const i = outputPath.lastIndexOf('/');
228
+ const j = outputPath.lastIndexOf('\\');
229
+ const pos = i < 0 ? j : j < 0 ? i : Math.max(i, j);
230
+ if (pos < 0) return `${outputPath}/`;
231
+ append = `${outputPath.slice(pos + 1)}/${append}`;
232
+ outputPath = outputPath.slice(0, pos);
233
+ }
234
+ } else if ('.' !== part) depth++;
235
+ return depth > 0 ? `${'../'.repeat(depth)}${append}` : enforceRelative ? `./${append}` : append;
236
+ }
237
+ const LibCssExtractPlugin_pluginName = 'LIB_CSS_EXTRACT_PLUGIN';
238
+ class LibCssExtractPlugin {
239
+ name = LibCssExtractPlugin_pluginName;
219
240
  options;
220
241
  constructor(options){
221
- this.options = options;
242
+ this.options = options ?? {};
222
243
  }
223
244
  apply(compiler) {
224
- const include = this.options.include;
225
- compiler.hooks.thisCompilation.tap(RemoveCssExtractAssetPlugin_pluginName, (compilation)=>{
226
- compilation.hooks.chunkAsset.tap(RemoveCssExtractAssetPlugin_pluginName, (_chunk, filename)=>{
245
+ compiler.hooks.thisCompilation.tap(LibCssExtractPlugin_pluginName, (compilation)=>{
246
+ compilation.hooks.chunkAsset.tap(LibCssExtractPlugin_pluginName, (_chunk, filename)=>{
227
247
  const asset = compilation.getAsset(filename);
228
248
  if (!asset) return;
229
- const needRemove = Boolean(asset.name.match(include));
249
+ const needRemove = Boolean(asset.name.match(RSLIB_CSS_ENTRY_FLAG));
230
250
  if (needRemove) compilation.deleteAsset(filename);
231
251
  });
232
252
  });
253
+ compiler.hooks.make.tap(LibCssExtractPlugin_pluginName, (compilation)=>{
254
+ compilation.hooks.processAssets.tap(LibCssExtractPlugin_pluginName, (assets)=>{
255
+ const chunkAsset = Object.keys(assets).filter((name)=>/\.css/.test(name));
256
+ for (const name of chunkAsset)compilation.updateAsset(name, (old)=>{
257
+ const oldSource = old.source().toString();
258
+ const replaceSource = new __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.sources.ReplaceSource(old);
259
+ function replace(searchValue, replaceValue) {
260
+ let start = oldSource.indexOf(searchValue);
261
+ while(-1 !== start){
262
+ replaceSource.replace(start, start + searchValue.length - 1, replaceValue);
263
+ start = oldSource.indexOf(searchValue, start + 1);
264
+ }
265
+ }
266
+ replace(ABSOLUTE_PUBLIC_PATH, '');
267
+ replace(SINGLE_DOT_PATH_SEGMENT, '.');
268
+ const undoPath = getUndoPath(name, compilation.outputOptions.path, false);
269
+ replace(AUTO_PUBLIC_PATH, undoPath);
270
+ return replaceSource;
271
+ });
272
+ });
273
+ });
233
274
  }
234
275
  }
235
276
  const cssConfig_require = (0, __WEBPACK_EXTERNAL_MODULE_node_module__.createRequire)(import.meta.url);
@@ -238,10 +279,7 @@ function isCssFile(filepath) {
238
279
  return CSS_EXTENSIONS_PATTERN.test(filepath);
239
280
  }
240
281
  const CSS_MODULE_REG = /\.module\.\w+$/i;
241
- /**
242
- * This function is modified based on
243
- * https://github.com/web-infra-dev/rspack/blob/7b80a45a1c58de7bc506dbb107fad6fda37d2a1f/packages/rspack/src/loader-runner/index.ts#L903
244
- */ const PATH_QUERY_FRAGMENT_REGEXP = /^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
282
+ const PATH_QUERY_FRAGMENT_REGEXP = /^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
245
283
  function parsePathQueryFragment(str) {
246
284
  const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
247
285
  return {
@@ -256,7 +294,6 @@ function isCssModulesFile(filepath, auto) {
256
294
  if (auto instanceof RegExp) return auto.test(filepath);
257
295
  if ('function' == typeof auto) {
258
296
  const { path, query, fragment } = parsePathQueryFragment(filepath);
259
- // this is a mock for loader
260
297
  return auto(path, query, fragment);
261
298
  }
262
299
  return false;
@@ -269,16 +306,11 @@ function isCssGlobalFile(filepath, auto) {
269
306
  }
270
307
  function cssExternalHandler(request, callback, jsExtension, auto, isStyleRedirect) {
271
308
  const isCssModulesRequest = isCssModulesFile(request, auto);
272
- // cssExtract would execute the file handled by css-loader, so we cannot external the "helper import" from css-loader
273
- // do not external @rsbuild/core/compiled/css-loader/noSourceMaps.js, sourceMaps.js, api.mjs etc.
274
309
  if (/compiled\/css-loader\//.test(request)) return callback();
275
- // 1. css modules: import './CounterButton.module.scss' -> import './CounterButton.module.mjs'
276
- // 2. css global: import './CounterButton.scss' -> import './CounterButton.css'
277
310
  if ('.' === request[0] && isCssFile(request)) {
278
- // preserve import './CounterButton.module.scss'
279
- if (!isStyleRedirect) return callback(null, request);
280
- if (isCssModulesRequest) return callback(null, request.replace(/\.[^.]+$/, jsExtension));
281
- return callback(null, request.replace(/\.[^.]+$/, '.css'));
311
+ if (!isStyleRedirect) return callback(void 0, request);
312
+ if (isCssModulesRequest) return callback(void 0, request.replace(/\.[^.]+$/, jsExtension));
313
+ return callback(void 0, request.replace(/\.[^.]+$/, '.css'));
282
314
  }
283
315
  return false;
284
316
  }
@@ -305,11 +337,7 @@ const pluginLibCss = (rootDir)=>({
305
337
  if (isUsingCssExtract) {
306
338
  const cssExtract = CHAIN_ID.PLUGIN.MINI_CSS_EXTRACT;
307
339
  config.plugins.delete(cssExtract);
308
- config.plugin(RemoveCssExtractAssetPlugin.name).use(RemoveCssExtractAssetPlugin, [
309
- {
310
- include: new RegExp(`^${RSLIB_CSS_ENTRY_FLAG}`)
311
- }
312
- ]);
340
+ config.plugin(LibCssExtractPlugin.name).use(LibCssExtractPlugin);
313
341
  }
314
342
  });
315
343
  }
@@ -322,14 +350,11 @@ const composeCssConfig = (rootDir, bundle = true)=>{
322
350
  ],
323
351
  tools: {
324
352
  cssLoader: {
325
- // Otherwise, external variables will be executed by css-extract and cause an error.
326
- // e.g: `@import url('./a.css');`
327
353
  import: false
328
354
  }
329
355
  }
330
356
  };
331
357
  };
332
- // The shim will be injected in PostEntryPlugin.
333
358
  const importMetaUrlShim = `const __rslib_import_meta_url__ = /*#__PURE__*/ (function () {
334
359
  return typeof document === 'undefined'
335
360
  ? new (require('url'.replace('', '')).URL)('file:' + __filename).href
@@ -337,10 +362,6 @@ const importMetaUrlShim = `const __rslib_import_meta_url__ = /*#__PURE__*/ (func
337
362
  new URL('main.js', document.baseURI).href;
338
363
  })();
339
364
  `;
340
- // This Rsbuild plugin will shim `import.meta.url` for CommonJS modules.
341
- // - Replace `import.meta.url` with `importMetaUrl`.
342
- // - Inject `importMetaUrl` to the end of the module (can't inject at the beginning because of `"use strict";`).
343
- // This is a short-term solution, and we hope to provide built-in polyfills like `node.__filename` on Rspack side.
344
365
  const pluginCjsImportMetaUrlShim = ()=>({
345
366
  name: 'rsbuild:cjs-import-meta-url-shim',
346
367
  setup (api) {
@@ -363,7 +384,6 @@ const pluginEsmRequireShim = ()=>({
363
384
  config.plugins ??= [];
364
385
  config.plugins.push(new __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.BannerPlugin({
365
386
  banner: requireShim,
366
- // Just before minify stage, to perform tree shaking.
367
387
  stage: __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE - 1,
368
388
  raw: true,
369
389
  include: /\.(js|cjs)$/
@@ -373,7 +393,7 @@ const pluginEsmRequireShim = ()=>({
373
393
  });
374
394
  const EntryChunkPlugin_require = (0, __WEBPACK_EXTERNAL_MODULE_node_module__.createRequire)(import.meta.url);
375
395
  const EntryChunkPlugin_PLUGIN_NAME = 'rsbuild:lib-entry-chunk';
376
- const LOADER_NAME = 'rsbuild:lib-entry-module';
396
+ const EntryChunkPlugin_LOADER_NAME = 'rsbuild:lib-entry-module';
377
397
  const matchFirstLine = (source, regex)=>{
378
398
  const lineBreakPos = source.match(/(\r\n|\n)/);
379
399
  const firstLineContent = source.slice(0, lineBreakPos?.index);
@@ -406,12 +426,10 @@ class EntryChunkPlugin {
406
426
  const content = compiler.inputFileSystem.readFileSync(filename, {
407
427
  encoding: 'utf-8'
408
428
  });
409
- // Shebang
410
429
  if (content.startsWith(SHEBANG_PREFIX)) {
411
430
  const shebangMatch = matchFirstLine(content, SHEBANG_REGEX);
412
431
  if (shebangMatch) this.shebangEntries[name] = shebangMatch;
413
432
  }
414
- // React directive
415
433
  const reactDirective = matchFirstLine(content, REACT_DIRECTIVE_REGEX);
416
434
  if (reactDirective) this.reactDirectives[name] = reactDirective;
417
435
  }
@@ -442,7 +460,6 @@ class EntryChunkPlugin {
442
460
  });
443
461
  compilation.hooks.processAssets.tap({
444
462
  name: EntryChunkPlugin_PLUGIN_NAME,
445
- // Just after minify stage, to avoid from being minified.
446
463
  stage: __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1
447
464
  }, (assets)=>{
448
465
  const chunkAsset = Object.keys(assets);
@@ -451,12 +468,10 @@ class EntryChunkPlugin {
451
468
  const reactDirectiveValue = this.reactDirectives[name];
452
469
  if (shebangValue || reactDirectiveValue) compilation.updateAsset(name, (old)=>{
453
470
  const replaceSource = new __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.rspack.sources.ReplaceSource(old);
454
- // Shebang
455
471
  if (shebangValue) {
456
472
  replaceSource.insert(0, `${shebangValue}\n`);
457
473
  this.shebangInjectedAssets.add(name);
458
474
  }
459
- // React directives
460
475
  if (reactDirectiveValue) replaceSource.insert(0, `${reactDirectiveValue}\n`);
461
476
  return replaceSource;
462
477
  });
@@ -472,7 +487,7 @@ const entryModuleLoaderRsbuildPlugin = ()=>({
472
487
  name: EntryChunkPlugin_PLUGIN_NAME,
473
488
  setup (api) {
474
489
  api.modifyBundlerChain((config, { CHAIN_ID })=>{
475
- config.module.rule(CHAIN_ID.RULE.JS).use(LOADER_NAME).loader(EntryChunkPlugin_require.resolve('./entryModuleLoader.js'));
490
+ config.module.rule(CHAIN_ID.RULE.JS).use(EntryChunkPlugin_LOADER_NAME).loader(EntryChunkPlugin_require.resolve('./entryModuleLoader.js'));
476
491
  });
477
492
  }
478
493
  });
@@ -545,13 +560,7 @@ const RSPACK_TARGET_UNLISTED_MODERN_ECMA_VERSIONS = [
545
560
  'es2024',
546
561
  'esnext'
547
562
  ];
548
- /**
549
- * The esX to browserslist mapping is transformed from esbuild:
550
- * https://github.com/evanw/esbuild/blob/main/internal/compat/js_table.go
551
- * It does not completely align with the browserslist query of Rsbuild now:
552
- * https://github.com/rspack-contrib/browserslist-to-es-version
553
- * TODO: align with Rsbuild, we may should align with SWC
554
- */ const ESX_TO_BROWSERSLIST = {
563
+ const ESX_TO_BROWSERSLIST = {
555
564
  es5: {
556
565
  chrome: '5.0.0',
557
566
  edge: '12.0.0',
@@ -656,10 +665,7 @@ function transformSyntaxToRspackTarget(syntax) {
656
665
  const normalizedSyntaxItem = syntaxItem.toLowerCase();
657
666
  if (normalizedSyntaxItem.startsWith('es')) {
658
667
  if (normalizedSyntaxItem in ESX_TO_BROWSERSLIST) {
659
- // The latest EcmaScript version supported by Rspack's `target` is es2022.
660
- // Higher versions are treated as es2022.
661
668
  if (RSPACK_TARGET_UNLISTED_MODERN_ECMA_VERSIONS.includes(normalizedSyntaxItem)) return 'es2022';
662
- // The es6 is the same as es2015, compatible with rspack API schema
663
669
  if ('es6' === normalizedSyntaxItem) return 'es2015';
664
670
  return normalizedSyntaxItem;
665
671
  }
@@ -695,7 +701,7 @@ function transformSyntaxToBrowserslist(syntax, target) {
695
701
  }
696
702
  const POSIX_SEP_RE = new RegExp('\\' + __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep, 'g');
697
703
  const NATIVE_SEP_RE = new RegExp('\\' + __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep, 'g');
698
- /** @type {Map<string,RegExp>}*/ const PATTERN_REGEX_CACHE = new Map();
704
+ const PATTERN_REGEX_CACHE = new Map();
699
705
  const GLOB_ALL_PATTERN = "**/*";
700
706
  const TS_EXTENSIONS = [
701
707
  '.ts',
@@ -713,10 +719,7 @@ const TSJS_EXTENSIONS = TS_EXTENSIONS.concat(util_JS_EXTENSIONS);
713
719
  const TS_EXTENSIONS_RE_GROUP = `\\.(?:${TS_EXTENSIONS.map((ext)=>ext.substring(1)).join('|')})`;
714
720
  const TSJS_EXTENSIONS_RE_GROUP = `\\.(?:${TSJS_EXTENSIONS.map((ext)=>ext.substring(1)).join('|')})`;
715
721
  const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep === __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep;
716
- /**
717
- * @template T
718
- * @returns {{resolve:(result:T)=>void, reject:(error:any)=>void, promise: Promise<T>}}
719
- */ function util_makePromise() {
722
+ function util_makePromise() {
720
723
  let resolve, reject;
721
724
  const promise = new Promise((res, rej)=>{
722
725
  resolve = res;
@@ -728,12 +731,8 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
728
731
  reject
729
732
  };
730
733
  }
731
- /**
732
- * @param {string} filename
733
- * @param {import('./cache.js').TSConfckCache} [cache]
734
- * @returns {Promise<string|void>}
735
- */ async function util_resolveTSConfigJson(filename, cache) {
736
- if ('.json' !== __WEBPACK_EXTERNAL_MODULE_node_path__["default"].extname(filename)) return; // ignore files that are not json
734
+ async function util_resolveTSConfigJson(filename, cache) {
735
+ if ('.json' !== __WEBPACK_EXTERNAL_MODULE_node_path__["default"].extname(filename)) return;
737
736
  const tsconfig = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(filename);
738
737
  if (cache && (cache.hasParseResult(tsconfig) || cache.hasParseResult(filename))) return tsconfig;
739
738
  return __WEBPACK_EXTERNAL_MODULE_node_fs__.promises.stat(tsconfig).then((stat)=>{
@@ -741,57 +740,18 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
741
740
  throw new Error(`${filename} exists but is not a regular file.`);
742
741
  });
743
742
  }
744
- /**
745
- *
746
- * @param {string} dir an absolute directory path
747
- * @returns {boolean} if dir path includes a node_modules segment
748
- */ const util_isInNodeModules = IS_POSIX ? (dir)=>dir.includes('/node_modules/') : (dir)=>dir.match(/[/\\]node_modules[/\\]/);
749
- /**
750
- * convert posix separator to native separator
751
- *
752
- * eg.
753
- * windows: C:/foo/bar -> c:\foo\bar
754
- * linux: /foo/bar -> /foo/bar
755
- *
756
- * @param {string} filename with posix separators
757
- * @returns {string} filename with native separators
758
- */ const posix2native = IS_POSIX ? (filename)=>filename : (filename)=>filename.replace(POSIX_SEP_RE, __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep);
759
- /**
760
- * convert native separator to posix separator
761
- *
762
- * eg.
763
- * windows: C:\foo\bar -> c:/foo/bar
764
- * linux: /foo/bar -> /foo/bar
765
- *
766
- * @param {string} filename - filename with native separators
767
- * @returns {string} filename with posix separators
768
- */ const util_native2posix = IS_POSIX ? (filename)=>filename : (filename)=>filename.replace(NATIVE_SEP_RE, __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep);
769
- /**
770
- * converts params to native separator, resolves path and converts native back to posix
771
- *
772
- * needed on windows to handle posix paths in tsconfig
773
- *
774
- * @param dir {string|null} directory to resolve from
775
- * @param filename {string} filename or pattern to resolve
776
- * @returns string
777
- */ const resolve2posix = IS_POSIX ? (dir, filename)=>dir ? __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(dir, filename) : __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(filename) : (dir, filename)=>util_native2posix(dir ? __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(posix2native(dir), posix2native(filename)) : __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(posix2native(filename)));
778
- /**
779
- *
780
- * @param {import('./public.d.ts').TSConfckParseResult} result
781
- * @param {import('./public.d.ts').TSConfckParseOptions} [options]
782
- * @returns {string[]}
783
- */ function util_resolveReferencedTSConfigFiles(result, options) {
743
+ const util_isInNodeModules = IS_POSIX ? (dir)=>dir.includes('/node_modules/') : (dir)=>dir.match(/[/\\]node_modules[/\\]/);
744
+ const posix2native = IS_POSIX ? (filename)=>filename : (filename)=>filename.replace(POSIX_SEP_RE, __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep);
745
+ const util_native2posix = IS_POSIX ? (filename)=>filename : (filename)=>filename.replace(NATIVE_SEP_RE, __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep);
746
+ const resolve2posix = IS_POSIX ? (dir, filename)=>dir ? __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(dir, filename) : __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(filename) : (dir, filename)=>util_native2posix(dir ? __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(posix2native(dir), posix2native(filename)) : __WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(posix2native(filename)));
747
+ function util_resolveReferencedTSConfigFiles(result, options) {
784
748
  const dir = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(result.tsconfigFile);
785
749
  return result.tsconfig.references.map((ref)=>{
786
750
  const refPath = ref.path.endsWith('.json') ? ref.path : __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(ref.path, options?.configName ?? 'tsconfig.json');
787
751
  return resolve2posix(dir, refPath);
788
752
  });
789
753
  }
790
- /**
791
- * @param {string} filename
792
- * @param {import('./public.d.ts').TSConfckParseResult} result
793
- * @returns {import('./public.d.ts').TSConfckParseResult}
794
- */ function util_resolveSolutionTSConfig(filename, result) {
754
+ function util_resolveSolutionTSConfig(filename, result) {
795
755
  const allowJs = result.tsconfig.compilerOptions?.allowJs;
796
756
  const extensions = allowJs ? TSJS_EXTENSIONS : TS_EXTENSIONS;
797
757
  if (result.referenced && extensions.some((ext)=>filename.endsWith(ext)) && !util_isIncluded(filename, result)) {
@@ -800,12 +760,7 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
800
760
  }
801
761
  return result;
802
762
  }
803
- /**
804
- *
805
- * @param {string} filename
806
- * @param {import('./public.d.ts').TSConfckParseResult} result
807
- * @returns {boolean}
808
- */ function util_isIncluded(filename, result) {
763
+ function util_isIncluded(filename, result) {
809
764
  const dir = util_native2posix(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(result.tsconfigFile));
810
765
  const files = (result.tsconfig.files || []).map((file)=>resolve2posix(dir, file));
811
766
  const absoluteFilename = resolve2posix(null, filename);
@@ -820,18 +775,9 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
820
775
  }
821
776
  return false;
822
777
  }
823
- /**
824
- * test filenames agains glob patterns in tsconfig
825
- *
826
- * @param filename {string} posix style abolute path to filename to test
827
- * @param dir {string} posix style absolute path to directory of tsconfig containing patterns
828
- * @param patterns {string[]} glob patterns to match against
829
- * @param allowJs {boolean} allowJs setting in tsconfig to include js extensions in checks
830
- * @returns {boolean} true when at least one pattern matches filename
831
- */ function isGlobMatch(filename, dir, patterns, allowJs) {
778
+ function isGlobMatch(filename, dir, patterns, allowJs) {
832
779
  const extensions = allowJs ? TSJS_EXTENSIONS : TS_EXTENSIONS;
833
780
  return patterns.some((pattern)=>{
834
- // filename must end with part of pattern that comes after last wildcard
835
781
  let lastWildcardIndex = pattern.length;
836
782
  let hasWildcard = false;
837
783
  let hasExtension = false;
@@ -855,19 +801,14 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
855
801
  if (hasWildcard && hasSlash) break;
856
802
  }
857
803
  if (!hasExtension && (!hasWildcard || lastWildcardIndex < lastSlashIndex)) {
858
- // add implicit glob
859
804
  pattern += `${pattern.endsWith('/') ? '' : '/'}${GLOB_ALL_PATTERN}`;
860
805
  lastWildcardIndex = pattern.length - 1;
861
806
  hasWildcard = true;
862
807
  }
863
- // if pattern does not end with wildcard, filename must end with pattern after last wildcard
864
808
  if (lastWildcardIndex < pattern.length - 1 && !filename.endsWith(pattern.slice(lastWildcardIndex + 1))) return false;
865
- // if pattern ends with *, filename must end with a default extension
866
809
  if (pattern.endsWith('*') && !extensions.some((ext)=>filename.endsWith(ext))) return false;
867
- // for **/* , filename must start with the dir
868
810
  if (pattern === GLOB_ALL_PATTERN) return filename.startsWith(`${dir}/`);
869
811
  const resolvedPattern = resolve2posix(dir, pattern);
870
- // filename must start with part of pattern that comes before first wildcard
871
812
  let firstWildcardIndex = -1;
872
813
  for(let i = 0; i < resolvedPattern.length; i++)if ('*' === resolvedPattern[i] || '?' === resolvedPattern[i]) {
873
814
  firstWildcardIndex = i;
@@ -875,22 +816,15 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
875
816
  break;
876
817
  }
877
818
  if (firstWildcardIndex > 1 && !filename.startsWith(resolvedPattern.slice(0, firstWildcardIndex - 1))) return false;
878
- if (!hasWildcard) // no wildcard in pattern, filename must be equal to resolved pattern
879
- return filename === resolvedPattern;
880
- if (firstWildcardIndex + GLOB_ALL_PATTERN.length === resolvedPattern.length - (pattern.length - 1 - lastWildcardIndex) && resolvedPattern.slice(firstWildcardIndex, firstWildcardIndex + GLOB_ALL_PATTERN.length) === GLOB_ALL_PATTERN) // singular glob-all pattern and we already validated prefix and suffix matches
881
- return true;
882
- // complex pattern, use regex to check it
819
+ if (!hasWildcard) return filename === resolvedPattern;
820
+ if (firstWildcardIndex + GLOB_ALL_PATTERN.length === resolvedPattern.length - (pattern.length - 1 - lastWildcardIndex) && resolvedPattern.slice(firstWildcardIndex, firstWildcardIndex + GLOB_ALL_PATTERN.length) === GLOB_ALL_PATTERN) return true;
883
821
  if (PATTERN_REGEX_CACHE.has(resolvedPattern)) return PATTERN_REGEX_CACHE.get(resolvedPattern).test(filename);
884
822
  const regex = pattern2regex(resolvedPattern, allowJs);
885
823
  PATTERN_REGEX_CACHE.set(resolvedPattern, regex);
886
824
  return regex.test(filename);
887
825
  });
888
826
  }
889
- /**
890
- * @param {string} resolvedPattern
891
- * @param {boolean} allowJs
892
- * @returns {RegExp}
893
- */ function pattern2regex(resolvedPattern, allowJs) {
827
+ function pattern2regex(resolvedPattern, allowJs) {
894
828
  let regexStr = '^';
895
829
  for(let i = 0; i < resolvedPattern.length; i++){
896
830
  const char = resolvedPattern[i];
@@ -901,7 +835,7 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
901
835
  if ('*' === char) {
902
836
  if ('*' === resolvedPattern[i + 1] && '/' === resolvedPattern[i + 2]) {
903
837
  i += 2;
904
- regexStr += '(?:[^\\/]*\\/)*'; // zero or more path segments
838
+ regexStr += '(?:[^\\/]*\\/)*';
905
839
  continue;
906
840
  }
907
841
  regexStr += '[^\\/]*';
@@ -910,27 +844,14 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
910
844
  if ('/.+^${}()|[]\\'.includes(char)) regexStr += "\\";
911
845
  regexStr += char;
912
846
  }
913
- // add known file endings if pattern ends on *
914
847
  if (resolvedPattern.endsWith('*')) regexStr += allowJs ? TSJS_EXTENSIONS_RE_GROUP : TS_EXTENSIONS_RE_GROUP;
915
848
  regexStr += '$';
916
849
  return new RegExp(regexStr);
917
850
  }
918
- /**
919
- * replace tokens like ${configDir}
920
- * @param {any} tsconfig
921
- * @param {string} configDir
922
- * @returns {any}
923
- */ function util_replaceTokens(tsconfig, configDir) {
924
- return JSON.parse(JSON.stringify(tsconfig)// replace ${configDir}
925
- .replaceAll(/"\${configDir}/g, `"${util_native2posix(configDir)}`));
926
- }
927
- /**
928
- * find the closest tsconfig.json file
929
- *
930
- * @param {string} filename - path to file to find tsconfig for (absolute or relative to cwd)
931
- * @param {import('./public.d.ts').TSConfckFindOptions} [options] - options
932
- * @returns {Promise<string|null>} absolute path to closest tsconfig.json or null if not found
933
- */ async function find(filename, options) {
851
+ function util_replaceTokens(tsconfig, configDir) {
852
+ return JSON.parse(JSON.stringify(tsconfig).replaceAll(/"\${configDir}/g, `"${util_native2posix(configDir)}`));
853
+ }
854
+ async function find(filename, options) {
934
855
  let dir = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].resolve(filename));
935
856
  if (options?.ignoreNodeModules && util_isInNodeModules(dir)) return null;
936
857
  const cache = options?.cache;
@@ -945,12 +866,7 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
945
866
  }, options);
946
867
  return promise;
947
868
  }
948
- /**
949
- *
950
- * @param {string} dir
951
- * @param {{promise:Promise<string|null>,resolve:(result:string|null)=>void,reject:(err:any)=>void}} madePromise
952
- * @param {import('./public.d.ts').TSConfckFindOptions} [options] - options
953
- */ function findUp(dir, { resolve, reject, promise }, options) {
869
+ function findUp(dir, { resolve, reject, promise }, options) {
954
870
  const { cache, root, configName } = options ?? {};
955
871
  if (cache) {
956
872
  if (cache.hasConfigPath(dir, configName)) {
@@ -980,38 +896,13 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
980
896
  }
981
897
  });
982
898
  }
983
- /**
984
- * @typedef WalkState
985
- * @interface
986
- * @property {string[]} files - files
987
- * @property {number} calls - number of ongoing calls
988
- * @property {(dir: string)=>boolean} skip - function to skip dirs
989
- * @property {boolean} err - error flag
990
- * @property {string[]} configNames - config file names
991
- */ __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep;
992
- /*
993
- this file contains code from strip-bom and strip-json-comments by Sindre Sorhus
994
- https://github.com/sindresorhus/strip-json-comments/blob/v4.0.0/index.js
995
- https://github.com/sindresorhus/strip-bom/blob/v5.0.0/index.js
996
- licensed under MIT, see ../LICENSE
997
- */ /**
998
- * convert content of tsconfig.json to regular json
999
- *
1000
- * @param {string} tsconfigJson - content of tsconfig.json
1001
- * @returns {string} content as regular json, comments and dangling commas have been replaced with whitespace
1002
- */ function toJson(tsconfigJson) {
899
+ __WEBPACK_EXTERNAL_MODULE_node_path__["default"].sep;
900
+ function toJson(tsconfigJson) {
1003
901
  const stripped = stripDanglingComma(stripJsonComments(stripBom(tsconfigJson)));
1004
- if ('' === stripped.trim()) // only whitespace left after stripping, return empty object so that JSON.parse still works
1005
- return '{}';
902
+ if ('' === stripped.trim()) return '{}';
1006
903
  return stripped;
1007
904
  }
1008
- /**
1009
- * replace dangling commas from pseudo-json string with single space
1010
- * implementation heavily inspired by strip-json-comments
1011
- *
1012
- * @param {string} pseudoJson
1013
- * @returns {string}
1014
- */ function stripDanglingComma(pseudoJson) {
905
+ function stripDanglingComma(pseudoJson) {
1015
906
  let insideString = false;
1016
907
  let offset = 0;
1017
908
  let result = '';
@@ -1040,13 +931,7 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
1040
931
  }
1041
932
  return result + pseudoJson.substring(offset);
1042
933
  }
1043
- // start strip-json-comments
1044
- /**
1045
- *
1046
- * @param {string} jsonString
1047
- * @param {number} quotePosition
1048
- * @returns {boolean}
1049
- */ function isEscaped(jsonString, quotePosition) {
934
+ function isEscaped(jsonString, quotePosition) {
1050
935
  let index = quotePosition - 1;
1051
936
  let backslashCount = 0;
1052
937
  while('\\' === jsonString[index]){
@@ -1055,22 +940,14 @@ const IS_POSIX = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.sep ===
1055
940
  }
1056
941
  return Boolean(backslashCount % 2);
1057
942
  }
1058
- /**
1059
- *
1060
- * @param {string} string
1061
- * @param {number?} start
1062
- * @param {number?} end
1063
- */ function strip(string, start, end) {
943
+ function strip(string, start, end) {
1064
944
  return string.slice(start, end).replace(/\S/g, ' ');
1065
945
  }
1066
946
  const singleComment = Symbol('singleComment');
1067
947
  const multiComment = Symbol('multiComment');
1068
- /**
1069
- * @param {string} jsonString
1070
- * @returns {string}
1071
- */ function stripJsonComments(jsonString) {
948
+ function stripJsonComments(jsonString) {
1072
949
  let isInsideString = false;
1073
- /** @type {false | symbol} */ let isInsideComment = false;
950
+ let isInsideComment = false;
1074
951
  let offset = 0;
1075
952
  let result = '';
1076
953
  for(let index = 0; index < jsonString.length; index++){
@@ -1112,14 +989,7 @@ const multiComment = Symbol('multiComment');
1112
989
  }
1113
990
  return result + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
1114
991
  }
1115
- // end strip-json-comments
1116
- // start strip-bom
1117
- /**
1118
- * @param {string} string
1119
- * @returns {string}
1120
- */ function stripBom(string) {
1121
- // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string
1122
- // conversion translates it to FEFF (UTF-16 BOM).
992
+ function stripBom(string) {
1123
993
  if (0xfeff === string.charCodeAt(0)) return string.slice(1);
1124
994
  return string;
1125
995
  }
@@ -1127,17 +997,10 @@ const not_found_result = {
1127
997
  tsconfigFile: null,
1128
998
  tsconfig: {}
1129
999
  };
1130
- /**
1131
- * parse the closest tsconfig.json file
1132
- *
1133
- * @param {string} filename - path to a tsconfig .json or a source file or directory (absolute or relative to cwd)
1134
- * @param {import('./public.d.ts').TSConfckParseOptions} [options] - options
1135
- * @returns {Promise<import('./public.d.ts').TSConfckParseResult>}
1136
- * @throws {TSConfckParseError}
1137
- */ async function parse(filename, options) {
1138
- /** @type {import('./cache.js').TSConfckCache} */ const cache = options?.cache;
1000
+ async function parse(filename, options) {
1001
+ const cache = options?.cache;
1139
1002
  if (cache?.hasParseResult(filename)) return getParsedDeep(filename, cache, options);
1140
- const { resolve, reject, /** @type {Promise<import('./public.d.ts').TSConfckParseResult>}*/ promise } = util_makePromise();
1003
+ const { resolve, reject, promise } = util_makePromise();
1141
1004
  cache?.setParseResult(filename, promise, true);
1142
1005
  try {
1143
1006
  let tsconfigFile = await util_resolveTSConfigJson(filename, cache) || await find(filename, options);
@@ -1161,13 +1024,7 @@ const not_found_result = {
1161
1024
  }
1162
1025
  return promise;
1163
1026
  }
1164
- /**
1165
- * ensure extends and references are parsed
1166
- *
1167
- * @param {string} filename - cached file
1168
- * @param {import('./cache.js').TSConfckCache} cache - cache
1169
- * @param {import('./public.d.ts').TSConfckParseOptions} options - options
1170
- */ async function getParsedDeep(filename, cache, options) {
1027
+ async function getParsedDeep(filename, cache, options) {
1171
1028
  const result = await cache.getParseResult(filename);
1172
1029
  if (result.tsconfig.extends && !result.extended || result.tsconfig.references && !result.referenced) {
1173
1030
  const promise = Promise.all([
@@ -1179,13 +1036,7 @@ const not_found_result = {
1179
1036
  }
1180
1037
  return result;
1181
1038
  }
1182
- /**
1183
- *
1184
- * @param {string} tsconfigFile - path to tsconfig file
1185
- * @param {import('./cache.js').TSConfckCache} [cache] - cache
1186
- * @param {boolean} [skipCache] - skip cache
1187
- * @returns {Promise<import('./public.d.ts').TSConfckParseResult>}
1188
- */ async function parseFile(tsconfigFile, cache, skipCache) {
1039
+ async function parseFile(tsconfigFile, cache, skipCache) {
1189
1040
  if (!skipCache && cache?.hasParseResult(tsconfigFile) && !cache.getParseResult(tsconfigFile)._isRootFile_) return cache.getParseResult(tsconfigFile);
1190
1041
  const promise = __WEBPACK_EXTERNAL_MODULE_node_fs__.promises.readFile(tsconfigFile, 'utf-8').then(toJson).then((json)=>{
1191
1042
  const parsed = JSON.parse(json);
@@ -1200,23 +1051,12 @@ const not_found_result = {
1200
1051
  if (!skipCache && (!cache?.hasParseResult(tsconfigFile) || !cache.getParseResult(tsconfigFile)._isRootFile_)) cache?.setParseResult(tsconfigFile, promise);
1201
1052
  return promise;
1202
1053
  }
1203
- /**
1204
- * normalize to match the output of ts.parseJsonConfigFileContent
1205
- *
1206
- * @param {any} tsconfig - typescript tsconfig output
1207
- * @param {string} dir - directory
1208
- */ function normalizeTSConfig(tsconfig, dir) {
1209
- // set baseUrl to absolute path
1054
+ function normalizeTSConfig(tsconfig, dir) {
1210
1055
  const baseUrl = tsconfig.compilerOptions?.baseUrl;
1211
1056
  if (baseUrl && !baseUrl.startsWith('${') && !__WEBPACK_EXTERNAL_MODULE_node_path__["default"].isAbsolute(baseUrl)) tsconfig.compilerOptions.baseUrl = resolve2posix(dir, baseUrl);
1212
1057
  return tsconfig;
1213
1058
  }
1214
- /**
1215
- *
1216
- * @param {import('./public.d.ts').TSConfckParseResult} result
1217
- * @param {import('./public.d.ts').TSConfckParseOptions} [options]
1218
- * @returns {Promise<void>}
1219
- */ async function parseReferences(result, options) {
1059
+ async function parseReferences(result, options) {
1220
1060
  if (!result.tsconfig.references) return;
1221
1061
  const referencedFiles = util_resolveReferencedTSConfigFiles(result, options);
1222
1062
  const referenced = await Promise.all(referencedFiles.map((file)=>parseFile(file, options?.cache)));
@@ -1226,32 +1066,23 @@ const not_found_result = {
1226
1066
  });
1227
1067
  result.referenced = referenced;
1228
1068
  }
1229
- /**
1230
- * @param {import('./public.d.ts').TSConfckParseResult} result
1231
- * @param {import('./cache.js').TSConfckCache}[cache]
1232
- * @returns {Promise<void>}
1233
- */ async function parseExtends(result, cache) {
1069
+ async function parseExtends(result, cache) {
1234
1070
  if (!result.tsconfig.extends) return;
1235
- // use result as first element in extended
1236
- // but dereference tsconfig so that mergeExtended can modify the original without affecting extended[0]
1237
- /** @type {import('./public.d.ts').TSConfckParseResult[]} */ const extended = [
1071
+ const extended = [
1238
1072
  {
1239
1073
  tsconfigFile: result.tsconfigFile,
1240
1074
  tsconfig: JSON.parse(JSON.stringify(result.tsconfig))
1241
1075
  }
1242
1076
  ];
1243
- // flatten extends graph into extended
1244
1077
  let pos = 0;
1245
- /** @type {string[]} */ const extendsPath = [];
1078
+ const extendsPath = [];
1246
1079
  let currentBranchDepth = 0;
1247
1080
  while(pos < extended.length){
1248
1081
  const extending = extended[pos];
1249
1082
  extendsPath.push(extending.tsconfigFile);
1250
1083
  if (extending.tsconfig.extends) {
1251
- // keep following this branch
1252
1084
  currentBranchDepth += 1;
1253
- /** @type {string[]} */ let resolvedExtends;
1254
- // reverse because typescript 5.0 treats ['a','b','c'] as c extends b extends a
1085
+ let resolvedExtends;
1255
1086
  resolvedExtends = Array.isArray(extending.tsconfig.extends) ? extending.tsconfig.extends.reverse().map((ex)=>resolveExtends(ex, extending.tsconfigFile)) : [
1256
1087
  resolveExtends(extending.tsconfig.extends, extending.tsconfigFile)
1257
1088
  ];
@@ -1262,27 +1093,18 @@ const not_found_result = {
1262
1093
  ]).join(' -> ');
1263
1094
  throw new TSConfckParseError(`Circular dependency in "extends": ${circle}`, 'EXTENDS_CIRCULAR', result.tsconfigFile);
1264
1095
  }
1265
- // add new extends to the list directly after current
1266
1096
  extended.splice(pos + 1, 0, ...await Promise.all(resolvedExtends.map((file)=>parseFile(file, cache))));
1267
1097
  } else {
1268
- // reached a leaf, backtrack to the last branching point and continue
1269
1098
  extendsPath.splice(-currentBranchDepth);
1270
1099
  currentBranchDepth = 0;
1271
1100
  }
1272
1101
  pos += 1;
1273
1102
  }
1274
1103
  result.extended = extended;
1275
- // skip first as it is the original config
1276
1104
  for (const ext of result.extended.slice(1))extendTSConfig(result, ext);
1277
1105
  }
1278
- /**
1279
- *
1280
- * @param {string} extended
1281
- * @param {string} from
1282
- * @returns {string}
1283
- */ function resolveExtends(extended, from) {
1284
- if ('..' === extended) // see #149
1285
- extended = '../tsconfig.json';
1106
+ function resolveExtends(extended, from) {
1107
+ if ('..' === extended) extended = '../tsconfig.json';
1286
1108
  const req = (0, __WEBPACK_EXTERNAL_MODULE_module__.createRequire)(from);
1287
1109
  let error;
1288
1110
  try {
@@ -1297,7 +1119,6 @@ const not_found_result = {
1297
1119
  }
1298
1120
  throw new TSConfckParseError(`failed to resolve "extends":"${extended}" in ${from}`, 'EXTENDS_RESOLVE', from, error);
1299
1121
  }
1300
- // references, extends and custom keys are not carried over
1301
1122
  const EXTENDABLE_KEYS = [
1302
1123
  'compilerOptions',
1303
1124
  'files',
@@ -1308,12 +1129,7 @@ const EXTENDABLE_KEYS = [
1308
1129
  'typeAcquisition',
1309
1130
  'buildOptions'
1310
1131
  ];
1311
- /**
1312
- *
1313
- * @param {import('./public.d.ts').TSConfckParseResult} extending
1314
- * @param {import('./public.d.ts').TSConfckParseResult} extended
1315
- * @returns void
1316
- */ function extendTSConfig(extending, extended) {
1132
+ function extendTSConfig(extending, extended) {
1317
1133
  const extendingConfig = extending.tsconfig;
1318
1134
  const extendedConfig = extended.tsconfig;
1319
1135
  const relativePath = util_native2posix(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].relative(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(extending.tsconfigFile), __WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(extended.tsconfigFile)));
@@ -1330,11 +1146,9 @@ const EXTENDABLE_KEYS = [
1330
1146
  }
1331
1147
  }
1332
1148
  const REBASE_KEYS = [
1333
- // root
1334
1149
  'files',
1335
1150
  'include',
1336
1151
  'exclude',
1337
- // compilerOptions
1338
1152
  'baseUrl',
1339
1153
  'rootDir',
1340
1154
  'rootDirs',
@@ -1342,53 +1156,24 @@ const REBASE_KEYS = [
1342
1156
  'outDir',
1343
1157
  'outFile',
1344
1158
  'declarationDir',
1345
- // watchOptions
1346
1159
  'excludeDirectories',
1347
1160
  'excludeFiles'
1348
1161
  ];
1349
- /** @typedef {string | string[]} PathValue */ /**
1350
- *
1351
- * @param {string} key
1352
- * @param {PathValue} value
1353
- * @param {string} prependPath
1354
- * @returns {PathValue}
1355
- */ function rebaseRelative(key, value, prependPath) {
1162
+ function rebaseRelative(key, value, prependPath) {
1356
1163
  if (!REBASE_KEYS.includes(key)) return value;
1357
1164
  if (Array.isArray(value)) return value.map((x)=>rebasePath(x, prependPath));
1358
1165
  return rebasePath(value, prependPath);
1359
1166
  }
1360
- /**
1361
- *
1362
- * @param {string} value
1363
- * @param {string} prependPath
1364
- * @returns {string}
1365
- */ function rebasePath(value, prependPath) {
1167
+ function rebasePath(value, prependPath) {
1366
1168
  if (__WEBPACK_EXTERNAL_MODULE_node_path__["default"].isAbsolute(value) || value.startsWith('${configDir}')) return value;
1367
- // relative paths use posix syntax in tsconfig
1368
1169
  return __WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.normalize(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].posix.join(prependPath, value));
1369
1170
  }
1370
1171
  class TSConfckParseError extends Error {
1371
- /**
1372
- * error code
1373
- * @type {string}
1374
- */ code;
1375
- /**
1376
- * error cause
1377
- * @type { Error | undefined}
1378
- */ cause;
1379
- /**
1380
- * absolute path of tsconfig file where the error happened
1381
- * @type {string}
1382
- */ tsconfigFile;
1383
- /**
1384
- *
1385
- * @param {string} message - error message
1386
- * @param {string} code - error code
1387
- * @param {string} tsconfigFile - path to tsconfig file
1388
- * @param {Error?} cause - cause of this error
1389
- */ constructor(message, code, tsconfigFile, cause){
1172
+ code;
1173
+ cause;
1174
+ tsconfigFile;
1175
+ constructor(message, code, tsconfigFile, cause){
1390
1176
  super(message);
1391
- // Set the prototype explicitly.
1392
1177
  Object.setPrototypeOf(this, TSConfckParseError.prototype);
1393
1178
  this.name = TSConfckParseError.name;
1394
1179
  this.code = code;
@@ -1396,11 +1181,7 @@ class TSConfckParseError extends Error {
1396
1181
  this.tsconfigFile = tsconfigFile;
1397
1182
  }
1398
1183
  }
1399
- /**
1400
- *
1401
- * @param {any} tsconfig
1402
- * @param {string} tsconfigFile
1403
- */ function applyDefaults(tsconfig, tsconfigFile) {
1184
+ function applyDefaults(tsconfig, tsconfigFile) {
1404
1185
  if (isJSConfig(tsconfigFile)) tsconfig.compilerOptions = {
1405
1186
  ...DEFAULT_JSCONFIG_COMPILER_OPTIONS,
1406
1187
  ...tsconfig.compilerOptions
@@ -1413,9 +1194,7 @@ const DEFAULT_JSCONFIG_COMPILER_OPTIONS = {
1413
1194
  skipLibCheck: true,
1414
1195
  noEmit: true
1415
1196
  };
1416
- /**
1417
- * @param {string} configFileName
1418
- */ function isJSConfig(configFileName) {
1197
+ function isJSConfig(configFileName) {
1419
1198
  return 'jsconfig.json' === __WEBPACK_EXTERNAL_MODULE_node_path__["default"].basename(configFileName);
1420
1199
  }
1421
1200
  async function loadTsconfig(root, tsconfigPath = 'tsconfig.json') {
@@ -1459,9 +1238,7 @@ const composeExternalsWarnConfig = (format, ...externalsArray)=>{
1459
1238
  if ('esm' !== format) return {};
1460
1239
  const externals = [];
1461
1240
  for (const e of externalsArray.filter(Boolean))if (Array.isArray(e)) externals.push(...e);
1462
- else // @ts-ignore
1463
- externals.push(e);
1464
- // Match logic is derived from https://github.com/webpack/webpack/blob/94aba382eccf3de1004d235045d4462918dfdbb7/lib/ExternalModuleFactoryPlugin.js#L166-L293.
1241
+ else externals.push(e);
1465
1242
  const matchUserExternals = (externals, request, callback)=>{
1466
1243
  if ('string' == typeof externals) {
1467
1244
  if (externals === request) {
@@ -1532,9 +1309,6 @@ const composeAutoExternalConfig = (options)=>{
1532
1309
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.warn('autoExternal configuration will not be applied due to read package.json failed');
1533
1310
  return {};
1534
1311
  }
1535
- // User externals configuration has higher priority than autoExternal
1536
- // eg: autoExternal: ['react'], user: output: { externals: { react: 'react-1' } }
1537
- // Only handle the case where the externals type is object, string / string[] does not need to be processed, other types are too complex.
1538
1312
  const userExternalKeys = userExternals && isObject(userExternals) ? Object.keys(userExternals) : [];
1539
1313
  const externalOptions = {
1540
1314
  dependencies: true,
@@ -1556,7 +1330,6 @@ const composeAutoExternalConfig = (options)=>{
1556
1330
  return externals.length ? {
1557
1331
  output: {
1558
1332
  externals: [
1559
- // Exclude dependencies, e.g. `react`, `react/jsx-runtime`
1560
1333
  ...uniqueExternals.map((dep)=>new RegExp(`^${dep}($|\\/|\\\\)`)),
1561
1334
  ...uniqueExternals
1562
1335
  ]
@@ -1566,10 +1339,7 @@ const composeAutoExternalConfig = (options)=>{
1566
1339
  function composeMinifyConfig(config) {
1567
1340
  const minify = config.output?.minify;
1568
1341
  const format = config.format;
1569
- if (void 0 !== minify) // User's minify configuration will be merged afterwards.
1570
- return {};
1571
- // When minify is not specified, Rslib will use a sane default for minify options.
1572
- // The default options will only perform dead code elimination and unused code elimination.
1342
+ if (void 0 !== minify) return {};
1573
1343
  return {
1574
1344
  output: {
1575
1345
  minify: {
@@ -1578,13 +1348,11 @@ function composeMinifyConfig(config) {
1578
1348
  jsOptions: {
1579
1349
  minimizerOptions: {
1580
1350
  mangle: false,
1581
- // MF assets are loaded over the network, which means they will not be compressed by the project. Therefore, minifying them is necessary.
1582
1351
  minify: 'mf' === format,
1583
1352
  compress: {
1584
1353
  defaults: false,
1585
1354
  unused: true,
1586
1355
  dead_code: true,
1587
- // remoteEntry's global variable will be tree-shaken if `toplevel` is enabled in "mf" format
1588
1356
  toplevel: 'mf' !== format
1589
1357
  },
1590
1358
  format: {
@@ -1658,7 +1426,6 @@ function composeDecoratorsConfig(compilerOptions, version) {
1658
1426
  }
1659
1427
  async function createConstantRsbuildConfig() {
1660
1428
  return (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.defineConfig)({
1661
- mode: 'production',
1662
1429
  dev: {
1663
1430
  progressBar: false
1664
1431
  },
@@ -1672,7 +1439,6 @@ async function createConstantRsbuildConfig() {
1672
1439
  rspack: {
1673
1440
  optimization: {
1674
1441
  splitChunks: {
1675
- // Splitted "sync" chunks will make entry modules can't be inlined.
1676
1442
  chunks: 'async'
1677
1443
  },
1678
1444
  moduleIds: 'named',
@@ -1685,8 +1451,6 @@ async function createConstantRsbuildConfig() {
1685
1451
  }
1686
1452
  }
1687
1453
  },
1688
- // TypeScript-specific behavior: if the extension is ".js" or ".jsx", try replacing it with ".ts" or ".tsx"
1689
- // see https://github.com/web-infra-dev/rslib/issues/41
1690
1454
  resolve: {
1691
1455
  extensionAlias: {
1692
1456
  '.js': [
@@ -1830,8 +1594,6 @@ const composeFormatConfig = ({ format, bundle = true, umdName, pkgJson })=>{
1830
1594
  output: {
1831
1595
  uniqueName: pkgJson.name
1832
1596
  },
1833
- // can not set nodeEnv to false, because mf format should build shared module.
1834
- // If nodeEnv is false, the process.env.NODE_ENV in third-party packages's will not be replaced
1835
1597
  optimization: {
1836
1598
  nodeEnv: 'production',
1837
1599
  moduleIds: 'deterministic'
@@ -1850,8 +1612,6 @@ const formatRsbuildPlugin = ()=>({
1850
1612
  name: 'rsbuild:format',
1851
1613
  setup (api) {
1852
1614
  api.modifyBundlerChain((config, { CHAIN_ID })=>{
1853
- // Fix for https://github.com/web-infra-dev/rslib/issues/499.
1854
- // Prevent parsing and try bundling `new URL()` in ESM format.
1855
1615
  config.module.rule(CHAIN_ID.RULE.JS).parser({
1856
1616
  url: false
1857
1617
  });
@@ -1886,7 +1646,6 @@ const composeShimsConfig = (format, shims)=>{
1886
1646
  tools: {
1887
1647
  rspack: {
1888
1648
  node: {
1889
- // "__dirname" and "__filename" shims will automatically be enabled when `output.module` is `true`
1890
1649
  __dirname: !!resolvedShims.esm.__dirname && 'node-module',
1891
1650
  __filename: !!resolvedShims.esm.__filename && 'node-module'
1892
1651
  }
@@ -1918,16 +1677,10 @@ const composeShimsConfig = (format, shims)=>{
1918
1677
  };
1919
1678
  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"')}.`;
1920
1679
  const composeExternalsConfig = (format, externals)=>{
1921
- // TODO: Define the internal externals config in Rsbuild's externals instead
1922
- // Rspack's externals as they will not be merged from different fields. All externals
1923
- // should to be unified and merged together in the future.
1924
1680
  const externalsTypeMap = {
1925
1681
  esm: 'module-import',
1926
1682
  cjs: 'commonjs-import',
1927
1683
  umd: 'umd',
1928
- // If use 'var', when projects import an external package like '@pkg', this will cause a syntax error such as 'var pkg = @pkg'.
1929
- // If use 'umd', the judgement conditions may be affected by other packages that define variables like 'define'.
1930
- // Therefore, we use 'global' to satisfy both web and node environments.
1931
1684
  mf: 'global'
1932
1685
  };
1933
1686
  switch(format){
@@ -1971,7 +1724,6 @@ const composeAutoExtensionConfig = (config, autoExtension, pkgJson)=>{
1971
1724
  };
1972
1725
  };
1973
1726
  const composeSyntaxConfig = (target, syntax)=>{
1974
- // Defaults to ESNext, Rslib will assume all of the latest JavaScript and CSS features are supported.
1975
1727
  if (syntax) return {
1976
1728
  tools: {
1977
1729
  rspack: (config)=>{
@@ -1992,7 +1744,6 @@ const composeSyntaxConfig = (target, syntax)=>{
1992
1744
  }
1993
1745
  },
1994
1746
  output: {
1995
- // If `syntax` is not defined, Rslib will try to determine by the `target`, with the last version of the target.
1996
1747
  overrideBrowserslist: ESX_TO_BROWSERSLIST.esnext(target)
1997
1748
  }
1998
1749
  };
@@ -2022,36 +1773,24 @@ const composeEntryConfig = async (entries, bundle, root, cssModulesAuto)=>{
2022
1773
  },
2023
1774
  lcp: null
2024
1775
  };
2025
- // In bundleless mode, resolve glob patterns and convert them to entry object.
2026
1776
  const resolvedEntries = {};
2027
1777
  for (const key of Object.keys(entries)){
2028
1778
  const entry = entries[key];
2029
- // Entries in bundleless mode could be:
2030
- // 1. A string of glob pattern: { entry: { index: 'src/*.ts' } }
2031
- // 2. An array of glob patterns: { entry: { index: ['src/*.ts', 'src/*.tsx'] } }
2032
- // Not supported for now: entry description object
2033
1779
  const entryFiles = Array.isArray(entry) ? entry : 'string' == typeof entry ? [
2034
1780
  entry
2035
1781
  ] : null;
2036
1782
  if (!entryFiles) throw new Error('Entry can only be a string or an array of strings for now');
2037
- // Turn entries in array into each separate entry.
2038
1783
  const globEntryFiles = await (0, __WEBPACK_EXTERNAL_MODULE_tinyglobby__.glob)(entryFiles, {
2039
1784
  cwd: root,
2040
1785
  absolute: true
2041
1786
  });
2042
- // Filter the glob resolved entry files based on the allowed extensions
2043
1787
  const resolvedEntryFiles = globEntryFiles.filter((file)=>ENTRY_EXTENSIONS_PATTERN.test(file));
2044
1788
  if (0 === resolvedEntryFiles.length) throw new Error(`Cannot find ${resolvedEntryFiles}`);
2045
- // Similar to `rootDir` in tsconfig and `outbase` in esbuild.
2046
1789
  const lcp = await calcLongestCommonPath(resolvedEntryFiles);
2047
- // Using the longest common path of all non-declaration input files by default.
2048
1790
  const outBase = null === lcp ? root : lcp;
2049
1791
  function getEntryName(file) {
2050
1792
  const { dir, name } = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].parse(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].relative(outBase, file));
2051
- // Entry filename contains nested path to preserve source directory structure.
2052
1793
  const entryFileName = __WEBPACK_EXTERNAL_MODULE_node_path__["default"].join(dir, name);
2053
- // 1. we mark the global css files (which will generate empty js chunk in cssExtract), and deleteAsset in RemoveCssExtractAssetPlugin
2054
- // 2. avoid the same name e.g: `index.ts` and `index.css`
2055
1794
  if (isCssGlobalFile(file, cssModulesAuto)) return `${RSLIB_CSS_ENTRY_FLAG}/${entryFileName}`;
2056
1795
  return entryFileName;
2057
1796
  }
@@ -2072,39 +1811,52 @@ const composeEntryConfig = async (entries, bundle, root, cssModulesAuto)=>{
2072
1811
  lcp
2073
1812
  };
2074
1813
  };
2075
- const composeBundleConfig = (jsExtension, redirect, cssModulesAuto, bundle)=>{
2076
- if (bundle) return {};
2077
- const isStyleRedirect = redirect.style ?? true;
1814
+ const composeBundlelessExternalConfig = (jsExtension, redirect, cssModulesAuto, bundle)=>{
1815
+ if (bundle) return {
1816
+ config: {}
1817
+ };
1818
+ const isStyleRedirected = redirect.style ?? true;
1819
+ const jsRedirectPath = redirect.js?.path ?? true;
1820
+ const jsRedirectExtension = redirect.js?.extension ?? true;
1821
+ let resolver;
2078
1822
  return {
2079
- output: {
2080
- externals: [
2081
- (data, callback)=>{
2082
- // Issuer is not empty string when the module is imported by another module.
2083
- // Prevent from externalizing entry modules here.
2084
- if (data.contextInfo.issuer) {
2085
- // Node.js ECMAScript module loader does no extension searching.
2086
- // Add a file extension according to autoExtension config
2087
- // when data.request is a relative path and do not have an extension.
2088
- // If data.request already have an extension, we replace it with new extension
2089
- // This may result in a change in semantics,
2090
- // user should use copy to keep origin file or use another separate entry to deal this
2091
- let request = data.request;
2092
- const cssExternal = cssExternalHandler(request, callback, jsExtension, cssModulesAuto, isStyleRedirect);
2093
- if (false !== cssExternal) return cssExternal;
2094
- if ('.' === request[0]) {
2095
- const ext = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.extname)(request);
2096
- if (ext) {
2097
- if (!JS_EXTENSIONS_PATTERN.test(request)) // If it does not match jsExtensionsPattern, we should do nothing, eg: ./foo.png
2098
- return callback();
2099
- request = request.replace(/\.[^.]+$/, jsExtension);
2100
- } else // TODO: add redirect.extension option
2101
- request = `${request}${jsExtension}`;
1823
+ resolvedJsRedirect: {
1824
+ path: jsRedirectPath,
1825
+ extension: jsRedirectExtension
1826
+ },
1827
+ config: {
1828
+ output: {
1829
+ externals: [
1830
+ async (data, callback)=>{
1831
+ const { request, getResolve, context, contextInfo } = data;
1832
+ if (!request || !getResolve || !context || !contextInfo) return callback();
1833
+ if (!resolver) resolver = await getResolve();
1834
+ if (contextInfo.issuer) {
1835
+ let resolvedRequest = request;
1836
+ const cssExternal = cssExternalHandler(resolvedRequest, callback, jsExtension, cssModulesAuto, isStyleRedirected);
1837
+ if (false !== cssExternal) return cssExternal;
1838
+ if (jsRedirectPath) {
1839
+ try {
1840
+ resolvedRequest = await resolver(context, resolvedRequest);
1841
+ } catch (e) {
1842
+ __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.debug(`Failed to resolve ${resolvedRequest} with resolver`);
1843
+ }
1844
+ resolvedRequest = normalizeSlash(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].relative(__WEBPACK_EXTERNAL_MODULE_node_path__["default"].dirname(contextInfo.issuer), resolvedRequest));
1845
+ if ('.' !== resolvedRequest[0]) resolvedRequest = `./${resolvedRequest}`;
1846
+ }
1847
+ if (jsRedirectExtension) {
1848
+ const ext = (0, __WEBPACK_EXTERNAL_MODULE_node_path__.extname)(resolvedRequest);
1849
+ if (ext) {
1850
+ if (!JS_EXTENSIONS_PATTERN.test(resolvedRequest)) return callback();
1851
+ resolvedRequest = resolvedRequest.replace(/\.[^.]+$/, jsExtension);
1852
+ } else resolvedRequest = `${resolvedRequest}${jsExtension}`;
1853
+ }
1854
+ return callback(void 0, resolvedRequest);
2102
1855
  }
2103
- return callback(null, request);
1856
+ callback();
2104
1857
  }
2105
- callback();
2106
- }
2107
- ]
1858
+ ]
1859
+ }
2108
1860
  }
2109
1861
  };
2110
1862
  };
@@ -2112,7 +1864,6 @@ const composeDtsConfig = async (libConfig, dtsExtension)=>{
2112
1864
  const { format, autoExternal, banner, footer } = libConfig;
2113
1865
  let { dts } = libConfig;
2114
1866
  if (false === dts || void 0 === dts) return {};
2115
- // DTS default to bundleless whether js is bundle or not
2116
1867
  if (true === dts) dts = {
2117
1868
  bundle: false
2118
1869
  };
@@ -2120,7 +1871,6 @@ const composeDtsConfig = async (libConfig, dtsExtension)=>{
2120
1871
  return {
2121
1872
  plugins: [
2122
1873
  pluginDts({
2123
- // Only setting ⁠dts.bundle to true will generate the bundled d.ts.
2124
1874
  bundle: dts?.bundle,
2125
1875
  distPath: dts?.distPath,
2126
1876
  build: dts?.build,
@@ -2133,10 +1883,9 @@ const composeDtsConfig = async (libConfig, dtsExtension)=>{
2133
1883
  ]
2134
1884
  };
2135
1885
  };
2136
- const composeTargetConfig = (target, format)=>{
2137
- let defaultTarget = target;
2138
- if (!defaultTarget) defaultTarget = 'mf' === format ? 'web' : 'node';
2139
- switch(defaultTarget){
1886
+ const composeTargetConfig = (userTarget, format)=>{
1887
+ const target = userTarget ?? ('mf' === format ? 'web' : 'node');
1888
+ switch(target){
2140
1889
  case 'web':
2141
1890
  return {
2142
1891
  config: {
@@ -2148,7 +1897,8 @@ const composeTargetConfig = (target, format)=>{
2148
1897
  }
2149
1898
  }
2150
1899
  },
2151
- target: 'web'
1900
+ target: 'web',
1901
+ externalsConfig: {}
2152
1902
  };
2153
1903
  case 'node':
2154
1904
  return {
@@ -2161,26 +1911,18 @@ const composeTargetConfig = (target, format)=>{
2161
1911
  }
2162
1912
  },
2163
1913
  output: {
2164
- // When output.target is 'node', Node.js's built-in will be treated as externals of type `node-commonjs`.
2165
- // Simply override the built-in modules to make them external.
2166
- // https://github.com/webpack/webpack/blob/dd44b206a9c50f4b4cb4d134e1a0bd0387b159a3/lib/node/NodeTargetPlugin.js#L81
2167
- externals: nodeBuiltInModules,
2168
1914
  target: 'node'
2169
1915
  }
2170
1916
  },
2171
- target: 'node'
1917
+ target: 'node',
1918
+ externalsConfig: {
1919
+ output: {
1920
+ externals: nodeBuiltInModules
1921
+ }
1922
+ }
2172
1923
  };
2173
- // TODO: Support `neutral` target, however Rsbuild don't list it as an option in the target field.
2174
- // case 'neutral':
2175
- // return {
2176
- // tools: {
2177
- // rspack: {
2178
- // target: ['web', 'node'],
2179
- // },
2180
- // },
2181
- // };
2182
1924
  default:
2183
- throw new Error(`Unsupported platform: ${defaultTarget}`);
1925
+ throw new Error(`Unsupported platform: ${target}`);
2184
1926
  }
2185
1927
  };
2186
1928
  const composeExternalHelpersConfig = (externalHelpers, pkgJson)=>{
@@ -2211,10 +1953,9 @@ const composeExternalHelpersConfig = (externalHelpers, pkgJson)=>{
2211
1953
  }
2212
1954
  return defaultConfig;
2213
1955
  };
2214
- async function composeLibRsbuildConfig(config, sharedPlugins) {
1956
+ async function composeLibRsbuildConfig(config, root, sharedPlugins) {
2215
1957
  checkMFPlugin(config, sharedPlugins);
2216
- // Get the absolute path of the root directory to align with Rsbuild's default behavior
2217
- const rootPath = config.root ? getAbsolutePath(process.cwd(), config.root) : process.cwd();
1958
+ const rootPath = root ? getAbsolutePath(process.cwd(), root) : process.cwd();
2218
1959
  const pkgJson = readPackageJson(rootPath);
2219
1960
  const { compilerOptions } = await loadTsconfig(rootPath, config.source?.tsconfigPath);
2220
1961
  const cssModulesAuto = config.output?.cssModules?.auto ?? true;
@@ -2227,10 +1968,10 @@ async function composeLibRsbuildConfig(config, sharedPlugins) {
2227
1968
  umdName
2228
1969
  });
2229
1970
  const externalHelpersConfig = composeExternalHelpersConfig(externalHelpers, pkgJson);
2230
- const externalsConfig = composeExternalsConfig(format, config.output?.externals);
1971
+ const userExternalsConfig = composeExternalsConfig(format, config.output?.externals);
2231
1972
  const { config: autoExtensionConfig, jsExtension, dtsExtension } = composeAutoExtensionConfig(config, autoExtension, pkgJson);
2232
- const bundleConfig = composeBundleConfig(jsExtension, redirect, cssModulesAuto, bundle);
2233
- const { config: targetConfig, target } = composeTargetConfig(config.output?.target, format);
1973
+ const { config: bundlelessExternalConfig } = composeBundlelessExternalConfig(jsExtension, redirect, cssModulesAuto, bundle);
1974
+ const { config: targetConfig, externalsConfig: targetExternalsConfig, target } = composeTargetConfig(config.output?.target, format);
2234
1975
  const syntaxConfig = composeSyntaxConfig(target, config?.syntax);
2235
1976
  const autoExternalConfig = composeAutoExternalConfig({
2236
1977
  format: format,
@@ -2240,43 +1981,30 @@ async function composeLibRsbuildConfig(config, sharedPlugins) {
2240
1981
  });
2241
1982
  const { entryConfig, lcp } = await composeEntryConfig(config.source?.entry, config.bundle, rootPath, cssModulesAuto);
2242
1983
  const cssConfig = composeCssConfig(lcp, config.bundle);
1984
+ const assetConfig = composeAssetConfig(bundle, format);
2243
1985
  const entryChunkConfig = composeEntryChunkConfig({
2244
1986
  enabledImportMetaUrlShim: enabledShims.cjs['import.meta.url']
2245
1987
  });
2246
1988
  const dtsConfig = await composeDtsConfig(config, dtsExtension);
2247
- const externalsWarnConfig = composeExternalsWarnConfig(format, autoExternalConfig?.output?.externals, externalsConfig?.output?.externals);
1989
+ const externalsWarnConfig = composeExternalsWarnConfig(format, autoExternalConfig?.output?.externals, userExternalsConfig?.output?.externals);
2248
1990
  const minifyConfig = composeMinifyConfig(config);
2249
1991
  const bannerFooterConfig = composeBannerFooterConfig(banner, footer);
2250
1992
  const decoratorsConfig = composeDecoratorsConfig(compilerOptions, config.source?.decorators?.version);
2251
- 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);
1993
+ return (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(formatConfig, shimsConfig, syntaxConfig, externalHelpersConfig, autoExtensionConfig, targetConfig, externalsWarnConfig, autoExternalConfig, targetExternalsConfig, userExternalsConfig, bundlelessExternalConfig, entryConfig, cssConfig, assetConfig, entryChunkConfig, minifyConfig, dtsConfig, bannerFooterConfig, decoratorsConfig);
2252
1994
  }
2253
1995
  async function composeCreateRsbuildConfig(rslibConfig) {
2254
1996
  const constantRsbuildConfig = await createConstantRsbuildConfig();
2255
- const { lib: libConfigsArray, plugins: sharedPlugins, ...sharedRsbuildConfig } = rslibConfig;
1997
+ const { lib: libConfigsArray, mode, root, plugins: sharedPlugins, dev, server, ...sharedRsbuildConfig } = rslibConfig;
2256
1998
  if (!libConfigsArray) throw new Error(`Expect lib field to be an array, but got ${libConfigsArray}.`);
2257
1999
  const libConfigPromises = libConfigsArray.map(async (libConfig)=>{
2258
2000
  const userConfig = (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(sharedRsbuildConfig, libConfig);
2259
- // Merge the configuration of each environment based on the shared Rsbuild
2260
- // configuration and Lib configuration in the settings.
2261
- const libRsbuildConfig = await composeLibRsbuildConfig(userConfig, sharedPlugins);
2262
- // Reset certain fields because they will be completely overridden by the upcoming merge.
2263
- // We don't want to retain them in the final configuration.
2264
- // The reset process should occur after merging the library configuration.
2001
+ const libRsbuildConfig = await composeLibRsbuildConfig(userConfig, root, sharedPlugins);
2265
2002
  userConfig.source ??= {};
2266
2003
  userConfig.source.entry = {};
2267
- // Already manually sort and merge the externals configuration.
2268
2004
  userConfig.output ??= {};
2269
2005
  delete userConfig.output.externals;
2270
2006
  const config = {
2271
2007
  format: libConfig.format,
2272
- // The merge order represents the priority of the configuration
2273
- // The priorities from high to low are as follows:
2274
- // 1 - userConfig: users can configure any Rsbuild and Rspack config
2275
- // 2 - libRsbuildConfig: the configuration that we compose from Rslib unique config and userConfig from 1
2276
- // 3 - constantRsbuildConfig: the built-in best practice Rsbuild configuration we provide in Rslib
2277
- // We should state in the document that the built-in configuration should not be changed optionally
2278
- // In compose process of 2, we may read some config from 1, and reassemble the related config,
2279
- // so before final mergeRsbuildConfig, we reset some specified fields
2280
2008
  config: (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(constantRsbuildConfig, libRsbuildConfig, omit(userConfig, {
2281
2009
  id: true,
2282
2010
  bundle: true,
@@ -2301,7 +2029,7 @@ async function composeCreateRsbuildConfig(rslibConfig) {
2301
2029
  }
2302
2030
  async function composeRsbuildEnvironments(rslibConfig) {
2303
2031
  const rsbuildConfigWithLibInfo = await composeCreateRsbuildConfig(rslibConfig);
2304
- // User provided ids should take precedence over generated ids.
2032
+ const environmentWithInfos = [];
2305
2033
  const usedIds = rsbuildConfigWithLibInfo.map(({ id })=>id).filter(Boolean);
2306
2034
  const environments = {};
2307
2035
  const formatCount = rsbuildConfigWithLibInfo.reduce((acc, { format })=>{
@@ -2319,10 +2047,18 @@ async function composeRsbuildEnvironments(rslibConfig) {
2319
2047
  for (const { format, id, config } of rsbuildConfigWithLibInfo){
2320
2048
  const libId = 'string' == typeof id ? id : composeDefaultId(format);
2321
2049
  environments[libId] = config;
2050
+ environmentWithInfos.push({
2051
+ id: libId,
2052
+ format,
2053
+ config
2054
+ });
2322
2055
  }
2323
2056
  const conflictIds = usedIds.filter((id, index)=>usedIds.indexOf(id) !== index);
2324
2057
  if (conflictIds.length) throw new Error(`The following ids are duplicated: ${conflictIds.map((id)=>`"${id}"`).join(', ')}. Please change the "lib.id" to be unique.`);
2325
- return environments;
2058
+ return {
2059
+ environments,
2060
+ environmentWithInfos
2061
+ };
2326
2062
  }
2327
2063
  const pruneEnvironments = (environments, libs)=>{
2328
2064
  if (!libs) return environments;
@@ -2333,7 +2069,6 @@ async function watchFilesForRestart(files, restart) {
2333
2069
  const chokidar = await import("../compiled/chokidar/index.js");
2334
2070
  const watcher = chokidar.watch(files, {
2335
2071
  ignoreInitial: true,
2336
- // If watching fails due to read permissions, the errors will be suppressed silently.
2337
2072
  ignorePermissionErrors: true
2338
2073
  });
2339
2074
  const callback = debounce(async (filePath)=>{
@@ -2348,9 +2083,7 @@ async function watchFilesForRestart(files, restart) {
2348
2083
  watcher.on('unlink', callback);
2349
2084
  }
2350
2085
  let cleaners = [];
2351
- /**
2352
- * Add a cleaner to handle side effects
2353
- */ const onBeforeRestart = (cleaner)=>{
2086
+ const onBeforeRestart = (cleaner)=>{
2354
2087
  cleaners.push(cleaner);
2355
2088
  };
2356
2089
  const clearConsole = ()=>{
@@ -2366,10 +2099,14 @@ const beforeRestart = async ({ filePath, clear = true } = {})=>{
2366
2099
  cleaners = [];
2367
2100
  };
2368
2101
  async function build(config, options = {}) {
2369
- const environments = await composeRsbuildEnvironments(config);
2102
+ const { environments } = await composeRsbuildEnvironments(config);
2370
2103
  const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2371
2104
  rsbuildConfig: {
2105
+ mode: 'production',
2106
+ root: config.root,
2372
2107
  plugins: config.plugins,
2108
+ dev: config.dev,
2109
+ server: config.server,
2373
2110
  environments: pruneEnvironments(environments, options.lib)
2374
2111
  }
2375
2112
  });
@@ -2413,10 +2150,14 @@ async function init(options) {
2413
2150
  };
2414
2151
  }
2415
2152
  async function inspect(config, options = {}) {
2416
- const environments = await composeRsbuildEnvironments(config);
2153
+ const { environments } = await composeRsbuildEnvironments(config);
2417
2154
  const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2418
2155
  rsbuildConfig: {
2156
+ mode: 'production',
2157
+ root: config.root,
2419
2158
  plugins: config.plugins,
2159
+ dev: config.dev,
2160
+ server: config.server,
2420
2161
  environments: pruneEnvironments(environments, options.lib)
2421
2162
  }
2422
2163
  });
@@ -2428,62 +2169,61 @@ async function inspect(config, options = {}) {
2428
2169
  });
2429
2170
  return rsbuildInstance;
2430
2171
  }
2431
- async function startMFDevServer(config) {
2432
- const rsbuildInstance = await initMFRsbuild(config);
2172
+ async function startMFDevServer(config, options = {}) {
2173
+ const rsbuildInstance = await initMFRsbuild(config, options);
2433
2174
  return rsbuildInstance;
2434
2175
  }
2435
- async function initMFRsbuild(rslibConfig) {
2436
- const rsbuildConfigObject = await composeCreateRsbuildConfig(rslibConfig);
2437
- const mfRsbuildConfig = rsbuildConfigObject.find((config)=>'mf' === config.format);
2438
- if (!mfRsbuildConfig) // no mf format, return.
2439
- return;
2440
- mfRsbuildConfig.config = changeEnvToDev(mfRsbuildConfig.config);
2176
+ async function initMFRsbuild(config, options = {}) {
2177
+ const { environments, environmentWithInfos } = await composeRsbuildEnvironments(config);
2178
+ const selectedEnvironmentIds = environmentWithInfos.filter((env)=>{
2179
+ const isMf = 'mf' === env.format;
2180
+ if (!options?.lib) return isMf;
2181
+ return env.id && options.lib.includes(env.id);
2182
+ }).map((env)=>env.id);
2183
+ if (!selectedEnvironmentIds.length) throw new Error('No mf format found, please check your config.');
2184
+ const selectedEnvironments = pruneEnvironments(environments, selectedEnvironmentIds);
2441
2185
  const rsbuildInstance = await (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.createRsbuild)({
2442
2186
  rsbuildConfig: {
2443
- ...mfRsbuildConfig.config,
2444
- plugins: [
2445
- ...rslibConfig.plugins || [],
2446
- ...mfRsbuildConfig.config.plugins || []
2447
- ]
2187
+ mode: 'development',
2188
+ root: config.root,
2189
+ plugins: config.plugins,
2190
+ dev: {
2191
+ ...config.dev ?? {},
2192
+ writeToDisk: true
2193
+ },
2194
+ server: config.server,
2195
+ tools: {
2196
+ rspack: {
2197
+ optimization: {
2198
+ nodeEnv: 'development',
2199
+ moduleIds: 'named'
2200
+ }
2201
+ }
2202
+ },
2203
+ environments: selectedEnvironments
2448
2204
  }
2449
2205
  });
2450
2206
  const devServer = await rsbuildInstance.startDevServer();
2451
2207
  onBeforeRestart(devServer.server.close);
2452
2208
  return rsbuildInstance;
2453
2209
  }
2454
- function changeEnvToDev(rsbuildConfig) {
2455
- return (0, __WEBPACK_EXTERNAL_MODULE__rsbuild_core__.mergeRsbuildConfig)(rsbuildConfig, {
2456
- mode: 'development',
2457
- dev: {
2458
- writeToDisk: true
2459
- },
2460
- tools: {
2461
- rspack: {
2462
- optimization: {
2463
- nodeEnv: 'development',
2464
- moduleIds: 'named'
2465
- }
2466
- }
2467
- }
2468
- });
2469
- }
2470
2210
  const applyCommonOptions = (command)=>{
2471
- 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').option('--env-dir <dir>', 'specify the directory to load `.env` files');
2211
+ 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').option('--env-dir <dir>', 'specify the directory to load `.env` files').option('--lib <id>', 'specify the library (repeatable, e.g. --lib esm --lib cjs)', repeatableOption);
2472
2212
  };
2473
2213
  const repeatableOption = (value, previous)=>(previous ?? []).concat([
2474
2214
  value
2475
2215
  ]);
2476
2216
  function runCli() {
2477
- __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.name('rslib').usage('<command> [options]').version("0.1.4");
2217
+ __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.name('rslib').usage('<command> [options]').version("0.2.0");
2478
2218
  const buildCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('build');
2479
2219
  const inspectCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('inspect');
2480
- const mfDevCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('mf dev');
2220
+ const mfDevCommand = __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.command('mf-dev');
2481
2221
  [
2482
2222
  buildCommand,
2483
2223
  inspectCommand,
2484
2224
  mfDevCommand
2485
2225
  ].forEach(applyCommonOptions);
2486
- 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)=>{
2226
+ buildCommand.option('-w --watch', 'turn on watch mode, watch for changes and rebuild').description('build the library for production').action(async (options)=>{
2487
2227
  try {
2488
2228
  const cliBuild = async ()=>{
2489
2229
  const { config, watchFiles } = await init(options);
@@ -2499,9 +2239,8 @@ function runCli() {
2499
2239
  process.exit(1);
2500
2240
  }
2501
2241
  });
2502
- 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)=>{
2242
+ inspectCommand.description('inspect the Rsbuild / Rspack configs of Rslib projects').option('--output <output>', 'specify inspect content output path', '.rsbuild').option('--verbose', 'show full function definitions in output').action(async (options)=>{
2503
2243
  try {
2504
- // TODO: inspect should output Rslib's config
2505
2244
  const { config } = await init(options);
2506
2245
  await inspect(config, {
2507
2246
  lib: options.lib,
@@ -2519,21 +2258,22 @@ function runCli() {
2519
2258
  try {
2520
2259
  const cliMfDev = async ()=>{
2521
2260
  const { config, watchFiles } = await init(options);
2522
- // TODO: support lib option in mf dev server
2523
- await startMFDevServer(config);
2261
+ await startMFDevServer(config, {
2262
+ lib: options.lib
2263
+ });
2524
2264
  watchFilesForRestart(watchFiles, async ()=>{
2525
2265
  await cliMfDev();
2526
2266
  });
2527
2267
  };
2528
2268
  await cliMfDev();
2529
2269
  } catch (err) {
2530
- __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error('Failed to start mf dev.');
2270
+ __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error('Failed to start mf-dev.');
2531
2271
  __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger.error(err);
2532
2272
  process.exit(1);
2533
2273
  }
2534
2274
  });
2535
2275
  __WEBPACK_EXTERNAL_MODULE__compiled_commander_index_js__.program.parse();
2536
2276
  }
2537
- const src_rslib_entry_version = "0.1.4";
2277
+ const src_rslib_entry_version = "0.2.0";
2538
2278
  var __webpack_exports__logger = __WEBPACK_EXTERNAL_MODULE__compiled_rslog_index_js__.logger;
2539
2279
  export { build, defineConfig, inspect, loadConfig, prepareCli, runCli, startMFDevServer, composeCreateRsbuildConfig as unstable_composeCreateRsbuildConfig, src_rslib_entry_version as version, __webpack_exports__logger as logger };