@rsdoctor/core 1.5.1 → 1.5.2

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.
@@ -41,10 +41,12 @@ const compat_namespaceObject = require("es-toolkit/compat");
41
41
  const external_filesize_namespaceObject = require("filesize");
42
42
  const ruleUtils_namespaceObject = require("@rsdoctor/utils/ruleUtils");
43
43
  const external_path_namespaceObject = require("path");
44
+ const types_namespaceObject = require("@rsdoctor/types");
44
45
  const logger_namespaceObject = require("@rsdoctor/utils/logger");
45
46
  const parseBundle = (bundlePath, modulesData)=>{
46
47
  if (bundlePath.indexOf('.worker.') > 0) return {};
47
- if ('.js' !== (0, external_path_namespaceObject.extname)(bundlePath)) return {};
48
+ const ext = (0, external_path_namespaceObject.extname)(bundlePath);
49
+ if (!types_namespaceObject.Constants.JSExtensions.includes(ext)) return {};
48
50
  let content = external_fs_default().readFileSync(bundlePath, 'utf8');
49
51
  const tagCache = new Map();
50
52
  const sourceMapRegex = /\/\/# sourceMappingURL=[^\n]*$/m;
@@ -5,10 +5,12 @@ import { find, mapValues } from "es-toolkit/compat";
5
5
  import { filesize } from "filesize";
6
6
  import { parser } from "@rsdoctor/utils/ruleUtils";
7
7
  import { extname } from "path";
8
+ import { Constants } from "@rsdoctor/types";
8
9
  import { logger } from "@rsdoctor/utils/logger";
9
10
  const parseBundle = (bundlePath, modulesData)=>{
10
11
  if (bundlePath.indexOf('.worker.') > 0) return {};
11
- if ('.js' !== extname(bundlePath)) return {};
12
+ const ext = extname(bundlePath);
13
+ if (!Constants.JSExtensions.includes(ext)) return {};
12
14
  let content = fs.readFileSync(bundlePath, 'utf8');
13
15
  const tagCache = new Map();
14
16
  const sourceMapRegex = /\/\/# sourceMappingURL=[^\n]*$/m;
@@ -154,7 +154,7 @@ async function handleAfterEmitAssets(compilation, _this, sourceMapFilenameRegex,
154
154
  if (outputPath && 'string' == typeof outputPath) sourceMapPath = (0, external_path_namespaceObject.resolve)(outputPath, sourceMapAsset.name);
155
155
  }
156
156
  } else {
157
- if (assetName && 'string' == typeof assetName && (assetName.endsWith('.js') || assetName.endsWith('.css'))) _this.assetsWithoutSourceMap.add(assetName);
157
+ if (assetName && 'string' == typeof assetName && (assetName.endsWith('.js') || assetName.endsWith('.bundle') || assetName.endsWith('.css'))) _this.assetsWithoutSourceMap.add(assetName);
158
158
  continue;
159
159
  }
160
160
  }
@@ -237,7 +237,7 @@ function parseAsset(asset, assets, type) {
237
237
  };
238
238
  }
239
239
  assetLinesCodeList = bundledCode.split(/\r?\n/);
240
- } else if ('js/css' === type && (assetName.endsWith('.js') || assetName.endsWith('.css'))) {
240
+ } else if ('js/css' === type && (assetName.endsWith('.js') || assetName.endsWith('.bundle') || assetName.endsWith('.css'))) {
241
241
  assetContent = asset.source?.source?.() || '';
242
242
  assetLinesCodeList = assetContent.split(/\r?\n/);
243
243
  map = asset.source?.sourceAndMap?.()?.map || null;
@@ -124,7 +124,7 @@ async function handleAfterEmitAssets(compilation, _this, sourceMapFilenameRegex,
124
124
  if (outputPath && 'string' == typeof outputPath) sourceMapPath = resolve(outputPath, sourceMapAsset.name);
125
125
  }
126
126
  } else {
127
- if (assetName && 'string' == typeof assetName && (assetName.endsWith('.js') || assetName.endsWith('.css'))) _this.assetsWithoutSourceMap.add(assetName);
127
+ if (assetName && 'string' == typeof assetName && (assetName.endsWith('.js') || assetName.endsWith('.bundle') || assetName.endsWith('.css'))) _this.assetsWithoutSourceMap.add(assetName);
128
128
  continue;
129
129
  }
