@rsdoctor/core 1.4.0 → 1.5.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.
@@ -39,7 +39,7 @@ class InternalBundleTagPlugin extends external_base_cjs_namespaceObject.Internal
39
39
  name: 'RsdoctorTagBannerPlugin',
40
40
  stage: -2000
41
41
  }, async ()=>{
42
- if (!compilation.options.plugins.map((p)=>p && p.constructor.name).includes('BannerPlugin') && true !== supportBannerPlugin || false === supportBannerPlugin || 'rspack' in compiler) return;
42
+ if (true !== supportBannerPlugin || 'rspack' in compiler) return;
43
43
  logger_namespaceObject.logger.info(logger_namespaceObject.chalk.magenta("Rsdoctor's `supports.banner` option is enabled, this is for debugging only. Do not use it for production."));
44
44
  const minimizers = compiler.options.optimization?.minimizer || [];
45
45
  const terserPlugin = minimizers.find((plugin)=>plugin?.constructor?.name === 'TerserPlugin');
@@ -13,7 +13,7 @@ class InternalBundleTagPlugin extends InternalBasePlugin {
13
13
  name: 'RsdoctorTagBannerPlugin',
14
14
  stage: -2000
15
15
  }, async ()=>{
16
- if (!compilation.options.plugins.map((p)=>p && p.constructor.name).includes('BannerPlugin') && true !== supportBannerPlugin || false === supportBannerPlugin || 'rspack' in compiler) return;
16
+ if (true !== supportBannerPlugin || 'rspack' in compiler) return;
17
17
  logger.info(chalk.magenta("Rsdoctor's `supports.banner` option is enabled, this is for debugging only. Do not use it for production."));
18
18
  const minimizers = compiler.options.optimization?.minimizer || [];
19
19
  const terserPlugin = minimizers.find((plugin)=>plugin?.constructor?.name === 'TerserPlugin');
@@ -47,6 +47,7 @@ const logger_namespaceObject = require("@rsdoctor/utils/logger");
47
47
  const external_path_namespaceObject = require("path");
48
48
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
49
49
  const external_url_namespaceObject = require("url");
50
+ const plugin_common_cjs_namespaceObject = require("../utils/plugin-common.cjs");
50
51
  const loader_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
51
52
  const loader_dirname = external_path_default().dirname(loader_filename);
52
53
  class InternalLoaderPlugin extends external_base_cjs_namespaceObject.InternalBasePlugin {
@@ -74,7 +75,7 @@ class InternalLoaderPlugin extends external_base_cjs_namespaceObject.InternalBas
74
75
  };
75
76
  return loader;
76
77
  });
77
- const newLoaders = (0, compat_namespaceObject.cloneDeep)(originLoaders);
78
+ const newLoaders = (0, plugin_common_cjs_namespaceObject.safeCloneDeep)(originLoaders);
78
79
  if ('object' == typeof compiler.options.cache && 'version' in compiler.options.cache && 'string' == typeof compiler.options.cache.version && compiler.options.cache.version.indexOf('next/dist/build') > -1) callback(loaderContext, module || {});
