@rsdoctor/core 2.0.0-alpha.1 → 2.0.0-beta.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.
Files changed (177) hide show
  1. package/dist/26.js +26174 -0
  2. package/dist/630.js +1280 -0
  3. package/dist/630.js.LICENSE.txt +7 -0
  4. package/dist/build-utils/build/chunks/assetsModules.d.ts +7 -1
  5. package/dist/build-utils/build/loader/probeLoader.d.ts +7 -2
  6. package/dist/build-utils/build/server.d.ts +1 -2
  7. package/dist/build-utils/build/utils/parseBundle.d.ts +1 -1
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +1908 -7
  10. package/dist/inner-plugins/constants.d.ts +1 -1
  11. package/dist/inner-plugins/plugins/base.d.ts +2 -2
  12. package/dist/inner-plugins/plugins/errors.d.ts +1 -0
  13. package/dist/inner-plugins/plugins/plugins.d.ts +1 -1
  14. package/dist/inner-plugins/plugins/summary.d.ts +3 -2
  15. package/dist/inner-plugins/utils/sdk.d.ts +2 -1
  16. package/dist/logger.d.ts +2 -2
  17. package/dist/probe-loader.js +2 -0
  18. package/dist/proxy-loader.d.ts +1 -0
  19. package/dist/proxy-loader.js +48 -0
  20. package/dist/rslib-runtime.js +28 -0
  21. package/dist/rspack-plugin/constants.d.ts +1 -1
  22. package/dist/rspack-plugin/multiple.d.ts +5 -3
  23. package/dist/rspack-plugin/plugin.d.ts +43 -17
  24. package/dist/rspack-plugin/session.d.ts +20 -0
  25. package/dist/rules/rules/ecma-version-check/htmlParserStub.d.ts +3 -0
  26. package/dist/rules/rules/ecma-version-check/types.d.ts +13 -2
  27. package/dist/sdk/multiple/controller.d.ts +13 -2
  28. package/dist/sdk/multiple/primary.d.ts +12 -4
  29. package/dist/sdk/server/apis/base.d.ts +1 -1
  30. package/dist/sdk/server/socket/api.d.ts +1 -1
  31. package/dist/sdk/utils/date.d.ts +1 -0
  32. package/dist/types/loader.d.ts +1 -1
  33. package/package.json +23 -117
  34. package/dist/build-utils/build/chunks/assetsModules.js +0 -9
  35. package/dist/build-utils/build/chunks/index.js +0 -3
  36. package/dist/build-utils/build/chunks/rspack/transform.js +0 -44
  37. package/dist/build-utils/build/envinfo.js +0 -60
  38. package/dist/build-utils/build/file/cache.js +0 -24
  39. package/dist/build-utils/build/file/index.js +0 -5
  40. package/dist/build-utils/build/file/sharding.js +0 -38
  41. package/dist/build-utils/build/index.js +0 -12
  42. package/dist/build-utils/build/json.js +0 -67
  43. package/dist/build-utils/build/loader/index.js +0 -3
  44. package/dist/build-utils/build/loader/probeLoader.js +0 -44
  45. package/dist/build-utils/build/loader/probeLoaderPlugin.js +0 -32
  46. package/dist/build-utils/build/module-graph/index.js +0 -2
  47. package/dist/build-utils/build/module-graph/parser.js +0 -13
  48. package/dist/build-utils/build/module-graph/rspack/transform.js +0 -111
  49. package/dist/build-utils/build/module-graph/utils.js +0 -60
  50. package/dist/build-utils/build/process.js +0 -18
  51. package/dist/build-utils/build/server.js +0 -107
  52. package/dist/build-utils/build/utils/index.js +0 -4
  53. package/dist/build-utils/build/utils/loader.js +0 -267
  54. package/dist/build-utils/build/utils/parseBundle.js +0 -238
  55. package/dist/build-utils/build/utils/plugin.js +0 -21
  56. package/dist/build-utils/index.js +0 -13
  57. package/dist/collection.d.ts +0 -1
  58. package/dist/collection.js +0 -2
  59. package/dist/common/file.js +0 -8
  60. package/dist/common/global-config.js +0 -33
  61. package/dist/common/index.d.ts +0 -4
  62. package/dist/common/index.js +0 -6
  63. package/dist/common-browser.d.ts +0 -1
  64. package/dist/common-browser.js +0 -2
  65. package/dist/error/error.js +0 -143
  66. package/dist/error/index.js +0 -3
  67. package/dist/error/transform.js +0 -138
  68. package/dist/error/utils.js +0 -23
  69. package/dist/graph/index.d.ts +0 -1
  70. package/dist/graph/index.js +0 -2
  71. package/dist/inner-plugins/constants.js +0 -19
  72. package/dist/inner-plugins/index.js +0 -3
  73. package/dist/inner-plugins/loaders/proxy.js +0 -65
  74. package/dist/inner-plugins/plugins/base.js +0 -20
  75. package/dist/inner-plugins/plugins/bundle.js +0 -63
  76. package/dist/inner-plugins/plugins/ensureModulesChunkGraph.js +0 -74
  77. package/dist/inner-plugins/plugins/errors.js +0 -65
  78. package/dist/inner-plugins/plugins/index.js +0 -11
  79. package/dist/inner-plugins/plugins/loader.js +0 -108
  80. package/dist/inner-plugins/plugins/plugins.js +0 -40
  81. package/dist/inner-plugins/plugins/progress.js +0 -35
  82. package/dist/inner-plugins/plugins/resolver.js +0 -57
  83. package/dist/inner-plugins/plugins/rspack.js +0 -99
  84. package/dist/inner-plugins/plugins/rules.js +0 -64
  85. package/dist/inner-plugins/plugins/sourcemapTool.js +0 -230
  86. package/dist/inner-plugins/plugins/summary.js +0 -92
  87. package/dist/inner-plugins/utils/circleDetect.js +0 -16
  88. package/dist/inner-plugins/utils/config.js +0 -141
  89. package/dist/inner-plugins/utils/index.js +0 -8
  90. package/dist/inner-plugins/utils/loader.js +0 -134
  91. package/dist/inner-plugins/utils/normalize-config.js +0 -77
  92. package/dist/inner-plugins/utils/openBrowser.js +0 -55
  93. package/dist/inner-plugins/utils/plugin-common.js +0 -94
  94. package/dist/inner-plugins/utils/plugin.js +0 -70
  95. package/dist/inner-plugins/utils/sdk.js +0 -19
  96. package/dist/logger.js +0 -51
  97. package/dist/rspack-plugin/constants.js +0 -23
  98. package/dist/rspack-plugin/index.js +0 -3
  99. package/dist/rspack-plugin/multiple.js +0 -39
  100. package/dist/rspack-plugin/plugin.js +0 -133
  101. package/dist/rule-utils/document/document.js +0 -46
  102. package/dist/rule-utils/document/index.js +0 -4
  103. package/dist/rule-utils/document/server.js +0 -13
  104. package/dist/rule-utils/document/types.js +0 -1
  105. package/dist/rule-utils/index.js +0 -3
  106. package/dist/rule-utils/parser/asserts.js +0 -105
  107. package/dist/rule-utils/parser/index.js +0 -5
  108. package/dist/rule-utils/parser/parser.js +0 -24
  109. package/dist/rule-utils/parser/types.js +0 -8
  110. package/dist/rule-utils/parser/utils.js +0 -106
  111. package/dist/rules/index.js +0 -4
  112. package/dist/rules/linter.js +0 -36
  113. package/dist/rules/rule.js +0 -101
  114. package/dist/rules/rules/cjs-require/index.js +0 -50
  115. package/dist/rules/rules/cjs-require/types.js +0 -1
  116. package/dist/rules/rules/cross-chunks-package/index.js +0 -41
  117. package/dist/rules/rules/cross-chunks-package/types.js +0 -1
  118. package/dist/rules/rules/cross-chunks-package/utils.js +0 -7
  119. package/dist/rules/rules/default-import-check/index.js +0 -83
  120. package/dist/rules/rules/default-import-check/types.js +0 -1
  121. package/dist/rules/rules/default-import-check/utils.js +0 -52
  122. package/dist/rules/rules/duplicate-package/index.js +0 -39
  123. package/dist/rules/rules/duplicate-package/types.js +0 -24
  124. package/dist/rules/rules/duplicate-package/utils.js +0 -38
  125. package/dist/rules/rules/ecma-version-check/index.js +0 -53
  126. package/dist/rules/rules/ecma-version-check/types.js +0 -1
  127. package/dist/rules/rules/ecma-version-check/utils.js +0 -6
  128. package/dist/rules/rules/esm-resolved-to-cjs/index.js +0 -193
  129. package/dist/rules/rules/esm-resolved-to-cjs/types.js +0 -1
  130. package/dist/rules/rules/index.js +0 -22
  131. package/dist/rules/rules/loader-performance-optimization/index.js +0 -86
  132. package/dist/rules/rules/loader-performance-optimization/types.js +0 -1
  133. package/dist/rules/rules/loader-performance-optimization/utils.js +0 -10
  134. package/dist/rules/rules/module-mixed-chunks/index.js +0 -52
  135. package/dist/rules/rules/module-mixed-chunks/types.js +0 -1
  136. package/dist/rules/rules/side-effects-only-imports/index.js +0 -81
  137. package/dist/rules/rules/side-effects-only-imports/types.js +0 -1
  138. package/dist/rules/utils.js +0 -10
  139. package/dist/sdk/index.js +0 -3
  140. package/dist/sdk/multiple/controller.js +0 -42
  141. package/dist/sdk/multiple/index.js +0 -3
  142. package/dist/sdk/multiple/primary.js +0 -64
  143. package/dist/sdk/multiple/server.js +0 -14
  144. package/dist/sdk/sdk/core.js +0 -163
  145. package/dist/sdk/sdk/index.js +0 -435
  146. package/dist/sdk/sdk/types.js +0 -1
  147. package/dist/sdk/server/apis/alerts.js +0 -30
  148. package/dist/sdk/server/apis/base.js +0 -22
  149. package/dist/sdk/server/apis/bundle-diff.js +0 -51
  150. package/dist/sdk/server/apis/data.js +0 -44
  151. package/dist/sdk/server/apis/fs.js +0 -28
  152. package/dist/sdk/server/apis/graph.js +0 -116
  153. package/dist/sdk/server/apis/index.js +0 -11
  154. package/dist/sdk/server/apis/loader.js +0 -120
  155. package/dist/sdk/server/apis/plugin.js +0 -39
  156. package/dist/sdk/server/apis/project.js +0 -59
  157. package/dist/sdk/server/apis/renderer.js +0 -33
  158. package/dist/sdk/server/apis/resolver.js +0 -38
  159. package/dist/sdk/server/client.js +0 -8
  160. package/dist/sdk/server/fakeServer.js +0 -12
  161. package/dist/sdk/server/index.js +0 -292
  162. package/dist/sdk/server/json-body.js +0 -150
  163. package/dist/sdk/server/router.js +0 -83
  164. package/dist/sdk/server/security.js +0 -47
  165. package/dist/sdk/server/socket/api.js +0 -22
  166. package/dist/sdk/server/socket/index.js +0 -166
  167. package/dist/sdk/server/utils.js +0 -19
  168. package/dist/sdk/utils/base.js +0 -22
  169. package/dist/sdk/utils/constant.js +0 -4
  170. package/dist/sdk/utils/index.js +0 -4
  171. package/dist/sdk/utils/openBrowser.js +0 -53
  172. package/dist/sdk/utils/upload.js +0 -6
  173. package/dist/sdk.js +0 -2
  174. package/dist/types/index.js +0 -4
  175. package/dist/types/loader.js +0 -1
  176. package/dist/types/plugin.js +0 -1
  177. package/dist/types/rules.js +0 -1