130
130
  }
@@ -207,7 +207,7 @@ function parseAsset(asset, assets, type) {
207
207
  };
208
208
  }
209
209
  assetLinesCodeList = bundledCode.split(/\r?\n/);
210
- } else if ('js/css' === type && (assetName.endsWith('.js') || assetName.endsWith('.css'))) {
210
+ } else if ('js/css' === type && (assetName.endsWith('.js') || assetName.endsWith('.bundle') || assetName.endsWith('.css'))) {
211
211
  assetContent = asset.source?.source?.() || '';
212
212
  assetLinesCodeList = assetContent.split(/\r?\n/);
213
213
  map = asset.source?.sourceAndMap?.()?.map || null;
@@ -55,7 +55,7 @@ const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
55
55
  },
56
56
  async check ({ chunkGraph, report, ruleConfig, root, configs }) {
57
57
  for (const asset of chunkGraph.getAssets()){
58
- if ('.js' !== external_path_default().extname(asset.path)) continue;
58
+ if ('.js' !== external_path_default().extname(asset.path) && '.bundle' !== external_path_default().extname(asset.path)) continue;
59
59
  const browserslistConfig = (0, external_browserslist_load_config_namespaceObject.loadConfig)({
60
60
  path: root,
61
61
  env: 'production'
@@ -19,7 +19,7 @@ const rule = defineRule(()=>({
19
19
  },
20
20
  async check ({ chunkGraph, report, ruleConfig, root, configs }) {
21
21
  for (const asset of chunkGraph.getAssets()){
22
- if ('.js' !== path.extname(asset.path)) continue;
22
+ if ('.js' !== path.extname(asset.path) && '.bundle' !== path.extname(asset.path)) continue;
23
23
  const browserslistConfig = loadConfig({
24
24
  path: root,
25
25
  env: 'production'
@@ -31,12 +31,14 @@ const external_default_import_check_index_cjs_namespaceObject = require("./defau
31
31
  const external_loader_performance_optimization_index_cjs_namespaceObject = require("./loader-performance-optimization/index.cjs");
32
32
  const external_ecma_version_check_index_cjs_namespaceObject = require("./ecma-version-check/index.cjs");
33
33
  const external_cross_chunks_package_index_cjs_namespaceObject = require("./cross-chunks-package/index.cjs");
34
+ const external_module_mixed_chunks_index_cjs_namespaceObject = require("./module-mixed-chunks/index.cjs");
34
35
  const rules = [
35
36
  index_cjs_namespaceObject.rule,
36
37
  external_default_import_check_index_cjs_namespaceObject.rule,
37
38
  external_loader_performance_optimization_index_cjs_namespaceObject.rule,
38
39
  external_ecma_version_check_index_cjs_namespaceObject.rule,
39
- external_cross_chunks_package_index_cjs_namespaceObject.rule
40
+ external_cross_chunks_package_index_cjs_namespaceObject.rule,
41
+ external_module_mixed_chunks_index_cjs_namespaceObject.rule
40
42
  ];
41
43
  exports.rules = __webpack_exports__.rules;
42
44
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -1 +1 @@
1
- export declare const rules: (import("@rsdoctor/types/dist/linter").RuleData<import("./duplicate-package/index.js").Config, "duplicate-package"> | import("@rsdoctor/types/dist/linter").RuleData<import("./default-import-check/index.js").Config, "default-import-check"> | import("@rsdoctor/types/dist/linter").RuleData<import("./loader-performance-optimization/index.js").Config, "loader-performance-optimization"> | import("@rsdoctor/types/dist/linter").RuleData<import("./ecma-version-check/index.js").Config, "ecma-version-check"> | import("@rsdoctor/types/dist/linter").RuleData<import("./cross-chunks-package/index.js").Config, "cross-chunks-package">)[];
1
+ export declare const rules: (import("@rsdoctor/types/dist/linter").RuleData<import("./duplicate-package/index.js").Config, "duplicate-package"> | import("@rsdoctor/types/dist/linter").RuleData<import("./default-import-check/index.js").Config, "default-import-check"> | import("@rsdoctor/types/dist/linter").RuleData<import("./loader-performance-optimization/index.js").Config, "loader-performance-optimization"> | import("@rsdoctor/types/dist/linter").RuleData<import("./ecma-version-check/index.js").Config, "ecma-version-check"> | import("@rsdoctor/types/dist/linter").RuleData<import("./cross-chunks-package/index.js").Config, "cross-chunks-package"> | import("@rsdoctor/types/dist/linter").RuleData<import("./module-mixed-chunks/index.js").Config, "module-mixed-chunks">)[];
@@ -5,11 +5,13 @@ import { rule as index_js_rule } from "./default-import-check/index.js";
5
5
  import { rule as external_loader_performance_optimization_index_js_rule } from "./loader-performance-optimization/index.js";
6
6
  import { rule as external_ecma_version_check_index_js_rule } from "./ecma-version-check/index.js";
7
7
  import { rule as external_cross_chunks_package_index_js_rule } from "./cross-chunks-package/index.js";
8
+ import { rule as external_module_mixed_chunks_index_js_rule } from "./module-mixed-chunks/index.js";
8
9
  const rules = [
9
10
  rule,
10
11
  index_js_rule,
11
12
  external_loader_performance_optimization_index_js_rule,
12
13
  external_ecma_version_check_index_js_rule,
13
- external_cross_chunks_package_index_js_rule
14
+ external_cross_chunks_package_index_js_rule,
15
+ external_module_mixed_chunks_index_js_rule
14
16
  ];
15
17
  export { rules };
@@ -63,7 +63,7 @@ const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
63
63
  const cwd = config.context || root;
64
64
  const nodeModulesPathRegexp = /\/node_modules\//;
65
65
  const resultMap = new Map();
66
- const loaders = loader.map((el)=>el.loaders).reduce((t, c)=>t.concat(c));
66
+ const loaders = loader.flatMap((el)=>el.loaders);
67
67
  for (const item of loader){
68
68
  const { path, ext } = item.resource;
69
69
  if ((0, external_utils_cjs_namespaceObject.match)(ext, extensions)) {
@@ -37,7 +37,7 @@ const rule = defineRule(()=>({
37
37
  const cwd = config.context || root;
38
38
  const nodeModulesPathRegexp = /\/node_modules\//;
39
39
  const resultMap = new Map();
40
- const loaders = loader.map((el)=>el.loaders).reduce((t, c)=>t.concat(c));
40
+ const loaders = loader.flatMap((el)=>el.loaders);
41
41
  for (const item of loader){
42
42
  const { path, ext } = item.resource;
43
43
  if (match(ext, extensions)) {
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ rule: ()=>rule
28
+ });
29
+ const types_namespaceObject = require("@rsdoctor/types");
30
+ const external_rule_cjs_namespaceObject = require("../../rule.cjs");
31
+ const title = 'module-mixed-chunks';
32
+ const rule = (0, external_rule_cjs_namespaceObject.defineRule)(()=>({
33
+ meta: {
34
+ code: 'E1006',
35
+ title,
36
+ category: 'bundle',
37
+ severity: types_namespaceObject.Linter.Severity.Warn,
38
+ defaultConfig: {
39
+ ignore: []
40
+ }
41
+ },
42
+ check ({ moduleGraph, report, ruleConfig }) {
43
+ const modules = moduleGraph.getModules();
44
+ for (const module of modules){
45
+ if (ruleConfig.ignore.some((pattern)=>module.path.includes(pattern))) continue;
46
+ const moduleChunks = module.getChunks();
47
+ if (0 === moduleChunks.length) continue;
48
+ const hasInitial = moduleChunks.some((chunk)=>chunk.initial);
49
+ const hasAsync = moduleChunks.some((chunk)=>!chunk.initial);
50
+ if (hasInitial && hasAsync) {
51
+ const initialChunks = moduleChunks.filter((chunk)=>chunk.initial);
52
+ const asyncChunks = moduleChunks.filter((chunk)=>!chunk.initial);
53
+ const detail = {
54
+ type: title,
55
+ module: {
56
+ id: module.id,
57
+ path: module.path,
58
+ webpackId: module.webpackId
59
+ },
60
+ initialChunks: initialChunks.map((chunk)=>({
61
+ id: chunk.id,
62
+ name: chunk.name
63
+ })),
64
+ asyncChunks: asyncChunks.map((chunk)=>({
65
+ id: chunk.id,
66
+ name: chunk.name
67
+ }))
68
+ };
69
+ const chunkNames = moduleChunks.map((chunk)=>chunk.name || `chunk-${chunk.id}`).join(', ');
70
+ const message = `Module "${module.path}" is included in both initial and async chunks: ${chunkNames}. This should be optimized to avoid code duplication.`;
71
+ report({
72
+ message,
73
+ detail
74
+ });
75
+ }
76
+ }
77
+ }
78
+ }));
79
+ exports.rule = __webpack_exports__.rule;
80
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
81
+ "rule"
82
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
83
+ Object.defineProperty(exports, '__esModule', {
84
+ value: true
85
+ });
@@ -0,0 +1,4 @@
1
+ import { Linter } from '@rsdoctor/types';
2
+ import { Config } from './types.js';
3
+ export type { Config } from './types.js';
4
+ export declare const rule: Linter.RuleData<Config, "module-mixed-chunks">;
@@ -0,0 +1,53 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
3
+ import { Linter } from "@rsdoctor/types";
4
+ import { defineRule } from "../../rule.js";
5
+ const title = 'module-mixed-chunks';
6
+ const rule = defineRule(()=>({
7
+ meta: {
8
+ code: 'E1006',
9
+ title,
10
+ category: 'bundle',
11
+ severity: Linter.Severity.Warn,
12
+ defaultConfig: {
13
+ ignore: []
14
+ }
15
+ },
16
+ check ({ moduleGraph, report, ruleConfig }) {
17
+ const modules = moduleGraph.getModules();
18
+ for (const module of modules){
19
+ if (ruleConfig.ignore.some((pattern)=>module.path.includes(pattern))) continue;
20
+ const moduleChunks = module.getChunks();
21
+ if (0 === moduleChunks.length) continue;
22
+ const hasInitial = moduleChunks.some((chunk)=>chunk.initial);
23
+ const hasAsync = moduleChunks.some((chunk)=>!chunk.initial);
24
+ if (hasInitial && hasAsync) {
25
+ const initialChunks = moduleChunks.filter((chunk)=>chunk.initial);
26
+ const asyncChunks = moduleChunks.filter((chunk)=>!chunk.initial);
27
+ const detail = {
28
+ type: title,
29
+ module: {
30
+ id: module.id,
31
+ path: module.path,
32
+ webpackId: module.webpackId
33
+ },
34
+ initialChunks: initialChunks.map((chunk)=>({
35
+ id: chunk.id,
36
+ name: chunk.name
37
+ })),
38
+ asyncChunks: asyncChunks.map((chunk)=>({
39
+ id: chunk.id,
40
+ name: chunk.name
41
+ }))
42
+ };
43
+ const chunkNames = moduleChunks.map((chunk)=>chunk.name || `chunk-${chunk.id}`).join(', ');
44
+ const message = `Module "${module.path}" is included in both initial and async chunks: ${chunkNames}. This should be optimized to avoid code duplication.`;
45
+ report({
46
+ message,
47
+ detail
48
+ });
49
+ }
50
+ }
51
+ }
52
+ }));
53
+ export { rule };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });
@@ -0,0 +1,3 @@
1
+ export interface Config {
2
+ ignore: string[];
3
+ }
@@ -0,0 +1,2 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdoctor/core",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/rsdoctor",
@@ -69,10 +69,10 @@
69
69
  "fs-extra": "^11.1.1",
70
70
  "semver": "^7.7.3",
71
71
  "source-map": "^0.7.6",
72
- "@rsdoctor/graph": "1.5.1",
73
- "@rsdoctor/sdk": "1.5.1",
74
- "@rsdoctor/utils": "1.5.1",
75
- "@rsdoctor/types": "1.5.1"
72
+ "@rsdoctor/graph": "1.5.2",
73
+ "@rsdoctor/types": "1.5.2",
74
+ "@rsdoctor/utils": "1.5.2",
75
+ "@rsdoctor/sdk": "1.5.2"
76
76
  },
77
77
  "devDependencies": {
78
78
  "axios": "^1.13.4",