@rspack/cli 2.1.2 → 2.1.4

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.
@@ -0,0 +1,111 @@
1
+ import { Module } from "node:module";
2
+ import { fileURLToPath } from "node:url";
3
+ import { MessageChannel } from "node:worker_threads";
4
+ const instanceId = Math.random().toString(36).slice(2);
5
+ const relativeImportRE = /^\.{1,2}(?:\/|\\)/;
6
+ function escapeRegExp(value) {
7
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8
+ }
9
+ function buildQueryName() {
10
+ return `fresh-import-${instanceId}`;
11
+ }
12
+ function buildQueryRE(queryName) {
13
+ return new RegExp(`(?:\\?|&)${escapeRegExp(queryName)}=(\\d+),([^&]+)(?:&|$)`);
14
+ }
15
+ function formatTrackingQuery(queryName, id, context) {
16
+ return `?${queryName}=${id},${context}`;
17
+ }
18
+ function trackResolved(specifier, context, result, queryName, queryRE, onDependency) {
19
+ const isRelativeImport = relativeImportRE.test(specifier);
20
+ if ("builtin" === result.format || !isRelativeImport) return result;
21
+ if (!context.parentURL || queryRE.test(result.url) || !result.url.startsWith("file:")) return result;
22
+ const m = queryRE.exec(context.parentURL);
23
+ if (m) {
24
+ const [, id, contextFile] = m;
25
+ onDependency(contextFile, result.url);
26
+ result.url = result.url.replace(/(\?)|$/, (_n, n1)=>`?${queryName}=${id},${contextFile}${"?" === n1 ? "&" : ""}`);
27
+ }
28
+ return result;
29
+ }
30
+ var loader_default = 'data:text/javascript,Math.random().toString(36).slice(2);%0Aconst relativeImportRE = /^\\.{1,2}(%3F:\\/|\\\\)/;%0Afunction escapeRegExp(value) {%0A%09return value.replace(/[.*+%3F^${}()|[\\]\\\\]/g, "\\\\$&");%0A}%0A/**%0A* Build the regex that matches the tracking query `%3F<name>=<id>,<context>`%0A* (or the `&<name>=...` form).%0A*/%0Afunction buildQueryRE(queryName) {%0A%09return new RegExp(`(%3F:\\\\%3F|&)${escapeRegExp(queryName)}=(\\\\d+),([^&]+)(%3F:&|$)`);%0A}%0A/**%0A* Shared body of the resolve hook for both the on-thread and off-thread%0A* importers. Given an already-resolved `result`, decides whether it is a tracked%0A* relative file dependency; if so, reports it via `onDependency` and tags the%0A* URL so the query propagates to its own dependencies.%0A*%0A* The sync/async difference between the two hooks lives entirely in the caller%0A* (which awaits `nextResolve` or not); this function performs no I/O. `result`%0A* is mutated in place and returned.%0A*/%0Afunction trackResolved(specifier, context, result, queryName, queryRE, onDependency) {%0A%09const isRelativeImport = relativeImportRE.test(specifier);%0A%09if (result.format === "builtin" || !isRelativeImport) return result;%0A%09if (!context.parentURL || queryRE.test(result.url) || !result.url.startsWith("file:")) return result;%0A%09const m = queryRE.exec(context.parentURL);%0A%09if (m) {%0A%09%09const [, id, contextFile] = m;%0A%09%09onDependency(contextFile, result.url);%0A%09%09result.url = result.url.replace(/(\\%3F)|$/, (_n, n1) => `%3F${queryName}=${id},${contextFile}${n1 === "%3F" %3F "&" : ""}`);%0A%09}%0A%09return result;%0A}%0A//%23endregion%0A//%23region src/off-thread/loader.ts%0Alet port;%0Alet queryName;%0Alet queryRE;%0Aconst initialize = async (data) => {%0A%09port = data.port;%0A%09queryName = data.queryName;%0A%09queryRE = buildQueryRE(queryName);%0A};%0Aconst resolve = async (specifier, context, nextResolve) => {%0A%09return trackResolved(specifier, context, await nextResolve(specifier, context), queryName, queryRE, (ctx, url) => {%0A%09%09port.postMessage({%0A%09%09%09context: ctx,%0A%09%09%09url%0A%09%09});%0A%09});%0A};%0A//%23endregion%0Aexport { initialize, resolve };%0A';
31
+ let nextId$1 = 0;
32
+ function createOffThreadImporter() {
33
+ const queryName = buildQueryName();
34
+ const { port1, port2 } = new MessageChannel();
35
+ Module.register(loader_default, {
36
+ data: {
37
+ port: port2,
38
+ queryName
39
+ },
40
+ transferList: [
41
+ port2
42
+ ]
43
+ });
44
+ port1.unref();
45
+ return {
46
+ async collect (specifier) {
47
+ const id = nextId$1++;
48
+ const depsList = /* @__PURE__ */ new Set();
49
+ const onMessage = (e)=>{
50
+ if (e.context === specifier) depsList.add(e.url);
51
+ };
52
+ port1.on("message", onMessage);
53
+ port1.unref();
54
+ try {
55
+ const result = await import(specifier + formatTrackingQuery(queryName, id, specifier));
56
+ await new Promise((resolve)=>setImmediate(resolve));
57
+ return {
58
+ result,
59
+ dependencies: [
60
+ ...depsList
61
+ ].filter((url)=>url.startsWith("file:")).map((url)=>fileURLToPath(url))
62
+ };
63
+ } finally{
64
+ port1.off("message", onMessage);
65
+ }
66
+ }
67
+ };
68
+ }
69
+ let nextId = 0;
70
+ function createOnThreadImporter() {
71
+ const registry = /* @__PURE__ */ new Map();
72
+ const queryName = buildQueryName();
73
+ const queryRE = buildQueryRE(queryName);
74
+ const resolve = (specifier, context, nextResolve)=>trackResolved(specifier, context, nextResolve(specifier, context), queryName, queryRE, (ctx, url)=>{
75
+ registry.get(ctx)?.add(url);
76
+ });
77
+ Module.registerHooks({
78
+ resolve
79
+ });
80
+ return {
81
+ async collect (specifier) {
82
+ const id = nextId++;
83
+ const depsList = /* @__PURE__ */ new Set();
84
+ registry.set(specifier, depsList);
85
+ try {
86
+ return {
87
+ result: await import(specifier + formatTrackingQuery(queryName, id, specifier)),
88
+ dependencies: [
89
+ ...depsList
90
+ ].filter((url)=>url.startsWith("file:")).map((url)=>fileURLToPath(url))
91
+ };
92
+ } finally{
93
+ registry.delete(specifier);
94
+ }
95
+ }
96
+ };
97
+ }
98
+ function createImporter() {
99
+ if (Module.registerHooks) return createOnThreadImporter();
100
+ if (Module.register) return createOffThreadImporter();
101
+ }
102
+ let importer;
103
+ let initialized = false;
104
+ function freshImport(specifier) {
105
+ if (!initialized) {
106
+ importer = createImporter();
107
+ initialized = true;
108
+ }
109
+ return importer?.collect(specifier);
110
+ }
111
+ export { freshImport };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import node_path from "node:path";
1
+ import node_path, { isAbsolute, join } from "node:path";
2
2
  import node_util from "node:util";