79
80
  else {
80
81
  const proxyModule = new Proxy(module || {}, {
@@ -83,7 +84,7 @@ class InternalLoaderPlugin extends external_base_cjs_namespaceObject.InternalBas
83
84
  return Reflect.get(target, p, receiver);
84
85
  },
85
86
  set (target, p, newValue, receiver) {
86
- const _newValue = (0, compat_namespaceObject.cloneDeep)(newValue);
87
+ const _newValue = (0, plugin_common_cjs_namespaceObject.safeCloneDeep)(newValue);
87
88
  if ('loaders' === p) {
88
89
  if (Array.isArray(_newValue)) {
89
90
  newLoaders.length = 0;
@@ -2,12 +2,13 @@ import __rslib_shim_module__ from 'module';
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.url);
3
3
  import { Manifest } from "@rsdoctor/types";
4
4
  import { Loader } from "@rsdoctor/utils/common";
5
- import { cloneDeep, isEqual, omit } from "es-toolkit/compat";
5
+ import { isEqual, omit } from "es-toolkit/compat";
6
6
  import { interceptLoader } from "../utils/index.js";
7
7
  import { InternalBasePlugin } from "./base.js";
8
8
  import { time, timeEnd } from "@rsdoctor/utils/logger";
9
9
  import path from "path";
10
10
  import { fileURLToPath } from "url";
11
+ import { safeCloneDeep } from "../utils/plugin-common.js";
11
12
  const loader_filename = fileURLToPath(import.meta.url);
12
13
  const loader_dirname = path.dirname(loader_filename);
13
14
  class InternalLoaderPlugin extends InternalBasePlugin {
@@ -35,7 +36,7 @@ class InternalLoaderPlugin extends InternalBasePlugin {
35
36
  };
36
37
  return loader;
37
38
  });
38
- const newLoaders = cloneDeep(originLoaders);
39
+ const newLoaders = safeCloneDeep(originLoaders);
39
40
  if ('object' == typeof compiler.options.cache && 'version' in compiler.options.cache && 'string' == typeof compiler.options.cache.version && compiler.options.cache.version.indexOf('next/dist/build') > -1) callback(loaderContext, module || {});
40
41
  else {
41
42
  const proxyModule = new Proxy(module || {}, {
@@ -44,7 +45,7 @@ class InternalLoaderPlugin extends InternalBasePlugin {
44
45
  return Reflect.get(target, p, receiver);
45
46
  },
46
47
  set (target, p, newValue, receiver) {
47
- const _newValue = cloneDeep(newValue);
48
+ const _newValue = safeCloneDeep(newValue);
48
49
  if ('loaders' === p) {
49
50
  if (Array.isArray(_newValue)) {
50
51
  newLoaders.length = 0;
@@ -150,15 +150,11 @@ function normalizeRspackUserOptions(options) {
150
150
  const config = normalizeUserConfig(options);
151
151
  config.experiments ??= {
152
152
  enableNativePlugin: {
153
- moduleGraph: false,
154
- chunkGraph: false
153
+ moduleGraph: true,
154
+ chunkGraph: true
155
155
  }
156
156
  };
157
- if ('boolean' == typeof options.experiments?.enableNativePlugin && options.experiments?.enableNativePlugin === true) config.experiments.enableNativePlugin = {
158
- moduleGraph: true,
159
- chunkGraph: true
160
- };
161
- else config.experiments.enableNativePlugin = {
157
+ if ('boolean' == typeof options.experiments?.enableNativePlugin && options.experiments?.enableNativePlugin === false) config.experiments.enableNativePlugin = {
162
158
  moduleGraph: false,
163
159
  chunkGraph: false
164
160
  };
@@ -112,15 +112,11 @@ function normalizeRspackUserOptions(options) {
112
112
  const config = normalizeUserConfig(options);
113
113
  config.experiments ??= {
114
114
  enableNativePlugin: {
115
- moduleGraph: false,
116
- chunkGraph: false
115
+ moduleGraph: true,
116
+ chunkGraph: true
117
117
  }
118
118
  };
119
- if ('boolean' == typeof options.experiments?.enableNativePlugin && options.experiments?.enableNativePlugin === true) config.experiments.enableNativePlugin = {
120
- moduleGraph: true,
121
- chunkGraph: true
122
- };
123
- else config.experiments.enableNativePlugin = {
119
+ if ('boolean' == typeof options.experiments?.enableNativePlugin && options.experiments?.enableNativePlugin === false) config.experiments.enableNativePlugin = {
124
120
  moduleGraph: false,
125
121
  chunkGraph: false
126
122
  };
@@ -34,18 +34,79 @@ var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
36
  processCompilerConfig: ()=>processCompilerConfig,
37
+ safeCloneDeep: ()=>safeCloneDeep,
37
38
  handleBriefModeReport: ()=>handleBriefModeReport
38
39
  });
39
40
  const sdk_namespaceObject = require("@rsdoctor/sdk");
40
41
  const plugins_namespaceObject = require("@rsdoctor/core/plugins");
41
42
  const types_namespaceObject = require("@rsdoctor/types");
42
43
  const logger_namespaceObject = require("@rsdoctor/utils/logger");
43
- const compat_namespaceObject = require("es-toolkit/compat");
44
44
  const external_path_namespaceObject = require("path");
45
45
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
46
+ function safeCloneDeep(value, visited = new WeakMap()) {
47
+ if (null == value) return value;
48
+ if ('object' != typeof value) return value;
49
+ if (value instanceof Date) return new Date(value.getTime());
50
+ if (value instanceof RegExp) return new RegExp(value.source, value.flags);
51
+ if (visited.has(value)) return visited.get(value);
52
+ if (Array.isArray(value)) {
53
+ const len = value.length;
54
+ const cloned = new Array(len);
55
+ visited.set(value, cloned);
56
+ for(let i = 0; i < len; i++)cloned[i] = safeCloneDeep(value[i], visited);
57
+ return cloned;
58
+ }
59
+ const cloned = {};
60
+ visited.set(value, cloned);
61
+ const ownPropertyNames = Object.getOwnPropertyNames(value);
62
+ const ownSymbols = Object.getOwnPropertySymbols(value);
63
+ const enumerableKeys = Object.keys(value);
64
+ const enumerableKeysSet = new Set(enumerableKeys);
65
+ const obj = value;
66
+ for(let i = 0; i < enumerableKeys.length; i++){
67
+ const key = enumerableKeys[i];
68
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
69
+ if (!descriptor || !descriptor.get || descriptor.set) try {
70
+ const propValue = obj[key];
71
+ cloned[key] = safeCloneDeep(propValue, visited);
72
+ } catch {
73
+ continue;
74
+ }
75
+ }
76
+ for(let i = 0; i < ownPropertyNames.length; i++){
77
+ const key = ownPropertyNames[i];
78
+ if (enumerableKeysSet.has(key)) continue;
79
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
80
+ if (descriptor) {
81
+ if (!descriptor.get || descriptor.set) {
82
+ if (void 0 !== descriptor.set) try {
83
+ const propValue = obj[key];
84
+ cloned[key] = safeCloneDeep(propValue, visited);
85
+ } catch {
86
+ continue;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ for(let i = 0; i < ownSymbols.length; i++){
92
+ const key = ownSymbols[i];
93
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
94
+ if (descriptor) {
95
+ if (!descriptor.get || descriptor.set) {
96
+ if (descriptor.enumerable || void 0 !== descriptor.set) try {
97
+ const propValue = obj[key];
98
+ cloned[key] = safeCloneDeep(propValue, visited);
99
+ } catch {
100
+ continue;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ return cloned;
106
+ }
46
107
  function processCompilerConfig(config) {
47
- const { plugins, infrastructureLogging, ...rest } = config;
48
- const _rest = (0, compat_namespaceObject.cloneDeep)(rest);
108
+ const { plugins, infrastructureLogging: _infrastructureLogging, ...rest } = config;
109
+ const _rest = safeCloneDeep(rest);
49
110
  if (_rest.module?.defaultRules) (0, plugins_namespaceObject.makeRulesSerializable)(_rest.module.defaultRules);
50
111
  if (_rest.module?.rules) (0, plugins_namespaceObject.makeRulesSerializable)(_rest.module.rules);
51
112
  return {
@@ -71,9 +132,11 @@ async function handleBriefModeReport(sdk, options, disableClientServer) {
71
132
  }
72
133
  exports.handleBriefModeReport = __webpack_exports__.handleBriefModeReport;
73
134
  exports.processCompilerConfig = __webpack_exports__.processCompilerConfig;
135
+ exports.safeCloneDeep = __webpack_exports__.safeCloneDeep;
74
136
  for(var __rspack_i in __webpack_exports__)if (-1 === [
75
137
  "handleBriefModeReport",
76
- "processCompilerConfig"
138
+ "processCompilerConfig",
139
+ "safeCloneDeep"
77
140
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
78
141
  Object.defineProperty(exports, '__esModule', {
79
142
  value: true
@@ -1,4 +1,9 @@
1
1
  import type { Configuration } from '@rspack/core';
2
+ /**
3
+ * Safe cloneDeep implementation that skips read-only properties (getters without setters)
4
+ * to avoid errors when cloning objects like AppContext that have read-only properties
5
+ */
6
+ export declare function safeCloneDeep<T>(value: T, visited?: WeakMap<WeakKey, any>): T;
2
7
  /**
3
8
  * Process compiler configuration to make it serializable
4
9
  */
@@ -4,11 +4,71 @@ import { openBrowser } from "@rsdoctor/sdk";
4
4
  import { makeRulesSerializable } from "@rsdoctor/core/plugins";
5
5
  import { SDK } from "@rsdoctor/types";
6
6
  import { chalk } from "@rsdoctor/utils/logger";
7
- import { cloneDeep } from "es-toolkit/compat";
8
7
  import path from "path";
8
+ function safeCloneDeep(value, visited = new WeakMap()) {
9
+ if (null == value) return value;
10
+ if ('object' != typeof value) return value;
11
+ if (value instanceof Date) return new Date(value.getTime());
12
+ if (value instanceof RegExp) return new RegExp(value.source, value.flags);
13
+ if (visited.has(value)) return visited.get(value);
14
+ if (Array.isArray(value)) {
15
+ const len = value.length;
16
+ const cloned = new Array(len);
17
+ visited.set(value, cloned);
18
+ for(let i = 0; i < len; i++)cloned[i] = safeCloneDeep(value[i], visited);
19
+ return cloned;
20
+ }
21
+ const cloned = {};
22
+ visited.set(value, cloned);
23
+ const ownPropertyNames = Object.getOwnPropertyNames(value);
24
+ const ownSymbols = Object.getOwnPropertySymbols(value);
25
+ const enumerableKeys = Object.keys(value);
26
+ const enumerableKeysSet = new Set(enumerableKeys);
27
+ const obj = value;
28
+ for(let i = 0; i < enumerableKeys.length; i++){
29
+ const key = enumerableKeys[i];
30
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
31
+ if (!descriptor || !descriptor.get || descriptor.set) try {
32
+ const propValue = obj[key];
33
+ cloned[key] = safeCloneDeep(propValue, visited);
34
+ } catch {
35
+ continue;
36
+ }
37
+ }
38
+ for(let i = 0; i < ownPropertyNames.length; i++){
39
+ const key = ownPropertyNames[i];
40
+ if (enumerableKeysSet.has(key)) continue;
41
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
42
+ if (descriptor) {
43
+ if (!descriptor.get || descriptor.set) {
44
+ if (void 0 !== descriptor.set) try {
45
+ const propValue = obj[key];
46
+ cloned[key] = safeCloneDeep(propValue, visited);
47
+ } catch {
48
+ continue;
49
+ }
50
+ }
51
+ }
52
+ }
53
+ for(let i = 0; i < ownSymbols.length; i++){
54
+ const key = ownSymbols[i];
55
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
56
+ if (descriptor) {
57
+ if (!descriptor.get || descriptor.set) {
58
+ if (descriptor.enumerable || void 0 !== descriptor.set) try {
59
+ const propValue = obj[key];
60
+ cloned[key] = safeCloneDeep(propValue, visited);
61
+ } catch {
62
+ continue;
63
+ }
64
+ }
65
+ }
66
+ }
67
+ return cloned;
68
+ }
9
69
  function processCompilerConfig(config) {
10
- const { plugins, infrastructureLogging, ...rest } = config;
11
- const _rest = cloneDeep(rest);
70
+ const { plugins, infrastructureLogging: _infrastructureLogging, ...rest } = config;
71
+ const _rest = safeCloneDeep(rest);
12
72
  if (_rest.module?.defaultRules) makeRulesSerializable(_rest.module.defaultRules);
13
73
  if (_rest.module?.rules) makeRulesSerializable(_rest.module.rules);
14
74
  return {
@@ -32,4 +92,4 @@ async function handleBriefModeReport(sdk, options, disableClientServer) {
32
92
  }
33
93
  }
34
94
  }
35
- export { handleBriefModeReport, processCompilerConfig };
95
+ export { handleBriefModeReport, processCompilerConfig, safeCloneDeep };
@@ -33,7 +33,7 @@ export interface NativePluginConfig {
33
33
  export interface RsdoctorRspackPluginExperiments {
34
34
  /**
35
35
  * Whether to enable the native plugin to improve the performance.
36
- * @default false
36
+ * @default true
37
37
  */
38
38
  enableNativePlugin?: boolean;
39
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdoctor/core",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/rsdoctor",
@@ -62,21 +62,21 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "browserslist-load-config": "^1.0.1",
65
- "@rsbuild/plugin-check-syntax": "1.5.0",
65
+ "@rsbuild/plugin-check-syntax": "1.6.0",
66
66
  "enhanced-resolve": "5.12.0",
67
- "es-toolkit": "^1.41.0",
67
+ "es-toolkit": "^1.43.0",
68
68
  "filesize": "^10.1.6",
69
69
  "fs-extra": "^11.1.1",
70
70
  "semver": "^7.7.3",
71
71
  "source-map": "^0.7.6",
72
- "@rsdoctor/graph": "1.4.0",
73
- "@rsdoctor/sdk": "1.4.0",
74
- "@rsdoctor/types": "1.4.0",
75
- "@rsdoctor/utils": "1.4.0"
72
+ "@rsdoctor/graph": "1.5.0",
73
+ "@rsdoctor/types": "1.5.0",
74
+ "@rsdoctor/sdk": "1.5.0",
75
+ "@rsdoctor/utils": "1.5.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "axios": "^1.13.2",
79
- "@rspack/core": "1.6.8",
79
+ "@rspack/core": "1.7.1",
80
80
  "@types/fs-extra": "^11.0.4",
81
81
  "@types/node": "^22.8.1",
82
82
  "@types/node-fetch": "^2.6.13",