@rsdoctor/core 1.5.10 → 1.5.12

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.
@@ -24,8 +24,8 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- patchNativeChunkGraph: ()=>patchNativeChunkGraph,
28
- patchNativeAssets: ()=>patchNativeAssets
27
+ patchNativeAssets: ()=>patchNativeAssets,
28
+ patchNativeChunkGraph: ()=>patchNativeChunkGraph
29
29
  });
30
30
  const graph_namespaceObject = require("@rsdoctor/graph");
31
31
  function patchNativeChunkGraph(cg, rawChunkGraph) {
@@ -25,10 +25,10 @@ var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  Chunks: ()=>index_cjs_namespaceObject,
28
- Types: ()=>external_types_index_cjs_namespaceObject,
29
- Utils: ()=>external_utils_index_cjs_namespaceObject,
30
28
  Loader: ()=>external_loader_index_cjs_namespaceObject,
31
- ModuleGraph: ()=>external_module_graph_index_cjs_namespaceObject
29
+ ModuleGraph: ()=>external_module_graph_index_cjs_namespaceObject,
30
+ Types: ()=>external_types_index_cjs_namespaceObject,
31
+ Utils: ()=>external_utils_index_cjs_namespaceObject
32
32
  });
33
33
  const index_cjs_namespaceObject = require("./chunks/index.cjs");
34
34
  const external_utils_index_cjs_namespaceObject = require("./utils/index.cjs");
@@ -33,8 +33,8 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- loaderModule: ()=>loaderModule,
37
- default: ()=>probeLoader
36
+ default: ()=>probeLoader,
37
+ loaderModule: ()=>loaderModule
38
38
  });
39
39
  const external_index_cjs_namespaceObject = require("../../index.cjs");
40
40
  const index_cjs_namespaceObject = require("../../../inner-plugins/index.cjs");
@@ -25,9 +25,9 @@ var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  extractSideEffectCodes: ()=>extractSideEffectCodes,
28
- patchNativeModuleSources: ()=>patchNativeModuleSources,
28
+ patchNativeModuleGraph: ()=>patchNativeModuleGraph,
29
29
  patchNativeModuleIds: ()=>patchNativeModuleIds,
30
- patchNativeModuleGraph: ()=>patchNativeModuleGraph
30
+ patchNativeModuleSources: ()=>patchNativeModuleSources
31
31
  });
32
32
  const graph_namespaceObject = require("@rsdoctor/graph");
33
33
  const types_namespaceObject = require("@rsdoctor/types");
@@ -24,8 +24,8 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- getExportIdentifierStatement: ()=>getExportIdentifierStatement,
28
- getDeclarationIdentifier: ()=>getDeclarationIdentifier
27
+ getDeclarationIdentifier: ()=>getDeclarationIdentifier,
28
+ getExportIdentifierStatement: ()=>getExportIdentifierStatement
29
29
  });
30
30
  const compat_namespaceObject = require("es-toolkit/compat");
31
31
  const ruleUtils_namespaceObject = require("@rsdoctor/utils/ruleUtils");
@@ -51,15 +51,15 @@ var __webpack_exports__ = {};
51
51
  (()=>{
52
52
  __webpack_require__.r(__webpack_exports__);
53
53
  __webpack_require__.d(__webpack_exports__, {
54
- extractLoaderName: ()=>extractLoaderName,
55
- mapEachRules: ()=>mapEachRules,
56
54
  addProbeLoader2Rules: ()=>addProbeLoader2Rules,
57
55
  createLoaderContextTrap: ()=>createLoaderContextTrap,
58
- isESMLoader: ()=>isESMLoader,
59
- parseQuery: ()=>parseQuery,
56
+ extractLoaderName: ()=>extractLoaderName,
60
57
  getLoaderNameMatch: ()=>getLoaderNameMatch,
58
+ isESMLoader: ()=>isESMLoader,
59
+ loadLoaderModule: ()=>loadLoaderModule,
60
+ mapEachRules: ()=>mapEachRules,
61
61
  parsePathQueryFragment: ()=>parsePathQueryFragment,
62
- loadLoaderModule: ()=>loadLoaderModule
62
+ parseQuery: ()=>parseQuery
63
63
  });
64
64
  const external_node_path_namespaceObject = require("node:path");
65
65
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
@@ -24,9 +24,9 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ interceptCompilationHooks: ()=>interceptCompilationHooks,
27
28
  interceptCompilerHooks: ()=>interceptCompilerHooks,
28
- shouldInterceptPluginHook: ()=>shouldInterceptPluginHook,
29
- interceptCompilationHooks: ()=>interceptCompilationHooks
29
+ shouldInterceptPluginHook: ()=>shouldInterceptPluginHook
30
30
  });