@@ -1,193 +0,0 @@
1
- import "node:module";
2
- import fs from "fs";
3
- import path from "path";
4
- import { Linter, SDK } from "@rsdoctor/shared/types";
5
- import { defineRule } from "../../rule.js";
6
- const title = 'esm-resolved-to-cjs';
7
- function normalizePathForCompare(filePath) {
8
- const queryIndex = filePath.indexOf('?');
9
- const hashIndex = filePath.indexOf('#');
10
- const splitIndex = [
11
- queryIndex,
12
- hashIndex
13
- ].filter((index)=>index >= 0).reduce((min, index)=>Math.min(min, index), 1 / 0);
14
- const cleanPath = splitIndex === 1 / 0 ? filePath : filePath.slice(0, splitIndex);
15
- return path.normalize(cleanPath);
16
- }
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 resolveExportEntry(exports, exportKey) {
68
- if (Object.prototype.hasOwnProperty.call(exports, exportKey)) return {
69
- value: exports[exportKey],
70
- wildcard: ''
71
- };
72
- for (const [key, value] of Object.entries(exports)){
73
- const wildcard = matchPatternExportKey(key, exportKey);
74
- if (null !== wildcard) return {
75
- value,
76
- wildcard
77
- };
78
- }
79
- return null;
80
- }
81
- function resolveExportEntryForKey(exportsField, exportKey) {
82
- if (!isRecord(exportsField)) return null;
83
- if (!hasSubpathExportKeys(exportsField)) return '.' === exportKey ? {
84
- value: exportsField,
85
- wildcard: ''
86
- } : null;
87
- return resolveExportEntry(exportsField, exportKey);
88
- }
89
- function extractEsmEntries(pkgJson, pkgRoot, exportKey) {
90
- const { exports: exportsField, module: moduleField } = pkgJson;
91
- const resolvedExport = resolveExportEntryForKey(exportsField, exportKey);
92
- const entries = resolvedExport ? collectEsmTargets(resolvedExport.value, pkgRoot, resolvedExport.wildcard) : new Set();
93
- if ('.' === exportKey && 'string' == typeof moduleField) entries.add(path.resolve(pkgRoot, moduleField));
94
- return entries;
95
- }
96
- function getExportKeyFromRequest(packageName, request) {
97
- if (request === packageName) return '.';
98
- if (request.startsWith(`${packageName}/`)) return `.${request.slice(packageName.length)}`;
99
- return null;
100
- }
101
- const rule = defineRule(()=>({
102
- meta: {
103
- code: 'E1009',
104
- title: title,
105
- category: 'bundle',
106
- severity: Linter.Severity.Warn,
107
- defaultConfig: {
108
- ignore: []
109
- }
110
- },
111
- check ({ moduleGraph, packageGraph, report, ruleConfig }) {
112
- const pkgJsonCache = new Map();
113
- const realPathCache = new Map();
114
- const readPkgJson = (pkgRoot)=>{
115
- if (pkgJsonCache.has(pkgRoot)) return pkgJsonCache.get(pkgRoot);
116
- try {
117
- const raw = fs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf-8');
118
- const parsed = JSON.parse(raw);
119
- pkgJsonCache.set(pkgRoot, parsed);
120
- return parsed;
121
- } catch {
122
- pkgJsonCache.set(pkgRoot, null);
123
- return null;
124
- }
125
- };
126
- const toRealPath = (filePath)=>{
127
- const normalized = normalizePathForCompare(filePath);
128
- if (realPathCache.has(normalized)) return realPathCache.get(normalized);
129
- try {
130
- const realPath = 'function' == typeof fs.realpathSync.native ? fs.realpathSync.native(normalized) : fs.realpathSync(normalized);
131
- const normalizedRealPath = path.normalize(realPath);
132
- realPathCache.set(normalized, normalizedRealPath);
133
- return normalizedRealPath;
134
- } catch {
135
- realPathCache.set(normalized, normalized);
136
- return normalized;
137
- }
138
- };
139
- const groups = new Map();
140
- const inNodeModules = /[/\\]node_modules[/\\]/;
141
- for (const dep of moduleGraph.getDependencies()){
142
- if (dep.kind !== SDK.DependencyKind.ImportStatement || inNodeModules.test(dep.module.path) || !inNodeModules.test(dep.dependency.path) || dep.dependency.meta.strictHarmonyModule || ruleConfig.ignore.some((p)=>dep.request.includes(p))) continue;
143
- const pkg = packageGraph.getPackageByModule(dep.dependency);
144
- if (!pkg?.root) continue;
145
- const pkgJson = readPkgJson(pkg.root);
146
- if (ruleConfig.ignore.some((p)=>pkg.name.includes(p)) || !pkgJson) continue;
147
- const exportKey = getExportKeyFromRequest(pkg.name, dep.request);
148
- if (!exportKey) continue;
149
- const esmEntries = extractEsmEntries(pkgJson, pkg.root, exportKey);
150
- if (0 === esmEntries.size) continue;
151
- const esmEntryList = Array.from(esmEntries);
152
- const resolvedModuleRealPath = toRealPath(dep.dependency.path);
153
- if (isDefinitelyEsmFile(resolvedModuleRealPath)) continue;
154
- if (isDeclaredEsmEntry(resolvedModuleRealPath, esmEntryList, toRealPath)) continue;
155
- const groupKey = `${pkg.name}::${resolvedModuleRealPath}`;
156
- const issuer = {
157
- id: dep.module.id,
158
- path: dep.module.path,
159
- request: dep.request
160
- };
161
- if (groups.has(groupKey)) groups.get(groupKey).issuers.push(issuer);
162
- else groups.set(groupKey, {
163
- packageName: pkg.name,
164
- packageVersion: pkg.version,
165
- esmEntry: esmEntryList[0],
166
- resolvedModule: {
167
- id: dep.dependency.id,
168
- path: dep.dependency.path,
169
- identifier: dep.dependency.identifier
170
- },
171
- issuers: [
172
- issuer
173
- ]
174
- });
175
- }
176
- for (const group of groups.values()){
177
- const detail = {
178
- type: title,
179
- packageName: group.packageName,
180
- packageVersion: group.packageVersion,
181
- esmEntry: group.esmEntry,
182
- resolvedModule: group.resolvedModule,
183
- issuers: group.issuers
184
- };
185
- const message = `"${group.packageName}" declares an ESM entry ("${group.esmEntry}") but was resolved to CJS by ${group.issuers.length} ESM import(s). Check your bundler's \`resolve.mainFields\` or \`resolve.conditionNames\` config.`;
186
- report({
187
- message,
188
- detail
189
- });
190
- }
191
- }
192
- }));
193
- export { rule };
@@ -1 +0,0 @@
1
- import "node:module";
@@ -1,22 +0,0 @@
1
- import "node:module";
2
- import { rule } from "./duplicate-package/index.js";
3
- import { rule as index_js_rule } from "./default-import-check/index.js";
4
- import { rule as external_loader_performance_optimization_index_js_rule } from "./loader-performance-optimization/index.js";
5
- import { rule as external_ecma_version_check_index_js_rule } from "./ecma-version-check/index.js";
6
- import { rule as external_cross_chunks_package_index_js_rule } from "./cross-chunks-package/index.js";
7
- import { rule as external_module_mixed_chunks_index_js_rule } from "./module-mixed-chunks/index.js";
8
- import { rule as external_side_effects_only_imports_index_js_rule } from "./side-effects-only-imports/index.js";
9
- import { rule as external_cjs_require_index_js_rule } from "./cjs-require/index.js";
10
- import { rule as external_esm_resolved_to_cjs_index_js_rule } from "./esm-resolved-to-cjs/index.js";
11
- const rules = [
12
- rule,
13
- index_js_rule,
14
- external_loader_performance_optimization_index_js_rule,
15
- external_ecma_version_check_index_js_rule,
16
- external_cross_chunks_package_index_js_rule,
17
- external_module_mixed_chunks_index_js_rule,
18
- external_side_effects_only_imports_index_js_rule,
19
- external_cjs_require_index_js_rule,
20
- external_esm_resolved_to_cjs_index_js_rule
21
- ];
22
- export { rules };
@@ -1,86 +0,0 @@
1
- import "node:module";
2
- import { Linter } from "@rsdoctor/shared/types";
3
- import { Loader, Time } from "../../../common/index.js";
4
- import { defineRule } from "../../rule.js";
5
- import { match } from "./utils.js";
6
- const title = 'loader-performance-optimization';
7
- const rule = defineRule(()=>({
8
- meta: {
9
- code: 'E1003',
10
- title: title,
11
- category: 'compile',
12
- severity: Linter.Severity.Warn,
13
- defaultConfig: {
14
- ignore: [],
15
- threshold: 5000,
16
- extensions: [
17
- 'js',
18
- 'css',
19
- 'jpg',
20
- 'jpeg',
21
- 'png',
22
- 'gif',
23
- 'webp',
24
- 'svg'
25
- ]
26
- }
27
- },
28
- check ({ loader, configs, root, ruleConfig, report }) {
29
- const { extensions, ignore = [], threshold = 5000 } = ruleConfig;
30
- if (!extensions || extensions?.length === 0) return;
31
- if (0 === loader.length) return;
32
- const { config } = configs.find((e)=>'rspack' === e.name) || {
33
- config: void 0
34
- };
35
- if (!config) return;
36
- const cwd = config.context || root;
37
- const nodeModulesPathRegexp = /\/node_modules\//;
38
- const resultMap = new Map();
39
- const loaders = loader.flatMap((el)=>el.loaders);
40
- for (const item of loader){
41
- const { path, ext } = item.resource;
42
- if (match(ext, extensions)) {
43
- if (nodeModulesPathRegexp.test(path) || !path.startsWith(cwd)) item.loaders.forEach((el)=>{
44
- if (match(el.loader, ignore)) return;
45
- const costs = Loader.getLoaderCosts(el, loaders);
46
- const v = {
47
- ...el,
48
- __resource__: item.resource,
49
- __costs__: costs
50
- };
51
- if (resultMap.has(el.loader)) resultMap.get(el.loader).push(v);
52
- else resultMap.set(el.loader, [
53
- v
54
- ]);
55
- });
56
- }
57
- }
58
- const sum = (arr)=>{
59
- const v1 = arr.reduce((t, c)=>t + c.__costs__, 0);
60
- const v2 = Math.max.apply(null, arr.map((e)=>e.endAt)) - Math.min.apply(arr.map((e)=>e.startAt));
61
- if (v2 >= v1 || v2 === -1 / 0) return v1;
62
- return v2;
63
- };
64
- for (const [loaderName, v] of resultMap.entries()){
65
- const nodeModulesFiles = v.filter((e)=>nodeModulesPathRegexp.test(e.__resource__.path));
66
- const nodeModulesFilesCosts = sum(nodeModulesFiles);
67
- const outofCwdFiles = v.filter((e)=>!e.__resource__.path.startsWith(cwd));
68
- const outofCwdFilesCosts = sum(outofCwdFiles);
69
- const msg = [
70
- nodeModulesFilesCosts >= threshold && `${nodeModulesFiles.length} node_modules files (costs: ${Time.formatCosts(nodeModulesFilesCosts)})`,
71
- outofCwdFilesCosts >= threshold && `${outofCwdFiles.length} outside project files (costs: ${Time.formatCosts(outofCwdFilesCosts)})`
72
- ].filter(Boolean).join(' and ');
73
- if (msg) {
74
- const message = `${loaderName} has processed ${msg}.`;
75
- report({
76
- message,
77
- detail: {
78
- description: message,
79
- type: 'link'
80
- }
81
- });
82
- }
83
- }
84
- }
85
- }));
86
- export { rule };
@@ -1 +0,0 @@
1
- import "node:module";
@@ -1,10 +0,0 @@
1
- import "node:module";
2
- function match(str, patterns) {
3
- if (0 === patterns.length) return false;
4
- return patterns.some((p)=>{
5
- if ('string' == typeof p) return str === p;
6
- if (p instanceof RegExp) return p.test(str);
7
- return false;
8
- });
9
- }
10
- export { match };
@@ -1,52 +0,0 @@
1
- import "node:module";
2
- import { Linter } from "@rsdoctor/shared/types";
3
- import { defineRule } from "../../rule.js";
4
- const title = 'module-mixed-chunks';
5
- const rule = defineRule(()=>({
6
- meta: {
7
- code: 'E1006',
8
- title: title,
9
- category: 'bundle',
10
- severity: Linter.Severity.Warn,
11
- defaultConfig: {
12
- ignore: []
13
- }
14
- },
15
- check ({ moduleGraph, report, ruleConfig }) {
16
- const modules = moduleGraph.getModules();
17
- for (const module of modules){
18
- if (ruleConfig.ignore.some((pattern)=>module.path.includes(pattern))) continue;
19
- const moduleChunks = module.getChunks();
20
- if (0 === moduleChunks.length) continue;
21
- const hasInitial = moduleChunks.some((chunk)=>chunk.initial);
22
- const hasAsync = moduleChunks.some((chunk)=>!chunk.initial);
23
- if (hasInitial && hasAsync) {
24
- const initialChunks = moduleChunks.filter((chunk)=>chunk.initial);
25
- const asyncChunks = moduleChunks.filter((chunk)=>!chunk.initial);
26
- const detail = {
27
- type: title,
28
- module: {
29
- id: module.id,
30
- path: module.path,
31
- identifier: module.identifier
32
- },
33
- initialChunks: initialChunks.map((chunk)=>({
34
- id: chunk.id,
35
- name: chunk.name
36
- })),
37
- asyncChunks: asyncChunks.map((chunk)=>({
38
- id: chunk.id,
39
- name: chunk.name
40
- }))
41
- };
42
- const chunkNames = moduleChunks.map((chunk)=>chunk.name || `chunk-${chunk.id}`).join(', ');
43
- const message = `Module "${module.path}" is included in both initial and async chunks: ${chunkNames}. This should be optimized to avoid code duplication.`;
44
- report({
45
- message,
46
- detail
47
- });
48
- }
49
- }
50
- }
51
- }));
52
- export { rule };
@@ -1 +0,0 @@
1
- import "node:module";
@@ -1,81 +0,0 @@
1
- import "node:module";
2
- import { Linter } from "@rsdoctor/shared/types";
3
- import { defineRule } from "../../rule.js";
4
- const title = 'tree-shaking-side-effects-only';
5
- function isSideEffectDependencyType(dependencyType) {
6
- return 'esm import' === dependencyType.toLowerCase();
7
- }
8
- function isImportSpecifierDependencyType(dependencyType) {
9
- return 'esm import specifier' === dependencyType.toLowerCase();
10
- }
11
- function isStyleFile(modulePath) {
12
- const normalizedPath = modulePath.split('?')[0].split('#')[0].toLowerCase();
13
- return /\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/.test(normalizedPath);
14
- }
15
- function shouldCheckModule(modulePath, include) {
16
- const isNodeModulesModule = modulePath.includes('/node_modules/');
17
- if (!isNodeModulesModule) return true;
18
- return include.some((pattern)=>modulePath.includes(pattern));
19
- }
20
- function getSideEffectsImportConnections(connections, fallbackOriginModule) {
21
- const byOrigin = new Map();
22
- for (const connection of connections){
23
- const originModule = connection.originModule ?? fallbackOriginModule;
24
- const existing = byOrigin.get(originModule);
25
- if (existing) existing.push(connection);
26
- else byOrigin.set(originModule, [
27
- connection
28
- ]);
29
- }
30
- const result = [];
31
- for (const group of byOrigin.values()){
32
- const hasEsmImport = group.some((connection)=>isSideEffectDependencyType(connection.dependencyType));
33
- const hasEsmImportSpecifier = group.some((connection)=>isImportSpecifierDependencyType(connection.dependencyType));
34
- if (hasEsmImport && !hasEsmImportSpecifier) result.push(...group.filter((connection)=>isSideEffectDependencyType(connection.dependencyType)));
35
- }
36
- return result;
37
- }
38
- const rule = defineRule(()=>({
39
- meta: {
40
- code: 'E1007',
41
- title: title,
42
- category: 'bundle',
43
- severity: Linter.Severity.Warn,
44
- defaultConfig: {
45
- ignore: [],
46
- include: []
47
- }
48
- },
49
- check ({ moduleGraph, report, ruleConfig }) {
50
- const precomputed = moduleGraph.getConnectionsOnlyImports();
51
- for (const item of precomputed){
52
- if (isStyleFile(item.modulePath)) continue;
53
- if (ruleConfig.ignore.some((pattern)=>item.modulePath.includes(pattern))) continue;
54
- if (!shouldCheckModule(item.modulePath, ruleConfig.include)) continue;
55
- const module = moduleGraph.getModuleById(item.moduleUkey);
56
- if (!module) continue;
57
- const sideEffectConnections = getSideEffectsImportConnections(item.connections, item.moduleUkey);
58
- if (!sideEffectConnections.length) continue;
59
- const detail = {
60
- type: title,
61
- module: {
62
- id: module.id,
63
- path: module.path,
64
- identifier: module.identifier
65
- },
66
- connections: sideEffectConnections.map((c)=>({
67
- originModule: c.originModule ?? module.id,
68
- dependencyType: c.dependencyType,
69
- userRequest: c.userRequest
70
- }))
71
- };
72
- const importerCount = new Set(sideEffectConnections.map((c)=>c.originModule ?? module.id)).size;
73
- const message = `Module "${item.modulePath}" is only imported for its side effects by ${importerCount} importer(s). This may indicate an unintended tree-shaking failure causing redundant bundle output.`;
74
- report({
75
- message,
76
- detail
77
- });
78
- }
79
- }
80
- }));
81
- export { rule };
@@ -1 +0,0 @@
1
- import "node:module";
@@ -1,10 +0,0 @@
1
- import "node:module";
2
- import { Linter } from "@rsdoctor/shared/types";
3
- function toSeverity(input, defaultLevel) {
4
- if ('off' === input) return Linter.Severity.Ignore;
5
- if ('on' === input) return defaultLevel;
6
- const key = `${input[0].toUpperCase()}${input.slice(1)}`;
7
- return Linter.Severity[key];
8
- }
9
- function noop() {}
10
- export { noop, toSeverity };
package/dist/sdk/index.js DELETED
@@ -1,3 +0,0 @@
1
- import "node:module";
2
- export * from "./sdk/index.js";
3
- export * from "./multiple/index.js";
@@ -1,42 +0,0 @@
1
- import "node:module";
2
- import { RsdoctorPrimarySDK } from "./primary.js";
3
- class RsdoctorSDKController {
4
- get master() {
5
- return this.slaves[0];
6
- }
7
- getLastSdk() {
8
- return this.slaves[this.slaves.length - 1];
9
- }
10
- hasName(name) {
11
- return Boolean(this.slaves.find((item)=>item.name === name));
12
- }
13
- getSeriesData(serverUrl = false) {
14
- return this.slaves.map((item)=>{
15
- const data = {
16
- name: item.name,
17
- path: item.diskManifestPath,
18
- stage: item.stage
19
- };
20
- if (serverUrl) data.origin = item.server.origin;
21
- return data;
22
- });
23
- }
24
- createSlave({ name, stage, extraConfig, type }) {
25
- const slave = new RsdoctorPrimarySDK({
26
- name,
27
- stage,
28
- controller: this,
29
- extraConfig,
30
- type
31
- });
32
- this.slaves.push(slave);
33
- this.slaves.sort((a, b)=>a.stage - b.stage);
34
- return slave;
35
- }
36
- constructor(root = process.cwd()){
37
- this.slaves = [];
38
- this.root = '';
39
- this.root = root;
40
- }
41
- }
42
- export { RsdoctorSDKController };
@@ -1,3 +0,0 @@
1
- import "node:module";
2
- export * from "./controller.js";
3
- export * from "./primary.js";
@@ -1,64 +0,0 @@
1
- import "node:module";
2
- import path from "path";
3
- import { RsdoctorSDK } from "../sdk/index.js";
4
- import { RsdoctorSlaveServer } from "./server.js";
5
- let id = 1;
6
- class RsdoctorPrimarySDK extends RsdoctorSDK {
7
- clearSwitch() {
8
- this.uploadPieces = new Promise((resolve)=>{
9
- this.finishUploadPieceSwitch = resolve;
10
- });
11
- }
12
- get isMaster() {
13
- return this.parent.master === this;
14
- }
15
- async writePieces() {
16
- const { name, parent, isMaster, outputDir, finishUploadPieceSwitch } = this;
17
- this.setOutputDir(isMaster ? outputDir : path.join(parent.master.outputDir, '.slaves', name.replace(/\s+/g, '-')));
18
- await super.writePieces(this.getStoreData());
19
- finishUploadPieceSwitch?.();
20
- }
21
- async writeManifest() {
22
- const { parent, cloudData, dependencies } = this;
23
- if (!dependencies?.length) await Promise.all(this.parent.slaves.filter((item)=>!item.dependencies?.length).map((item)=>item.uploadPieces));
24
- if (cloudData) {
25
- cloudData.name = this.name;
26
- cloudData.series = parent.getSeriesData();
27
- }
28
- const result = await super.writeManifest();
29
- this.clearSwitch();
30
- return result;
31
- }
32
- getSeriesData(serverUrl = false) {
33
- return this.parent.getSeriesData(serverUrl);
34
- }
35
- setName(name) {
36
- this._name = this.parent.hasName(name) ? `${name}-${id}` : name;
37
- }
38
- getManifestData() {
39
- const data = super.getManifestData();
40
- data.name = this.name;
41
- data.series = this.getSeriesData(true);
42
- return data;
43
- }
44
- constructor({ name, stage, controller, extraConfig, type }){
45
- super({
46
- name,
47
- root: controller.root,
48
- config: extraConfig
49
- });
50
- const lastSdk = controller.getLastSdk();
51
- const port = lastSdk ? lastSdk.server.port + 1 : extraConfig?.server?.port ?? this.server.port;
52
- this.id = id++;
53
- this.stage = 'number' == typeof stage ? stage : 1;
54
- this.extraConfig = extraConfig;
55
- this.parent = controller;
56
- this.server = new RsdoctorSlaveServer(this, port, {
57
- cors: extraConfig?.server?.cors
58
- });
59
- this.type = type;
60
- this.setName(name);
61
- this.clearSwitch();
62
- }
63
- }
64
- export { RsdoctorPrimarySDK };
@@ -1,14 +0,0 @@
1
- import "node:module";
2
- import { Server } from "../../build-utils/index.js";
3
- import { RsdoctorServer } from "../server/index.js";
4
- class RsdoctorSlaveServer extends RsdoctorServer {
5
- async openClientPage(...args) {
6
- if (this.sdk.isMaster) return super.openClientPage(...args);
7
- return Promise.resolve();
8
- }
9
- constructor(sdk, port = Server.defaultPort, config){
10
- super(sdk, port, config);
11
- this.sdk = sdk;
12
- }
13
- }
14
- export { RsdoctorSlaveServer };