3
3
  import { rspack } from "@rspack/core";
4
4
  import node_fs from "node:fs";
@@ -854,98 +854,117 @@ class ServeCommand {
854
854
  }));
855
855
  }
856
856
  }
857
- function mergeWith(objects, customizer) {
858
- const [first, ...rest] = objects;
859
- let ret = first;
860
- rest.forEach((a)=>{
861
- ret = mergeTo(ret, a, customizer);
862
- });
863
- return ret;
864
- }
865
- function mergeTo(a, b, customizer) {
866
- const ret = {};
867
- Object.keys(a).concat(Object.keys(b)).forEach((k)=>{
868
- const v = customizer(a[k], b[k], k);
869
- ret[k] = void 0 === v ? a[k] : v;
857
+ const canReadExport = (module)=>null !== module && ('object' == typeof module || 'function' == typeof module);
858
+ const isConfigFunction = (configExport)=>'function' == typeof configExport;
859
+ const getConfigExport = (configModule, exportName, configPath)=>{
860
+ if (false === exportName) return {};
861
+ if ('default' === exportName) return canReadExport(configModule) && 'default' in configModule ? configModule.default : configModule;
862
+ if (canReadExport(configModule) && Object.hasOwn(configModule, exportName)) return configModule[exportName];
863
+ throw new Error(`Cannot find export ${exportName} in config file: ${configPath}`);
864
+ };
865
+ const loadWithJiti = async (configPath, exportName, fresh)=>{
866
+ let createJiti;
867
+ try {
868
+ ({ createJiti } = await import("../compiled/jiti/index.js"));
869
+ } catch (error) {
870
+ throw new Error('The "jiti" package is required to load this config. Install it with your package manager.', {
871
+ cause: error
872
+ });
873
+ }
874
+ const jiti = createJiti(configPath, {
875
+ moduleCache: !fresh,
876
+ interopDefault: true,
877
+ nativeModules: [
878
+ "typescript"
879
+ ]
870
880
  });
871
- return ret;
872
- }
873
- const merge_with = mergeWith;
874
- function isRegex(o) {
875
- return o instanceof RegExp;
876
- }
877
- function isPlainObject(value) {
878
- if ('[object Object]' !== Object.prototype.toString.call(value)) return false;
879
- const proto = Object.getPrototypeOf(value);
880
- if (null === proto) return true;
881
- let baseProto = proto;
882
- while(null !== Object.getPrototypeOf(baseProto))baseProto = Object.getPrototypeOf(baseProto);
883
- return proto === baseProto;
884
- }
885
- function isUndefined(value) {
886
- return void 0 === value;
887
- }
888
- function isPromiseLike(value) {
889
- return null !== value && ('object' == typeof value || 'function' == typeof value) && 'function' == typeof value.then;
890
- }
891
- const isArray = Array.isArray;
892
- function joinArrays({ customizeArray, customizeObject, key } = {}) {
893
- return function _joinArrays(a, b, k) {
894
- const newKey = key ? `${key}.${k}` : k;
895
- if ('function' == typeof a && 'function' == typeof b) return (...args)=>_joinArrays(a(...args), b(...args), k);
896
- if (isArray(a) && isArray(b)) {
897
- const customResult = customizeArray && customizeArray(a, b, newKey);
898
- return customResult || [
899
- ...a,
900
- ...b
901
- ];
902
- }
903
- if (isRegex(b)) return b;
904
- if (isPlainObject(a) && isPlainObject(b)) {
905
- const customResult = customizeObject && customizeObject(a, b, newKey);
906
- return customResult || merge_with([
907
- a,
908
- b
909
- ], joinArrays({
910
- customizeArray,
911
- customizeObject,
912
- key: newKey
913
- }));
914
- }
915
- if (isPlainObject(b)) return merge_with([
916
- {},
917
- b
918
- ], joinArrays({
919
- customizeArray,
920
- customizeObject,
921
- key: newKey
922
- }));
923
- if (isArray(b)) return [
924
- ...b
925
- ];
926
- return b;
881
+ if ('default' === exportName) return {
882
+ configExport: await jiti.import(configPath, {
883
+ default: true
884
+ }),
885
+ dependencies: []
927
886
  };
928
- }
929
- function merge(firstConfiguration, ...configurations) {
930
- return mergeWithCustomize({})(firstConfiguration, ...configurations);
931
- }
932
- function mergeWithCustomize(options) {
933
- return function(firstConfiguration, ...configurations) {
934
- if (isUndefined(firstConfiguration) || configurations.some(isUndefined)) throw new TypeError('Merging undefined is not supported');
935
- if (isPromiseLike(firstConfiguration)) throw new TypeError('Promises are not supported');
936
- if (!firstConfiguration) return {};
937
- if (0 === configurations.length) {
938
- if (Array.isArray(firstConfiguration)) {
939
- if (0 === firstConfiguration.length) return {};
940
- if (firstConfiguration.some(isUndefined)) throw new TypeError('Merging undefined is not supported');
941
- if (isPromiseLike(firstConfiguration[0])) throw new TypeError('Promises are not supported');
942
- return merge_with(firstConfiguration, joinArrays(options));
943
- }
944
- return firstConfiguration;
887
+ const configModule = await jiti.import(configPath);
888
+ return {
889
+ configExport: getConfigExport(configModule, exportName, configPath),
890
+ dependencies: []
891
+ };
892
+ };
893
+ const JS_CONFIG_REGEXP = /\.(?:js|mjs|cjs)$/;
894
+ const tryFreshImport = async (configFileURL)=>{
895
+ try {
896
+ const { freshImport } = await import("./freshImport.js");
897
+ return await freshImport(configFileURL);
898
+ } catch {}
899
+ };
900
+ const loadWithNative = async (configPath, fresh)=>{
901
+ const configFileURL = pathToFileURL(configPath).href;
902
+ if (!fresh) {
903
+ const configModule = await import(configFileURL);
904
+ return {
905
+ configModule,
906
+ dependencies: []
907
+ };
908
+ }
909
+ const freshImportResult = await tryFreshImport(configFileURL);
910
+ if (freshImportResult) return {
911
+ configModule: freshImportResult.result,
912
+ dependencies: freshImportResult.dependencies.sort()
913
+ };
914
+ const configModule = await import(`${configFileURL}?t=${Date.now()}`);
915
+ return {
916
+ configModule,
917
+ dependencies: []
918
+ };
919
+ };
920
+ const resolveConfigPath = (root, customConfig, configFileNames = [])=>{
921
+ if (customConfig) {
922
+ const customConfigPath = isAbsolute(customConfig) ? customConfig : join(root, customConfig);
923
+ if (node_fs.existsSync(customConfigPath)) return customConfigPath;
924
+ throw new Error(`Cannot find config file: ${customConfigPath}`);
925
+ }
926
+ for (const file of configFileNames){
927
+ const configFile = join(root, file);
928
+ if (node_fs.existsSync(configFile)) return configFile;
929
+ }
930
+ return null;
931
+ };
932
+ async function loadConfig({ cwd = process.cwd(), path, configFileNames = [], loader = 'auto', exportName = 'default', configParams = [], fresh = false } = {}) {
933
+ const configPath = resolveConfigPath(cwd, path, configFileNames);
934
+ if (!configPath) return {
935
+ content: {},
936
+ filePath: configPath,
937
+ dependencies: []
938
+ };
939
+ let loadedConfig;
940
+ const useNative = Boolean('native' === loader || 'auto' === loader && (process.features.typescript || process.versions.bun || process.versions.deno));
941
+ if (useNative || JS_CONFIG_REGEXP.test(configPath)) {
942
+ let result;
943
+ try {
944
+ result = await loadWithNative(configPath, fresh);
945
+ } catch (err) {
946
+ if ('native' === loader) throw err;
945
947
  }
946
- return merge_with([
947
- firstConfiguration
948
- ].concat(configurations), joinArrays(options));
948
+ if (result) loadedConfig = {
949
+ configExport: getConfigExport(result.configModule, exportName, configPath),
950
+ dependencies: result.dependencies
951
+ };
952
+ }
953
+ if (!loadedConfig) loadedConfig = await loadWithJiti(configPath, exportName, fresh);
954
+ const { configExport, dependencies } = loadedConfig;
955
+ if (isConfigFunction(configExport)) {
956
+ const result = await configExport(...configParams);
957
+ if (void 0 === result) throw new Error('The config function must return a config object.');
958
+ return {
959
+ content: result,
960
+ filePath: configPath,
961
+ dependencies
962
+ };
963
+ }
964
+ return {
965
+ content: configExport,
966
+ filePath: configPath,
967
+ dependencies
949
968
  };
950
969
  }
951
970
  const DEFAULT_EXTENSIONS = [
@@ -960,71 +979,22 @@ const findConfig = (basePath)=>DEFAULT_EXTENSIONS.map((ext)=>basePath + ext).fin
960
979
  const utils_findConfig = findConfig;
961
980
  const loadConfig_require = createRequire(import.meta.url);
962
981
  const loadConfig_DEFAULT_CONFIG_NAME = 'rspack.config';
963
- const JS_CONFIG_EXTENSION_REGEXP = /\.(?:js|mjs|cjs)$/;
964
- const CONFIG_LOADER_VALUES = [
965
- 'auto',
966
- 'jiti',
967
- 'native'
968
- ];
969
- const PREBUNDLED_JITI_PATH = new URL('../compiled/jiti/index.js', import.meta.url).href;
970
- const supportsNativeTypeScript = ()=>{
971
- const features = process.features;
972
- return Boolean(features.typescript || process.versions.bun || process.versions.deno);
973
- };
974
- const normalizeConfigLoader = (configLoader)=>{
975
- const normalizedLoader = configLoader ?? 'auto';
976
- if (CONFIG_LOADER_VALUES.includes(normalizedLoader)) return normalizedLoader;
977
- throw new Error(`config loader "${normalizedLoader}" is not supported. Expected one of: ${CONFIG_LOADER_VALUES.join(', ')}.`);
978
- };
979
- const resolveDefaultExport = (result)=>result && 'object' == typeof result && 'default' in result ? result.default : result;
980
- const loadConfigWithNativeLoader = async (configPath)=>{
981
- const configFileURL = pathToFileURL(configPath).href;
982
- const loadedModule = await import(`${configFileURL}?t=${Date.now()}`);
983
- return resolveDefaultExport(loadedModule);
984
- };
985
- let jitiInstancePromise;
986
- const getJiti = async ()=>{
987
- if (!jitiInstancePromise) jitiInstancePromise = import(PREBUNDLED_JITI_PATH).then((module)=>{
988
- const createJiti = 'createJiti' in module ? module.createJiti : module.default;
989
- return createJiti(import.meta.filename, {
990
- moduleCache: false,
991
- interopDefault: true,
992
- nativeModules: [
993
- "typescript"
994
- ]
995
- });
996
- });
997
- return jitiInstancePromise;
998
- };
999
- const loadConfigWithJiti = async (configPath)=>{
1000
- const jiti = await getJiti();
1001
- return jiti.import(configPath, {
1002
- default: true
1003
- });
1004
- };
1005
982
  const loadConfigByPath = async (configPath, options)=>{
1006
- const configLoader = normalizeConfigLoader(options.configLoader);
1007
- const useNative = Boolean('native' === configLoader || 'auto' === configLoader && supportsNativeTypeScript());
1008
- if (useNative || JS_CONFIG_EXTENSION_REGEXP.test(configPath)) try {
1009
- return await loadConfigWithNativeLoader(configPath);
1010
- } catch (error) {
1011
- if ('native' === configLoader) throw error;
1012
- }
1013
- return loadConfigWithJiti(configPath);
983
+ const configParams = [
984
+ options.env,
985
+ options
986
+ ];
987
+ const { content } = await loadConfig({
988
+ path: configPath,
989
+ loader: options.configLoader,
990
+ configParams,
991
+ fresh: true
992
+ });
993
+ if (!isRspackConfig(content)) throw new Error(`[rspack-cli:loadConfig] The config at "${configPath}" must be an object or an array, got ${String(content)}`);
994
+ return content;
1014
995
  };
1015
996
  const isConfigObject = (value)=>Boolean(value) && 'object' == typeof value && !Array.isArray(value);
1016
997
  const isRspackConfig = (value)=>Array.isArray(value) || isConfigObject(value);
1017
- const resolveRspackConfigExport = async (configExport, options)=>{
1018
- let loadedConfig = configExport;
1019
- if ('function' == typeof loadedConfig) {
1020
- let functionResult = loadedConfig(options.env, options);
1021
- if ('function' == typeof functionResult.then) functionResult = await functionResult;
1022
- if (void 0 === functionResult) throw new Error('[rspack-cli:loadConfig] The config function must return a config object.');
1023
- loadedConfig = functionResult;
1024
- }
1025
- if (!isRspackConfig(loadedConfig)) throw new Error(`[rspack-cli:loadConfig] The config must be an object, an array, or a function that returns one, get ${String(loadedConfig)}`);
1026
- return loadedConfig;
1027
- };
1028
998
  const checkIsMultiRspackOptions = (config)=>Array.isArray(config);
1029
999
  async function loadExtendedConfig(config, configPath, cwd, options, visitedPaths) {
1030
1000
  const currentVisitedPaths = visitedPaths ?? new Set();
@@ -1087,8 +1057,8 @@ async function loadExtendedConfig(config, configPath, cwd, options, visitedPaths
1087
1057
  }
1088
1058
  if (!node_fs.existsSync(resolvedPath)) throw new Error(`Extended configuration file "${resolvedPath}" not found.`);
1089
1059
  const loadedConfig = await loadConfigByPath(resolvedPath, options);
1090
- const resolvedConfig = await resolveRspackConfigExport(loadedConfig, options);
1091
- const { config: extendedConfig, pathMap: extendedPathMap } = await loadExtendedConfig(resolvedConfig, resolvedPath, cwd, options, currentVisitedPaths);
1060
+ const { merge } = await import("./rspack-merge.js");
1061
+ const { config: extendedConfig, pathMap: extendedPathMap } = await loadExtendedConfig(loadedConfig, resolvedPath, cwd, options, currentVisitedPaths);
1092
1062
  const configPaths = [
1093
1063
  ...pathMap.get(resultConfig) || [],
1094
1064
  ...extendedPathMap.get(extendedConfig) || []
@@ -1149,7 +1119,7 @@ class RspackCLI {
1149
1119
  this.colors = this.createColors();
1150
1120
  this.program = program;
1151
1121
  program.help();
1152
- program.version("2.1.2");
1122
+ program.version("2.1.4");
1153
1123
  }
1154
1124
  wrapAction(fn) {
1155
1125
  return (...args)=>{
@@ -1279,8 +1249,7 @@ class RspackCLI {
1279
1249
  pathMap: new WeakMap()
1280
1250
  };
1281
1251
  const { loadedConfig, configPath } = config;
1282
- const resolvedConfig = await resolveRspackConfigExport(loadedConfig, options);
1283
- const { config: extendedConfig, pathMap } = await loadExtendedConfig(resolvedConfig, configPath, process.cwd(), options);
1252
+ const { config: extendedConfig, pathMap } = await loadExtendedConfig(loadedConfig, configPath, process.cwd(), options);
1284
1253
  return {
1285
1254
  config: this.filterConfig(options, extendedConfig),
1286
1255
  pathMap
@@ -0,0 +1,95 @@
1
+ function mergeWith(objects, customizer) {
2
+ const [first, ...rest] = objects;
3
+ let ret = first;
4
+ rest.forEach((a)=>{
5
+ ret = mergeTo(ret, a, customizer);
6
+ });
7
+ return ret;
8
+ }
9
+ function mergeTo(a, b, customizer) {
10
+ const ret = {};
11
+ Object.keys(a).concat(Object.keys(b)).forEach((k)=>{
12
+ const v = customizer(a[k], b[k], k);
13
+ ret[k] = void 0 === v ? a[k] : v;
14
+ });
15
+ return ret;
16
+ }
17
+ const merge_with = mergeWith;
18
+ function isRegex(o) {
19
+ return o instanceof RegExp;
20
+ }
21
+ function isPlainObject(value) {
22
+ if ('[object Object]' !== Object.prototype.toString.call(value)) return false;
23
+ const proto = Object.getPrototypeOf(value);
24
+ if (null === proto) return true;
25
+ let baseProto = proto;
26
+ while(null !== Object.getPrototypeOf(baseProto))baseProto = Object.getPrototypeOf(baseProto);
27
+ return proto === baseProto;
28
+ }
29
+ function isUndefined(value) {
30
+ return void 0 === value;
31
+ }
32
+ function isPromiseLike(value) {
33
+ return null !== value && ('object' == typeof value || 'function' == typeof value) && 'function' == typeof value.then;
34
+ }
35
+ const isArray = Array.isArray;
36
+ function joinArrays({ customizeArray, customizeObject, key } = {}) {
37
+ return function _joinArrays(a, b, k) {
38
+ const newKey = key ? `${key}.${k}` : k;
39
+ if ('function' == typeof a && 'function' == typeof b) return (...args)=>_joinArrays(a(...args), b(...args), k);
40
+ if (isArray(a) && isArray(b)) {
41
+ const customResult = customizeArray && customizeArray(a, b, newKey);
42
+ return customResult || [
43
+ ...a,
44
+ ...b
45
+ ];
46
+ }
47
+ if (isRegex(b)) return b;
48
+ if (isPlainObject(a) && isPlainObject(b)) {
49
+ const customResult = customizeObject && customizeObject(a, b, newKey);
50
+ return customResult || merge_with([
51
+ a,
52
+ b
53
+ ], joinArrays({
54
+ customizeArray,
55
+ customizeObject,
56
+ key: newKey
57
+ }));
58
+ }
59
+ if (isPlainObject(b)) return merge_with([
60
+ {},
61
+ b
62
+ ], joinArrays({
63
+ customizeArray,
64
+ customizeObject,
65
+ key: newKey
66
+ }));
67
+ if (isArray(b)) return [
68
+ ...b
69
+ ];
70
+ return b;
71
+ };
72
+ }
73
+ function merge(firstConfiguration, ...configurations) {
74
+ return mergeWithCustomize({})(firstConfiguration, ...configurations);
75
+ }
76
+ function mergeWithCustomize(options) {
77
+ return function(firstConfiguration, ...configurations) {
78
+ if (isUndefined(firstConfiguration) || configurations.some(isUndefined)) throw new TypeError('Merging undefined is not supported');
79
+ if (isPromiseLike(firstConfiguration)) throw new TypeError('Promises are not supported');
80
+ if (!firstConfiguration) return {};
81
+ if (0 === configurations.length) {
82
+ if (Array.isArray(firstConfiguration)) {
83
+ if (0 === firstConfiguration.length) return {};
84
+ if (firstConfiguration.some(isUndefined)) throw new TypeError('Merging undefined is not supported');
85
+ if (isPromiseLike(firstConfiguration[0])) throw new TypeError('Promises are not supported');
86
+ return merge_with(firstConfiguration, joinArrays(options));
87
+ }
88
+ return firstConfiguration;
89
+ }
90
+ return merge_with([
91
+ firstConfiguration
92
+ ].concat(configurations), joinArrays(options));
93
+ };
94
+ }
95
+ export { merge };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack/cli",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "CLI for rspack",
5
5
  "homepage": "https://rspack.rs",
6
6
  "bugs": "https://github.com/web-infra-dev/rspack/issues",
@@ -30,7 +30,8 @@
30
30
  "devDependencies": {
31
31
  "@discoveryjs/json-ext": "^1.1.0",
32
32
  "@microsoft/api-extractor": "^7.58.9",
33
- "@rslib/core": "^0.23.0",
33
+ "@rstackjs/load-config": "^0.1.1",
34
+ "@rslib/core": "^0.23.2",
34
35
  "@rspack/dev-server": "^2.1.0",
35
36
  "cac": "^7.0.0",
36
37
  "concat-stream": "^2.0.0",
@@ -41,8 +42,8 @@
41
42
  "prebundle": "^1.6.5",
42
43
  "rspack-merge": "1.0.1",
43
44
  "typescript": "^6.0.3",
44
- "@rspack/core": "2.1.2",
45
- "@rspack/test-tools": "2.1.2"
45
+ "@rspack/core": "2.1.4",
46
+ "@rspack/test-tools": "2.1.4"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "@rspack/core": "^2.0.0-0",