31
31
  const graph_namespaceObject = require("@rsdoctor/graph");
32
32
  function shouldInterceptPluginHook(hook) {
@@ -24,9 +24,9 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- raw: ()=>raw,
28
27
  default: ()=>proxy,
29
- pitch: ()=>pitch
28
+ pitch: ()=>pitch,
29
+ raw: ()=>raw
30
30
  });
31
31
  const index_cjs_namespaceObject = require("../../build-utils/build/index.cjs");
32
32
  const external_utils_index_cjs_namespaceObject = require("../utils/index.cjs");
@@ -24,9 +24,9 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- ensureModulesChunksGraphFn: ()=>ensureModulesChunksGraphFn,
28
27
  calculateNamespaceAndRegex: ()=>calculateNamespaceAndRegex,
29
- ensureDevtools: ()=>ensureDevtools
28
+ ensureDevtools: ()=>ensureDevtools,
29
+ ensureModulesChunksGraphFn: ()=>ensureModulesChunksGraphFn
30
30
  });
31
31
  const types_namespaceObject = require("@rsdoctor/types");
32
32
  const build_namespaceObject = require("@rsdoctor/utils/build");
@@ -26,9 +26,9 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  UNASSIGNED: ()=>UNASSIGNED,
28
28
  bindContextCache: ()=>bindContextCache,
29
+ collectSourceMaps: ()=>collectSourceMaps,
29
30
  handleAfterEmitAssets: ()=>handleAfterEmitAssets,
30
- handleEmitAssets: ()=>handleEmitAssets,
31
- collectSourceMaps: ()=>collectSourceMaps
31
+ handleEmitAssets: ()=>handleEmitAssets
32
32
  });
33
33
  const common_namespaceObject = require("@rsdoctor/utils/common");
34
34
  const logger_namespaceObject = require("@rsdoctor/utils/logger");
@@ -33,9 +33,9 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- normalizeUserConfig: ()=>normalizeUserConfig,
37
36
  normalizeReportType: ()=>normalizeReportType,
38
- normalizeRspackUserOptions: ()=>normalizeRspackUserOptions
37
+ normalizeRspackUserOptions: ()=>normalizeRspackUserOptions,
38
+ normalizeUserConfig: ()=>normalizeUserConfig
39
39
  });
40
40
  const types_namespaceObject = require("@rsdoctor/types");
41
41
  const logger_namespaceObject = require("@rsdoctor/utils/logger");
@@ -65,6 +65,9 @@ function getDefaultSupports() {
65
65
  gzip: true
66
66
  };
67
67
  }
68
+ function isJsonOutputEnv(value) {
69
+ return 'json' === value;
70
+ }
68
71
  function normalizeFeatures(features, mode) {
69
72
  if (Array.isArray(features)) return {
70
73
  loader: features.includes('loader'),
@@ -99,9 +102,25 @@ function isValidMode(mode) {
99
102
  ].includes(mode);
100
103
  }
101
104
  function normalizeUserConfig(config = {}) {
102
- const { linter = {}, features = {}, loaderInterceptorOptions = {}, disableClientServer: userDisableClientServer = false, sdkInstance, innerClientPath = '', output = getDefaultOutput(), supports = getDefaultSupports(), port, printLog = {
105
+ const userOutput = config.output;
106
+ const defaultOutput = getDefaultOutput();
107
+ const outputConfig = isJsonOutputEnv(process.env.RSDOCTOR_OUTPUT) ? {
108
+ reportDir: userOutput?.reportDir,
109
+ compressData: userOutput?.compressData,
110
+ mode: 'brief',
111
+ options: {
112
+ type: [
113
+ 'json'
114
+ ]
115
+ }
116
+ } : userOutput ?? defaultOutput;
117
+ const normalizedConfig = {
118
+ ...config,
119
+ output: outputConfig
120
+ };
121
+ const { linter = {}, features = {}, loaderInterceptorOptions = {}, disableClientServer: userDisableClientServer = false, sdkInstance, innerClientPath = '', output = outputConfig, supports = getDefaultSupports(), port, printLog = {
103
122
  serverUrls: true
104
- }, mode, brief } = config;
123
+ }, mode, brief } = normalizedConfig;
105
124
  const disableClientServer = 'true' === process.env.RSTEST ? false : process.env.CI ? true : userDisableClientServer;
106
125
  external_assert_default()('object' == typeof linter);
107
126
  external_assert_default()('object' == typeof features || Array.isArray(features));
@@ -26,6 +26,9 @@ function getDefaultSupports() {
26
26
  gzip: true
27
27
  };
28
28
  }
29
+ function isJsonOutputEnv(value) {
30
+ return 'json' === value;
31
+ }
29
32
  function normalizeFeatures(features, mode) {
30
33
  if (Array.isArray(features)) return {
31
34
  loader: features.includes('loader'),
@@ -60,9 +63,25 @@ function isValidMode(mode) {
60
63
  ].includes(mode);
61
64
  }
62
65
  function normalizeUserConfig(config = {}) {
63
- const { linter = {}, features = {}, loaderInterceptorOptions = {}, disableClientServer: userDisableClientServer = false, sdkInstance, innerClientPath = '', output = getDefaultOutput(), supports = getDefaultSupports(), port, printLog = {
66
+ const userOutput = config.output;
67
+ const defaultOutput = getDefaultOutput();
68
+ const outputConfig = isJsonOutputEnv(process.env.RSDOCTOR_OUTPUT) ? {
69
+ reportDir: userOutput?.reportDir,
70
+ compressData: userOutput?.compressData,
71
+ mode: 'brief',
72
+ options: {
73
+ type: [
74
+ 'json'
75
+ ]
76
+ }
77
+ } : userOutput ?? defaultOutput;
78
+ const normalizedConfig = {
79
+ ...config,
80
+ output: outputConfig
81
+ };
82
+ const { linter = {}, features = {}, loaderInterceptorOptions = {}, disableClientServer: userDisableClientServer = false, sdkInstance, innerClientPath = '', output = outputConfig, supports = getDefaultSupports(), port, printLog = {
64
83
  serverUrls: true
65
- }, mode, brief } = config;
84
+ }, mode, brief } = normalizedConfig;
66
85
  const disableClientServer = 'true' === process.env.RSTEST ? false : process.env.CI ? true : userDisableClientServer;
67
86
  assert('object' == typeof linter);
68
87
  assert('object' == typeof features || Array.isArray(features));
@@ -33,12 +33,12 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- interceptLoader: ()=>interceptLoader,
36
+ getInternalLoaderOptions: ()=>getInternalLoaderOptions,
37
37
  getLoaderOptionsWithoutInternalKeys: ()=>getLoaderOptionsWithoutInternalKeys,
38
- shouldSkipLoader: ()=>shouldSkipLoader,
38
+ getOriginLoaderModule: ()=>getOriginLoaderModule,
39
+ interceptLoader: ()=>interceptLoader,
39
40
  reportLoader: ()=>reportLoader,
40
- getInternalLoaderOptions: ()=>getInternalLoaderOptions,
41
- getOriginLoaderModule: ()=>getOriginLoaderModule
41
+ shouldSkipLoader: ()=>shouldSkipLoader
42
42
  });
43
43
  const resolver_namespaceObject = require("@rspack/resolver");
44
44
  const compat_namespaceObject = require("es-toolkit/compat");
@@ -33,9 +33,9 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
+ handleBriefModeReport: ()=>handleBriefModeReport,
36
37
  processCompilerConfig: ()=>processCompilerConfig,
37
- safeCloneDeep: ()=>safeCloneDeep,
38
- handleBriefModeReport: ()=>handleBriefModeReport
38
+ safeCloneDeep: ()=>safeCloneDeep
39
39
  });
40
40
  const sdk_namespaceObject = require("@rsdoctor/sdk");
41
41
  const plugins_namespaceObject = require("@rsdoctor/core/plugins");
@@ -24,8 +24,8 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- defineRule: ()=>defineRule,
28
- Rule: ()=>Rule
27
+ Rule: ()=>Rule,
28
+ defineRule: ()=>defineRule
29
29
  });
30
30
  const types_namespaceObject = require("@rsdoctor/types");
31
31
  const common_namespaceObject = require("@rsdoctor/utils/common");
@@ -24,11 +24,11 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- hasSameLeftInAssignStatement: ()=>hasSameLeftInAssignStatement,
28
- getSourceRangeFromTransformedOffset: ()=>getSourceRangeFromTransformedOffset,
29
27
  getDefaultImportByRequest: ()=>getDefaultImportByRequest,
30
- importDeclarationToString: ()=>importDeclarationToString,
31
- getFixData: ()=>getFixData
28
+ getFixData: ()=>getFixData,
29
+ getSourceRangeFromTransformedOffset: ()=>getSourceRangeFromTransformedOffset,
30
+ hasSameLeftInAssignStatement: ()=>hasSameLeftInAssignStatement,
31
+ importDeclarationToString: ()=>importDeclarationToString
32
32
  });
33
33
  const ruleUtils_namespaceObject = require("@rsdoctor/utils/ruleUtils");
34
34
  const common_namespaceObject = require("@rsdoctor/utils/common");
@@ -52,28 +52,103 @@ function normalizePathForCompare(filePath) {
52
52
  const cleanPath = splitIndex === 1 / 0 ? filePath : filePath.slice(0, splitIndex);
53
53
  return external_path_default().normalize(cleanPath);
54
54
  }
55
- function extractEsmEntry(pkgJson, pkgRoot) {
56
- const { exports: exportsField, module: moduleField } = pkgJson;
57
- if (null !== exportsField && 'object' == typeof exportsField) {
58
- const exports1 = exportsField;
59
- const dotEntry = exports1['.'];
60
- if (null !== dotEntry && 'object' == typeof dotEntry) {
61
- const dot = dotEntry;
62
- const importEntry = dot['import'];
63
- if ('string' == typeof importEntry) return external_path_default().resolve(pkgRoot, importEntry);
64
- if (null !== importEntry && 'object' == typeof importEntry) {
65
- const nested = importEntry['default'];
66
- if ('string' == typeof nested) return external_path_default().resolve(pkgRoot, nested);
67
- }
68
- }
69
- const topImport = exports1['import'];
70
- if ('string' == typeof topImport) return external_path_default().resolve(pkgRoot, topImport);
71
- if (null !== topImport && 'object' == typeof topImport) {
72
- const nested = topImport['default'];
73
- if ('string' == typeof nested) return external_path_default().resolve(pkgRoot, nested);
74
- }
55
+ function isDefinitelyEsmFile(filePath) {
56
+ return '.mjs' === external_path_default().extname(normalizePathForCompare(filePath));
57
+ }
58
+ function isDeclaredEsmEntry(filePath, esmEntries, toRealPath) {
59
+ const realPath = toRealPath(filePath);
60
+ return esmEntries.some((esmEntry)=>realPath === toRealPath(esmEntry));
61
+ }
62
+ function isRecord(value) {
63
+ return null !== value && 'object' == typeof value && !Array.isArray(value);
64
+ }
65
+ function substituteExportPattern(target, wildcard) {
66
+ return target.replace(/\*/g, wildcard);
67
+ }
68
+ function toPackagePath(pkgRoot, target, wildcard) {
69
+ return external_path_default().resolve(pkgRoot, substituteExportPattern(target, wildcard));
70
+ }
71
+ function collectStringTargets(value, wildcard) {
72
+ if ('string' == typeof value) return [
73
+ substituteExportPattern(value, wildcard)
74
+ ];
75
+ if (Array.isArray(value)) return value.flatMap((item)=>collectStringTargets(item, wildcard));
76
+ if (!isRecord(value)) return [];
77
+ return Object.values(value).flatMap((child)=>collectStringTargets(child, wildcard));
78
+ }
79
+ function collectEsmTargets(exportEntry, pkgRoot, wildcard) {
80
+ const entries = new Set();
81
+ const addTargets = (value)=>{
82
+ for (const target of collectStringTargets(value, wildcard))entries.add(toPackagePath(pkgRoot, target, ''));
83
+ };
84
+ const visit = (value)=>{
85
+ if ('string' == typeof value || Array.isArray(value)) return void addTargets(value);
86
+ if (!isRecord(value)) return;
87
+ addTargets(value['import']);
88
+ addTargets(value['module']);
89
+ for (const child of Object.values(value))if (isRecord(child) || Array.isArray(child)) visit(child);
90
+ };
91
+ visit(exportEntry);
92
+ return entries;
93
+ }
94
+ function hasSubpathExportKeys(exports1) {
95
+ return Object.keys(exports1).some((key)=>'.' === key || key.startsWith('./'));
96
+ }
97
+ function matchPatternExportKey(patternKey, exportKey) {
98
+ const wildcardIndex = patternKey.indexOf('*');
99
+ if (wildcardIndex < 0) return null;
100
+ const prefix = patternKey.slice(0, wildcardIndex);
101
+ const suffix = patternKey.slice(wildcardIndex + 1);
102
+ if (!exportKey.startsWith(prefix) || !exportKey.endsWith(suffix)) return null;
103
+ return exportKey.slice(prefix.length, exportKey.length - suffix.length);
104
+ }
105
+ function isPatternExportKey(key) {
106
+ return key.indexOf('*') === key.lastIndexOf('*') && key.includes('*');
107
+ }
108
+ function patternKeyCompare(keyA, keyB) {
109
+ const baseLengthA = keyA.includes('*') ? keyA.indexOf('*') + 1 : keyA.length;
110
+ const baseLengthB = keyB.includes('*') ? keyB.indexOf('*') + 1 : keyB.length;
111
+ if (baseLengthA > baseLengthB) return -1;
112
+ if (baseLengthB > baseLengthA) return 1;
113
+ if (!keyA.includes('*')) return 1;
114
+ if (!keyB.includes('*')) return -1;
115
+ if (keyA.length > keyB.length) return -1;
116
+ if (keyB.length > keyA.length) return 1;
117
+ return 0;
118
+ }
119
+ function resolveExportEntry(exports1, exportKey) {
120
+ if (Object.prototype.hasOwnProperty.call(exports1, exportKey)) return {
121
+ value: exports1[exportKey],
122
+ wildcard: ''
123
+ };
124
+ const patternEntries = Object.entries(exports1).filter(([key])=>isPatternExportKey(key)).sort(([keyA], [keyB])=>patternKeyCompare(keyA, keyB));
125
+ for (const [key, value] of patternEntries){
126
+ const wildcard = matchPatternExportKey(key, exportKey);
127
+ if (null !== wildcard) return {
128
+ value,
129
+ wildcard
130
+ };
75
131
  }
76
- if ('string' == typeof moduleField) return external_path_default().resolve(pkgRoot, moduleField);
132
+ return null;
133
+ }
134
+ function resolveExportEntryForKey(exportsField, exportKey) {
135
+ if (!isRecord(exportsField)) return null;
136
+ if (!hasSubpathExportKeys(exportsField)) return '.' === exportKey ? {
137
+ value: exportsField,
138
+ wildcard: ''
139
+ } : null;
140
+ return resolveExportEntry(exportsField, exportKey);
141
+ }
142
+ function extractEsmEntries(pkgJson, pkgRoot, exportKey) {
143
+ const { exports: exportsField, module: moduleField } = pkgJson;
144
+ const resolvedExport = resolveExportEntryForKey(exportsField, exportKey);
145
+ const entries = resolvedExport ? collectEsmTargets(resolvedExport.value, pkgRoot, resolvedExport.wildcard) : new Set();
146
+ if ('.' === exportKey && 'string' == typeof moduleField) entries.add(external_path_default().resolve(pkgRoot, moduleField));
147
+ return entries;
148
+ }
149
+ function getExportKeyFromRequest(packageName, request) {
150
+ if (request === packageName) return '.';
151
+ if (request.startsWith(`${packageName}/`)) return `.${request.slice(packageName.length)}`;
77
152
  return null;
78
153
  }
79
154
  const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
@@ -121,10 +196,15 @@ const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
121
196
  const pkg = packageGraph.getPackageByModule(dep.dependency);
122
197
  if (!pkg?.root) continue;
123
198
  const pkgJson = readPkgJson(pkg.root);
124
- const esmEntry = !ruleConfig.ignore.some((p)=>pkg.name.includes(p)) && pkgJson && extractEsmEntry(pkgJson, pkg.root);
125
- if (!esmEntry) continue;
199
+ if (ruleConfig.ignore.some((p)=>pkg.name.includes(p)) || !pkgJson) continue;
200
+ const exportKey = getExportKeyFromRequest(pkg.name, dep.request);
201
+ if (!exportKey) continue;
202
+ const esmEntries = extractEsmEntries(pkgJson, pkg.root, exportKey);
203
+ if (0 === esmEntries.size) continue;
204
+ const esmEntryList = Array.from(esmEntries);
126
205
  const resolvedModuleRealPath = toRealPath(dep.dependency.path);
127
- if (resolvedModuleRealPath === toRealPath(esmEntry)) continue;
206
+ if (isDefinitelyEsmFile(resolvedModuleRealPath)) continue;
207
+ if (isDeclaredEsmEntry(resolvedModuleRealPath, esmEntryList, toRealPath)) continue;
128
208
  const groupKey = `${pkg.name}::${resolvedModuleRealPath}`;
129
209
  const issuer = {
130
210
  id: dep.module.id,
@@ -135,7 +215,7 @@ const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
135
215
  else groups.set(groupKey, {
136
216
  packageName: pkg.name,
137
217
  packageVersion: pkg.version,
138
- esmEntry,
218
+ esmEntry: esmEntryList[0],
139
219
  resolvedModule: {
140
220
  id: dep.dependency.id,
141
221
  path: dep.dependency.path,
@@ -14,28 +14,103 @@ function normalizePathForCompare(filePath) {
14
14
  const cleanPath = splitIndex === 1 / 0 ? filePath : filePath.slice(0, splitIndex);
15
15
  return path.normalize(cleanPath);
16
16
  }
17
- function extractEsmEntry(pkgJson, pkgRoot) {
18
- const { exports: exportsField, module: moduleField } = pkgJson;
19
- if (null !== exportsField && 'object' == typeof exportsField) {
20
- const exports = exportsField;
21
- const dotEntry = exports['.'];
22
- if (null !== dotEntry && 'object' == typeof dotEntry) {
23
- const dot = dotEntry;
24
- const importEntry = dot['import'];
25
- if ('string' == typeof importEntry) return path.resolve(pkgRoot, importEntry);
26
- if (null !== importEntry && 'object' == typeof importEntry) {
27
- const nested = importEntry['default'];
28
- if ('string' == typeof nested) return path.resolve(pkgRoot, nested);
29
- }
30
- }
31
- const topImport = exports['import'];
32
- if ('string' == typeof topImport) return path.resolve(pkgRoot, topImport);
33
- if (null !== topImport && 'object' == typeof topImport) {
34
- const nested = topImport['default'];
35
- if ('string' == typeof nested) return path.resolve(pkgRoot, nested);
36
- }
17
+ function isDefinitelyEsmFile(filePath) {
18
+ return '.mjs' === path.extname(normalizePathForCompare(filePath));
19
+ }
20
+ function isDeclaredEsmEntry(filePath, esmEntries, toRealPath) {
21
+ const realPath = toRealPath(filePath);
22
+ return esmEntries.some((esmEntry)=>realPath === toRealPath(esmEntry));
23
+ }
24
+ function isRecord(value) {
25
+ return null !== value && 'object' == typeof value && !Array.isArray(value);
26
+ }
27
+ function substituteExportPattern(target, wildcard) {
28
+ return target.replace(/\*/g, wildcard);
29
+ }
30
+ function toPackagePath(pkgRoot, target, wildcard) {
31
+ return path.resolve(pkgRoot, substituteExportPattern(target, wildcard));
32
+ }
33
+ function collectStringTargets(value, wildcard) {
34
+ if ('string' == typeof value) return [
35
+ substituteExportPattern(value, wildcard)
36
+ ];
37
+ if (Array.isArray(value)) return value.flatMap((item)=>collectStringTargets(item, wildcard));
38
+ if (!isRecord(value)) return [];
39
+ return Object.values(value).flatMap((child)=>collectStringTargets(child, wildcard));
40
+ }
41
+ function collectEsmTargets(exportEntry, pkgRoot, wildcard) {
42
+ const entries = new Set();
43
+ const addTargets = (value)=>{
44
+ for (const target of collectStringTargets(value, wildcard))entries.add(toPackagePath(pkgRoot, target, ''));
45
+ };
46
+ const visit = (value)=>{
47
+ if ('string' == typeof value || Array.isArray(value)) return void addTargets(value);
48
+ if (!isRecord(value)) return;
49
+ addTargets(value['import']);
50
+ addTargets(value['module']);
51
+ for (const child of Object.values(value))if (isRecord(child) || Array.isArray(child)) visit(child);
52
+ };
53
+ visit(exportEntry);
54
+ return entries;
55
+ }
56
+ function hasSubpathExportKeys(exports) {
57
+ return Object.keys(exports).some((key)=>'.' === key || key.startsWith('./'));
58
+ }
59
+ function matchPatternExportKey(patternKey, exportKey) {
60
+ const wildcardIndex = patternKey.indexOf('*');
61
+ if (wildcardIndex < 0) return null;
62
+ const prefix = patternKey.slice(0, wildcardIndex);
63
+ const suffix = patternKey.slice(wildcardIndex + 1);
64
+ if (!exportKey.startsWith(prefix) || !exportKey.endsWith(suffix)) return null;
65
+ return exportKey.slice(prefix.length, exportKey.length - suffix.length);
66
+ }
67
+ function isPatternExportKey(key) {
68
+ return key.indexOf('*') === key.lastIndexOf('*') && key.includes('*');
69
+ }
70
+ function patternKeyCompare(keyA, keyB) {
71
+ const baseLengthA = keyA.includes('*') ? keyA.indexOf('*') + 1 : keyA.length;
72
+ const baseLengthB = keyB.includes('*') ? keyB.indexOf('*') + 1 : keyB.length;
73
+ if (baseLengthA > baseLengthB) return -1;
74
+ if (baseLengthB > baseLengthA) return 1;
75
+ if (!keyA.includes('*')) return 1;
76
+ if (!keyB.includes('*')) return -1;
77
+ if (keyA.length > keyB.length) return -1;
78
+ if (keyB.length > keyA.length) return 1;
79
+ return 0;
80
+ }
81
+ function resolveExportEntry(exports, exportKey) {
82
+ if (Object.prototype.hasOwnProperty.call(exports, exportKey)) return {
83
+ value: exports[exportKey],
84
+ wildcard: ''
85
+ };
86
+ const patternEntries = Object.entries(exports).filter(([key])=>isPatternExportKey(key)).sort(([keyA], [keyB])=>patternKeyCompare(keyA, keyB));
87
+ for (const [key, value] of patternEntries){
88
+ const wildcard = matchPatternExportKey(key, exportKey);
89
+ if (null !== wildcard) return {
90
+ value,
91
+ wildcard
92
+ };
37
93
  }
38
- if ('string' == typeof moduleField) return path.resolve(pkgRoot, moduleField);
94
+ return null;
95
+ }
96
+ function resolveExportEntryForKey(exportsField, exportKey) {
97
+ if (!isRecord(exportsField)) return null;
98
+ if (!hasSubpathExportKeys(exportsField)) return '.' === exportKey ? {
99
+ value: exportsField,
100
+ wildcard: ''
101
+ } : null;
102
+ return resolveExportEntry(exportsField, exportKey);
103
+ }
104
+ function extractEsmEntries(pkgJson, pkgRoot, exportKey) {
105
+ const { exports: exportsField, module: moduleField } = pkgJson;
106
+ const resolvedExport = resolveExportEntryForKey(exportsField, exportKey);
107
+ const entries = resolvedExport ? collectEsmTargets(resolvedExport.value, pkgRoot, resolvedExport.wildcard) : new Set();
108
+ if ('.' === exportKey && 'string' == typeof moduleField) entries.add(path.resolve(pkgRoot, moduleField));
109
+ return entries;
110
+ }
111
+ function getExportKeyFromRequest(packageName, request) {
112
+ if (request === packageName) return '.';
113
+ if (request.startsWith(`${packageName}/`)) return `.${request.slice(packageName.length)}`;
39
114
  return null;
40
115
  }
41
116
  const rule = defineRule(()=>({
@@ -83,10 +158,15 @@ const rule = defineRule(()=>({
83
158
  const pkg = packageGraph.getPackageByModule(dep.dependency);
84
159
  if (!pkg?.root) continue;
85
160
  const pkgJson = readPkgJson(pkg.root);
86
- const esmEntry = !ruleConfig.ignore.some((p)=>pkg.name.includes(p)) && pkgJson && extractEsmEntry(pkgJson, pkg.root);
87
- if (!esmEntry) continue;
161
+ if (ruleConfig.ignore.some((p)=>pkg.name.includes(p)) || !pkgJson) continue;
162
+ const exportKey = getExportKeyFromRequest(pkg.name, dep.request);
163
+ if (!exportKey) continue;
164
+ const esmEntries = extractEsmEntries(pkgJson, pkg.root, exportKey);
165
+ if (0 === esmEntries.size) continue;
166
+ const esmEntryList = Array.from(esmEntries);
88
167
  const resolvedModuleRealPath = toRealPath(dep.dependency.path);
89
- if (resolvedModuleRealPath === toRealPath(esmEntry)) continue;
168
+ if (isDefinitelyEsmFile(resolvedModuleRealPath)) continue;
169
+ if (isDeclaredEsmEntry(resolvedModuleRealPath, esmEntryList, toRealPath)) continue;
90
170
  const groupKey = `${pkg.name}::${resolvedModuleRealPath}`;
91
171
  const issuer = {
92
172
  id: dep.module.id,
@@ -97,7 +177,7 @@ const rule = defineRule(()=>({
97
177
  else groups.set(groupKey, {
98
178
  packageName: pkg.name,
99
179
  packageVersion: pkg.version,
100
- esmEntry,
180
+ esmEntry: esmEntryList[0],
101
181
  resolvedModule: {
102
182
  id: dep.dependency.id,
103
183
  path: dep.dependency.path,
@@ -1 +1,2 @@
1
- export declare const rules: (import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./duplicate-package").Config, "duplicate-package"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./default-import-check").Config, "default-import-check"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./loader-performance-optimization").Config, "loader-performance-optimization"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./ecma-version-check").Config, "ecma-version-check"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./cross-chunks-package").Config, "cross-chunks-package"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./module-mixed-chunks").Config, "module-mixed-chunks"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./side-effects-only-imports").Config, "tree-shaking-side-effects-only"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./cjs-require").Config, "cjs-require"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./esm-resolved-to-cjs").Config, "esm-resolved-to-cjs">)[];
1
+ import type { Linter } from '@rsdoctor/types';
2
+ export declare const rules: Linter.RuleData[];
@@ -1 +1,2 @@
1
- export declare const rules: (import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./duplicate-package/index.js").Config, "duplicate-package"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./default-import-check/index.js").Config, "default-import-check"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./loader-performance-optimization/index.js").Config, "loader-performance-optimization"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./ecma-version-check/index.js").Config, "ecma-version-check"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./cross-chunks-package/index.js").Config, "cross-chunks-package"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./module-mixed-chunks/index.js").Config, "module-mixed-chunks"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./side-effects-only-imports/index.js").Config, "tree-shaking-side-effects-only"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./cjs-require/index.js").Config, "cjs-require"> | import("node_modules/@rsdoctor/types/dist/linter").RuleData<import("./esm-resolved-to-cjs/index.js").Config, "esm-resolved-to-cjs">)[];
1
+ import type { Linter } from '@rsdoctor/types';
2
+ export declare const rules: Linter.RuleData[];
@@ -24,8 +24,8 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- toSeverity: ()=>toSeverity,
28
- noop: ()=>noop
27
+ noop: ()=>noop,
28
+ toSeverity: ()=>toSeverity
29
29
  });
30
30
  const types_namespaceObject = require("@rsdoctor/types");
31
31
  function toSeverity(input, defaultLevel) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdoctor/core",
3
- "version": "1.5.10",
3
+ "version": "1.5.12",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/rsdoctor",
@@ -90,19 +90,19 @@
90
90
  "@rsbuild/plugin-check-syntax": "1.6.1",
91
91
  "@rspack/resolver": "0.2.8",
92
92
  "es-toolkit": "^1.45.1",
93
- "filesize": "^10.1.6",
93
+ "filesize": "^11.0.17",
94
94
  "fs-extra": "^11.1.1",
95
95
  "semver": "^7.7.4",
96
96
  "source-map": "^0.7.6",
97
- "@rsdoctor/graph": "1.5.10",
98
- "@rsdoctor/utils": "1.5.10",
99
- "@rsdoctor/sdk": "1.5.10",
100
- "@rsdoctor/types": "1.5.10"
97
+ "@rsdoctor/graph": "1.5.12",
98
+ "@rsdoctor/types": "1.5.12",
99
+ "@rsdoctor/sdk": "1.5.12",
100
+ "@rsdoctor/utils": "1.5.12"
101
101
  },
102
102
  "devDependencies": {
103
- "@rspack/core": "2.0.0",
103
+ "@rspack/core": "2.0.3",
104
104
  "@types/fs-extra": "^11.0.4",
105
- "@types/node": "^22.8.1",
105
+ "@types/node": "^24.12.3",
106
106
  "@types/node-fetch": "^2.6.13",
107
107
  "@types/semver": "^7.7.1",
108
108
  "@types/tapable": "2.3.0",
@@ -111,7 +111,7 @@
111
111
  "string-loader": "0.0.1",
112
112
  "ts-loader": "^9.5.7",
113
113
  "tslib": "2.8.1",
114
- "typescript": "^5.9.2",
114
+ "typescript": "^6.0.3",
115
115
  "webpack": "^5.105.4",
116
116
  "@scripts/test-helper": "0.1.1"
117
117
  },