@yannick-z/modulo 0.3.0 → 0.3.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.
- package/bin/modulo.js +1 -1
- package/dist/183.js +130 -0
- package/dist/740.js +793 -0
- package/dist/882.js +697 -0
- package/dist/bin/modulo.js +93 -0
- package/dist/index.js +200 -0
- package/package.json +14 -6
- package/src/bin/modulo.ts +16 -0
- package/src/config/presets.ts +1 -1
- package/src/index.ts +3 -1
- package/src/packer/auto-external-plugin.ts +153 -59
- package/src/packer/get-externals-and-tags.ts +18 -11
- package/src/packer/lib.ts +9 -6
- package/src/packer/page.ts +2 -3
- package/.vscode/extensions.json +0 -3
- package/biome.json +0 -34
- package/rslib.config.ts +0 -22
- package/template/index.html +0 -12
- package/tsconfig.json +0 -11
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
var __webpack_modules__ = {};
|
|
3
|
+
var __webpack_module_cache__ = {};
|
|
4
|
+
function __webpack_require__(moduleId) {
|
|
5
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
6
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
7
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
8
|
+
exports: {}
|
|
9
|
+
};
|
|
10
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
11
|
+
return module.exports;
|
|
12
|
+
}
|
|
13
|
+
__webpack_require__.m = __webpack_modules__;
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.d = (exports, definition)=>{
|
|
16
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: definition[key]
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
})();
|
|
22
|
+
(()=>{
|
|
23
|
+
__webpack_require__.f = {};
|
|
24
|
+
__webpack_require__.e = (chunkId)=>Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key)=>{
|
|
25
|
+
__webpack_require__.f[key](chunkId, promises);
|
|
26
|
+
return promises;
|
|
27
|
+
}, []));
|
|
28
|
+
})();
|
|
29
|
+
(()=>{
|
|
30
|
+
__webpack_require__.u = (chunkId)=>"" + chunkId + ".js";
|
|
31
|
+
})();
|
|
32
|
+
(()=>{
|
|
33
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
34
|
+
})();
|
|
35
|
+
(()=>{
|
|
36
|
+
__webpack_require__.r = (exports)=>{
|
|
37
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {
|
|
38
|
+
value: 'Module'
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(exports, '__esModule', {
|
|
41
|
+
value: true
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
(()=>{
|
|
46
|
+
var installedChunks = {
|
|
47
|
+
660: 0
|
|
48
|
+
};
|
|
49
|
+
var installChunk = (data)=>{
|
|
50
|
+
var __webpack_ids__ = data.__webpack_ids__;
|
|
51
|
+
var __webpack_modules__ = data.__webpack_modules__;
|
|
52
|
+
var __webpack_runtime__ = data.__webpack_runtime__;
|
|
53
|
+
var moduleId, chunkId, i = 0;
|
|
54
|
+
for(moduleId in __webpack_modules__)if (__webpack_require__.o(__webpack_modules__, moduleId)) __webpack_require__.m[moduleId] = __webpack_modules__[moduleId];
|
|
55
|
+
if (__webpack_runtime__) __webpack_runtime__(__webpack_require__);
|
|
56
|
+
for(; i < __webpack_ids__.length; i++){
|
|
57
|
+
chunkId = __webpack_ids__[i];
|
|
58
|
+
if (__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) installedChunks[chunkId][0]();
|
|
59
|
+
installedChunks[__webpack_ids__[i]] = 0;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
__webpack_require__.f.j = function(chunkId, promises) {
|
|
63
|
+
var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : void 0;
|
|
64
|
+
if (0 !== installedChunkData) if (installedChunkData) promises.push(installedChunkData[1]);
|
|
65
|
+
else {
|
|
66
|
+
var promise = import("../" + __webpack_require__.u(chunkId)).then(installChunk, (e)=>{
|
|
67
|
+
if (0 !== installedChunks[chunkId]) installedChunks[chunkId] = void 0;
|
|
68
|
+
throw e;
|
|
69
|
+
});
|
|
70
|
+
var promise = Promise.race([
|
|
71
|
+
promise,
|
|
72
|
+
new Promise((resolve)=>{
|
|
73
|
+
installedChunkData = installedChunks[chunkId] = [
|
|
74
|
+
resolve
|
|
75
|
+
];
|
|
76
|
+
})
|
|
77
|
+
]);
|
|
78
|
+
promises.push(installedChunkData[1] = promise);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
})();
|
|
82
|
+
__webpack_require__.e("183").then(__webpack_require__.bind(__webpack_require__, "./src/index.ts?fb01")).then((module)=>{
|
|
83
|
+
try {
|
|
84
|
+
module.exec();
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.error(e);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}).catch((e)=>{
|
|
90
|
+
console.error("\x1b[31mError: Failed to load modulo.\x1b[0m");
|
|
91
|
+
console.error(e);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
});
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
|
|
2
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
|
|
3
|
+
import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
|
|
4
|
+
import { cac } from "cac";
|
|
5
|
+
var __webpack_modules__ = {
|
|
6
|
+
"./src/tools/log.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
7
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
8
|
+
n: ()=>debug_log,
|
|
9
|
+
v: ()=>logger
|
|
10
|
+
});
|
|
11
|
+
var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:fs");
|
|
12
|
+
var node_path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("node:path");
|
|
13
|
+
var picocolors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("picocolors");
|
|
14
|
+
const logFile = node_path__WEBPACK_IMPORTED_MODULE_1__.join(process.cwd(), "modulo.debug.log");
|
|
15
|
+
let index = 0;
|
|
16
|
+
function debug_log(hint, ...params) {
|
|
17
|
+
const argv_debug = process.env.DEBUG || process.argv.includes("--debug");
|
|
18
|
+
const argv_verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|
|
19
|
+
if (!argv_debug && !argv_verbose) return;
|
|
20
|
+
const timestamp = new Date().toISOString();
|
|
21
|
+
const sn = String(index++).padStart(3, "0");
|
|
22
|
+
const logEntry = `--------------\n${sn} [${timestamp}] ${hint}\n${params.map((p)=>"object" == typeof p ? JSON.stringify(p, null, 2) : String(p)).join("\n")}\n---------------\n\n`;
|
|
23
|
+
if (argv_verbose) console.log(logEntry);
|
|
24
|
+
if (argv_debug) {
|
|
25
|
+
console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].blue(`\ndebug log ${sn}`));
|
|
26
|
+
node_fs__WEBPACK_IMPORTED_MODULE_0__.appendFileSync(logFile, logEntry);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const logger = {
|
|
30
|
+
info: (msg)=>console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].cyan(msg)),
|
|
31
|
+
success: (msg)=>console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].green(msg)),
|
|
32
|
+
warn: (msg)=>console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].yellow(msg)),
|
|
33
|
+
error: (msg)=>console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].red(msg)),
|
|
34
|
+
debug: (msg)=>{
|
|
35
|
+
if (process.env.DEBUG) console.log(picocolors__WEBPACK_IMPORTED_MODULE_2__["default"].gray(`[DEBUG] ${msg}`));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
"node:fs": function(module) {
|
|
40
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__;
|
|
41
|
+
},
|
|
42
|
+
"node:path": function(module) {
|
|
43
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__;
|
|
44
|
+
},
|
|
45
|
+
picocolors: function(module) {
|
|
46
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE_picocolors__;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var __webpack_module_cache__ = {};
|
|
50
|
+
function __webpack_require__(moduleId) {
|
|
51
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
52
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
53
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
54
|
+
exports: {}
|
|
55
|
+
};
|
|
56
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
57
|
+
return module.exports;
|
|
58
|
+
}
|
|
59
|
+
__webpack_require__.m = __webpack_modules__;
|
|
60
|
+
(()=>{
|
|
61
|
+
__webpack_require__.d = (exports, definition)=>{
|
|
62
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
get: definition[key]
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
})();
|
|
68
|
+
(()=>{
|
|
69
|
+
__webpack_require__.f = {};
|
|
70
|
+
__webpack_require__.e = (chunkId)=>Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key)=>{
|
|
71
|
+
__webpack_require__.f[key](chunkId, promises);
|
|
72
|
+
return promises;
|
|
73
|
+
}, []));
|
|
74
|
+
})();
|
|
75
|
+
(()=>{
|
|
76
|
+
__webpack_require__.u = (chunkId)=>"" + chunkId + ".js";
|
|
77
|
+
})();
|
|
78
|
+
(()=>{
|
|
79
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
80
|
+
})();
|
|
81
|
+
(()=>{
|
|
82
|
+
__webpack_require__.r = (exports)=>{
|
|
83
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {
|
|
84
|
+
value: 'Module'
|
|
85
|
+
});
|
|
86
|
+
Object.defineProperty(exports, '__esModule', {
|
|
87
|
+
value: true
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
})();
|
|
91
|
+
(()=>{
|
|
92
|
+
var installedChunks = {
|
|
93
|
+
410: 0
|
|
94
|
+
};
|
|
95
|
+
var installChunk = (data)=>{
|
|
96
|
+
var __webpack_ids__ = data.__webpack_ids__;
|
|
97
|
+
var __webpack_modules__ = data.__webpack_modules__;
|
|
98
|
+
var __webpack_runtime__ = data.__webpack_runtime__;
|
|
99
|
+
var moduleId, chunkId, i = 0;
|
|
100
|
+
for(moduleId in __webpack_modules__)if (__webpack_require__.o(__webpack_modules__, moduleId)) __webpack_require__.m[moduleId] = __webpack_modules__[moduleId];
|
|
101
|
+
if (__webpack_runtime__) __webpack_runtime__(__webpack_require__);
|
|
102
|
+
for(; i < __webpack_ids__.length; i++){
|
|
103
|
+
chunkId = __webpack_ids__[i];
|
|
104
|
+
if (__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) installedChunks[chunkId][0]();
|
|
105
|
+
installedChunks[__webpack_ids__[i]] = 0;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
__webpack_require__.f.j = function(chunkId, promises) {
|
|
109
|
+
var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : void 0;
|
|
110
|
+
if (0 !== installedChunkData) if (installedChunkData) promises.push(installedChunkData[1]);
|
|
111
|
+
else {
|
|
112
|
+
var promise = import("./" + __webpack_require__.u(chunkId)).then(installChunk, (e)=>{
|
|
113
|
+
if (0 !== installedChunks[chunkId]) installedChunks[chunkId] = void 0;
|
|
114
|
+
throw e;
|
|
115
|
+
});
|
|
116
|
+
var promise = Promise.race([
|
|
117
|
+
promise,
|
|
118
|
+
new Promise((resolve)=>{
|
|
119
|
+
installedChunkData = installedChunks[chunkId] = [
|
|
120
|
+
resolve
|
|
121
|
+
];
|
|
122
|
+
})
|
|
123
|
+
]);
|
|
124
|
+
promises.push(installedChunkData[1] = promise);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
})();
|
|
128
|
+
var log = __webpack_require__("./src/tools/log.ts");
|
|
129
|
+
var package_namespaceObject = {
|
|
130
|
+
rE: "0.3.2"
|
|
131
|
+
};
|
|
132
|
+
const cli = cac("modulo");
|
|
133
|
+
cli.command("init <target>", "Initialize modulo configuration or scripts").option("-f, --force", "Force overwrite existing files").option("--path <path>", "Specify the path to initialize").option("--preset <preset>", "Specify the preset to use").action((target, options)=>{
|
|
134
|
+
__webpack_require__.e("882").then(__webpack_require__.bind(__webpack_require__, "./src/cli/init.ts")).then(({ init_tool })=>{
|
|
135
|
+
init_tool({
|
|
136
|
+
cmd: "init",
|
|
137
|
+
target: target,
|
|
138
|
+
init: {
|
|
139
|
+
path: options.path,
|
|
140
|
+
force: options.force,
|
|
141
|
+
preset: options.preset
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
cli.command("build <target>", "Build the project for production").option("-c, --config <file>", "Use specified config file").option("-w, --watch", "Watch for changes").option("--env <env>", "Specify the environment (dev/prd)").action((target, options)=>{
|
|
147
|
+
__webpack_require__.e("740").then(__webpack_require__.bind(__webpack_require__, "./src/cli/pack-code.ts")).then(({ pack_code })=>{
|
|
148
|
+
pack_code({
|
|
149
|
+
cmd: "build",
|
|
150
|
+
target: target,
|
|
151
|
+
pack: {
|
|
152
|
+
config: options.config,
|
|
153
|
+
env: options.env || "prd",
|
|
154
|
+
watch: options.watch,
|
|
155
|
+
esm: true
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
cli.command("dev <target>", "Start development server").option("-c, --config <file>", "Use specified config file").option("--env <env>", "Specify the environment (dev/prd)").option("--debug", "Enable debug mode").action((target, options)=>{
|
|
161
|
+
if (options.debug) process.env.DEBUG = "true";
|
|
162
|
+
__webpack_require__.e("740").then(__webpack_require__.bind(__webpack_require__, "./src/cli/pack-code.ts")).then(({ pack_code })=>{
|
|
163
|
+
pack_code({
|
|
164
|
+
cmd: "dev",
|
|
165
|
+
target: target,
|
|
166
|
+
pack: {
|
|
167
|
+
config: options.config,
|
|
168
|
+
env: options.env || "dev",
|
|
169
|
+
watch: true,
|
|
170
|
+
esm: true
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
cli.command("preview <target>", "Preview the production build").option("-c, --config <file>", "Use specified config file").action((target, options)=>{
|
|
176
|
+
__webpack_require__.e("740").then(__webpack_require__.bind(__webpack_require__, "./src/cli/pack-code.ts")).then(({ pack_code })=>{
|
|
177
|
+
pack_code({
|
|
178
|
+
cmd: "preview",
|
|
179
|
+
target: target,
|
|
180
|
+
pack: {
|
|
181
|
+
config: options.config,
|
|
182
|
+
env: "prd",
|
|
183
|
+
watch: false,
|
|
184
|
+
esm: true
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
cli.help();
|
|
190
|
+
cli.version(package_namespaceObject.rE);
|
|
191
|
+
function exec() {
|
|
192
|
+
try {
|
|
193
|
+
cli.parse();
|
|
194
|
+
} catch (error) {
|
|
195
|
+
log.v.error(`Error: ${error.message}`);
|
|
196
|
+
cli.outputHelp();
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
export { exec };
|
package/package.json
CHANGED
|
@@ -2,17 +2,25 @@
|
|
|
2
2
|
"name": "@yannick-z/modulo",
|
|
3
3
|
"description": "",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.3.
|
|
6
|
-
"main": "./
|
|
5
|
+
"version": "0.3.2",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
7
|
"author": "oyangxiao",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
9
|
+
"build": "rslib build",
|
|
10
|
+
"lint": "biome lint src bin rslib.config.ts",
|
|
11
|
+
"format": "biome format --write src bin rslib.config.ts package.json biome.json",
|
|
12
|
+
"check": "biome check --write src bin rslib.config.ts package.json biome.json"
|
|
12
13
|
},
|
|
13
14
|
"bin": {
|
|
14
|
-
"modulo": "./bin/modulo.js"
|
|
15
|
+
"modulo": "./dist/bin/modulo.js"
|
|
15
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"bin",
|
|
20
|
+
"src",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
16
24
|
"dependencies": {
|
|
17
25
|
"@rsbuild/core": "^1.7.3",
|
|
18
26
|
"@rsbuild/plugin-less": "^1.6.0",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import("../index.js")
|
|
4
|
+
.then((module) => {
|
|
5
|
+
try {
|
|
6
|
+
module.exec();
|
|
7
|
+
} catch (e) {
|
|
8
|
+
console.error(e);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
.catch((e) => {
|
|
13
|
+
console.error("\x1b[31mError: Failed to load modulo.\x1b[0m");
|
|
14
|
+
console.error(e);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
});
|
package/src/config/presets.ts
CHANGED
|
@@ -10,7 +10,7 @@ export const preset_dev_server_config = {
|
|
|
10
10
|
port: 8080, // 开发页面时, dev-server服务器端口
|
|
11
11
|
proxy: {} as Record<
|
|
12
12
|
string,
|
|
13
|
-
string | { target: string; pathRewrite?: Record<string, string
|
|
13
|
+
string | { target: string; pathRewrite?: Record<string, string>; changeOrigin?: boolean; secure?: boolean }
|
|
14
14
|
>, // dev时的代理配置
|
|
15
15
|
};
|
|
16
16
|
export type DEV_SERVER_CONFIG = typeof preset_dev_server_config;
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
2
3
|
import type { ModuloArgs_Pack } from "../args/index.ts";
|
|
3
4
|
import type { GLOBAL_CONFIG } from "../config/type.ts";
|
|
4
5
|
import { getExternalsAndImportMap } from "./get-externals-and-tags.ts";
|
|
@@ -23,21 +24,39 @@ export class AutoExternalPlugin {
|
|
|
23
24
|
this.usedExternals = new Set<string>();
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
apply(compiler:
|
|
27
|
+
apply(compiler: any) {
|
|
27
28
|
compiler.hooks.compilation.tap(
|
|
28
29
|
"AutoExternalPlugin",
|
|
29
|
-
(compilation:
|
|
30
|
+
(compilation: any) => {
|
|
30
31
|
// 1. 扫描模块依赖
|
|
31
|
-
compilation.hooks.finishModules.tap("AutoExternalPlugin", (modules) => {
|
|
32
|
+
compilation.hooks.finishModules.tap("AutoExternalPlugin", (modules: any[]) => {
|
|
33
|
+
// ... (省略模块扫描逻辑,这里没有问题) ...
|
|
32
34
|
for (const module of modules) {
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
const constructorName = module.constructor.name;
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
const request = module.request;
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
const userRequest = module.userRequest;
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
const resource = module.resource;
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
const externalType = module.externalType;
|
|
45
|
+
|
|
46
|
+
// 策略 A: 检查 ExternalModule
|
|
47
|
+
// Rspack 中 ExternalModule 的 userRequest 通常是 import 的路径 (例如 'vue')
|
|
48
|
+
if (constructorName === 'ExternalModule' || externalType) {
|
|
49
|
+
const libName = request || userRequest; // 通常 request 是 'vue'
|
|
50
|
+
if (libName && this.externalLibNames.includes(libName)) {
|
|
51
|
+
this.usedExternals.add(libName);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 策略 B: 检查 module.resource 是否包含 node_modules (针对未被 external 但我们想知道是否被引用的情况 - 但这通常意味着它被打包了)
|
|
57
|
+
// 之前的逻辑保留,作为兜底,或者针对未正确 external 的情况
|
|
36
58
|
if (resource && resource.includes("node_modules")) {
|
|
37
59
|
for (const libName of this.externalLibNames) {
|
|
38
|
-
// 简单的包含匹配,更严谨的可以使用路径解析
|
|
39
|
-
// 例如: /node_modules/vue/
|
|
40
|
-
// 这里简化处理,匹配 /node_modules/<libName>/
|
|
41
60
|
if (
|
|
42
61
|
resource.includes(`/node_modules/${libName}/`) ||
|
|
43
62
|
resource.includes(`\\node_modules\\${libName}\\`)
|
|
@@ -45,66 +64,141 @@ export class AutoExternalPlugin {
|
|
|
45
64
|
this.usedExternals.add(libName);
|
|
46
65
|
}
|
|
47
66
|
}
|
|
67
|
+
} else if (resource && resource.includes("/node_modules/.pnpm/")) {
|
|
68
|
+
// 兼容 pnpm
|
|
69
|
+
for (const libName of this.externalLibNames) {
|
|
70
|
+
if (
|
|
71
|
+
resource.includes(`/node_modules/.pnpm/${libName}@`) ||
|
|
72
|
+
resource.includes(`/node_modules/.pnpm/${libName}+`) ||
|
|
73
|
+
// 某些情况下 pnpm 可能会直接链接
|
|
74
|
+
resource.includes(`/node_modules/${libName}/`)
|
|
75
|
+
) {
|
|
76
|
+
this.usedExternals.add(libName);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
48
79
|
}
|
|
49
80
|
}
|
|
50
81
|
});
|
|
51
82
|
|
|
83
|
+
// 尝试通过 compilation.hooks 访问 HtmlWebpackPlugin hooks
|
|
84
|
+
// Rsbuild 可能通过 mixin 或者其他方式将 hooks 注入到了 compilation 上
|
|
85
|
+
// 或者我们可以尝试直接使用 tapAsync 到 HtmlWebpackPlugin 的实例上,如果我们能找到它
|
|
86
|
+
|
|
87
|
+
// 终极 Hook 调试: 使用 compiler.hooks.emit 来检查 assets,看是否包含 index.html,以及内容
|
|
88
|
+
compiler.hooks.emit.tapAsync("AutoExternalPlugin", (compilation: any, cb: any) => {
|
|
89
|
+
if (process.env.DEBUG) console.log('[AutoExternalPlugin] emit hook triggered');
|
|
90
|
+
// 检查 compilation.assets
|
|
91
|
+
const assetNames = Object.keys(compilation.assets);
|
|
92
|
+
if (process.env.DEBUG) console.log('[AutoExternalPlugin] Assets:', assetNames);
|
|
93
|
+
cb();
|
|
94
|
+
});
|
|
95
|
+
|
|
52
96
|
// 2. 注入 HTML
|
|
53
|
-
|
|
54
|
-
compiler.webpack.HtmlWebpackPlugin ||
|
|
55
|
-
compiler.options.plugins.find(
|
|
56
|
-
(p: any) => p.constructor.name === "HtmlWebpackPlugin",
|
|
57
|
-
)?.constructor;
|
|
97
|
+
let HtmlWebpackPlugin: any;
|
|
58
98
|
|
|
59
|
-
|
|
99
|
+
// 优先从 compiler.options.plugins 中查找实例并获取其构造函数
|
|
100
|
+
// 这是最稳妥的方式,确保我们获取的是同一个类的构造函数
|
|
101
|
+
const htmlPluginInstance = compiler.options.plugins.find(
|
|
102
|
+
(p: any) => p && (p.constructor.name === "HtmlWebpackPlugin" || p.constructor.name === "HtmlRspackPlugin")
|
|
103
|
+
);
|
|
60
104
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (Object.keys(filteredImportMap).length === 0) return data;
|
|
80
|
-
|
|
81
|
-
let tags: any[] = [];
|
|
82
|
-
if (this.config.externalsType === "script") {
|
|
83
|
-
tags = Object.values(filteredImportMap).map((url) => ({
|
|
84
|
-
tagName: "script",
|
|
85
|
-
voidTag: false,
|
|
86
|
-
attributes: { src: url },
|
|
87
|
-
}));
|
|
88
|
-
} else {
|
|
89
|
-
tags = [
|
|
90
|
-
{
|
|
91
|
-
tagName: "script",
|
|
92
|
-
voidTag: false,
|
|
93
|
-
attributes: { type: "importmap" },
|
|
94
|
-
innerHTML: JSON.stringify(
|
|
95
|
-
{ imports: filteredImportMap },
|
|
96
|
-
null,
|
|
97
|
-
2,
|
|
98
|
-
),
|
|
99
|
-
},
|
|
100
|
-
];
|
|
105
|
+
if (htmlPluginInstance) {
|
|
106
|
+
HtmlWebpackPlugin = htmlPluginInstance.constructor;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fallback: 如果没找到实例(可能被封装了),尝试从 compiler.webpack 中获取
|
|
110
|
+
if (!HtmlWebpackPlugin) {
|
|
111
|
+
HtmlWebpackPlugin =
|
|
112
|
+
compiler.webpack.HtmlRspackPlugin ||
|
|
113
|
+
(compiler.webpack as any).HtmlWebpackPlugin;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!HtmlWebpackPlugin) {
|
|
117
|
+
// Try to import from @rspack/plugin-html
|
|
118
|
+
try {
|
|
119
|
+
HtmlWebpackPlugin = require('@rspack/plugin-html').HtmlRspackPlugin;
|
|
120
|
+
} catch (e) {
|
|
121
|
+
// ignore
|
|
101
122
|
}
|
|
123
|
+
}
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
if (!HtmlWebpackPlugin) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 确保我们拿到的确实是 HtmlWebpackPlugin 构造函数,并且它有 getHooks 方法
|
|
130
|
+
if (typeof (HtmlWebpackPlugin as any).getHooks !== 'function') {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const hooks = (HtmlWebpackPlugin as any).getHooks(compilation);
|
|
135
|
+
|
|
136
|
+
hooks.alterAssetTags.tapAsync("AutoExternalPlugin", (data: any, cb: any) => {
|
|
137
|
+
if (data.assetTags && data.assetTags.scripts) {
|
|
138
|
+
this.processTags(data, 'assetTags.scripts');
|
|
139
|
+
}
|
|
140
|
+
cb(null, data);
|
|
106
141
|
});
|
|
107
142
|
},
|
|
108
143
|
);
|
|
109
144
|
}
|
|
145
|
+
|
|
146
|
+
private processTags(data: any, targetProp: string) {
|
|
147
|
+
if (!this.config.autoExternal) {
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 重新计算 importmaps
|
|
152
|
+
const { importMap } = getExternalsAndImportMap(
|
|
153
|
+
this.args,
|
|
154
|
+
this.config.externals,
|
|
155
|
+
this.config.externalsType,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// 过滤未使用的依赖
|
|
159
|
+
const filteredImportMap = Object.fromEntries(
|
|
160
|
+
Object.entries(importMap).filter(([key]) =>
|
|
161
|
+
this.usedExternals.has(key),
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
if (Object.keys(filteredImportMap).length === 0) {
|
|
166
|
+
return data;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let tags: any[] = [];
|
|
170
|
+
if (this.config.externalsType === "script") {
|
|
171
|
+
tags = Object.values(filteredImportMap).map((url) => ({
|
|
172
|
+
tagName: "script",
|
|
173
|
+
voidTag: false,
|
|
174
|
+
attributes: {
|
|
175
|
+
src: url,
|
|
176
|
+
},
|
|
177
|
+
}));
|
|
178
|
+
} else {
|
|
179
|
+
tags = [
|
|
180
|
+
{
|
|
181
|
+
tagName: "script",
|
|
182
|
+
voidTag: false,
|
|
183
|
+
attributes: { type: "importmap" },
|
|
184
|
+
innerHTML: JSON.stringify(
|
|
185
|
+
{ imports: filteredImportMap },
|
|
186
|
+
null,
|
|
187
|
+
2,
|
|
188
|
+
),
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 插入到 head 的最前面
|
|
194
|
+
if (targetProp === 'headTags') {
|
|
195
|
+
data.headTags.unshift(...tags);
|
|
196
|
+
} else if (targetProp === 'assetTags.scripts') {
|
|
197
|
+
data.assetTags.scripts.unshift(...tags);
|
|
198
|
+
} else if (targetProp === 'head') {
|
|
199
|
+
data.head.unshift(...tags);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return data;
|
|
203
|
+
}
|
|
110
204
|
}
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
is_env_external,
|
|
9
9
|
is_string,
|
|
10
|
-
is_import_external,
|
|
11
10
|
} from "../type/guard.ts";
|
|
12
11
|
|
|
13
12
|
function getExternalUrl(args: ModuloArgs_Pack, url: ConfigExternalUrl) {
|
|
@@ -39,17 +38,21 @@ export function getExternalsAndImportMap(
|
|
|
39
38
|
return Object.entries(externalLibs).reduce(
|
|
40
39
|
({ externals, importMap }, [libName, data]) => {
|
|
41
40
|
// 归一化为GlobalExternal或者ImportExternal
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// 1. data 是 string -> { url: data }
|
|
42
|
+
// 2. data 是 EnvExternalUrl (dev/prd) -> { url: data }
|
|
43
|
+
// 3. data 是 ImportExternal -> data
|
|
44
|
+
|
|
44
45
|
let externalLib: ImportExternal;
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
externalLib = { url:
|
|
46
|
+
|
|
47
|
+
if (is_string(data)) {
|
|
48
|
+
externalLib = { url: data };
|
|
49
|
+
} else if (is_env_external(data)) {
|
|
50
|
+
externalLib = { url: data };
|
|
48
51
|
} else {
|
|
49
|
-
|
|
50
|
-
externalLib = externalData as ImportExternal;
|
|
52
|
+
externalLib = data as ImportExternal;
|
|
51
53
|
}
|
|
52
|
-
|
|
54
|
+
|
|
55
|
+
// 解析 url (处理 EnvExternalUrl)
|
|
53
56
|
const url = getExternalUrl(args, externalLib.url);
|
|
54
57
|
|
|
55
58
|
if (externalsType === "script") {
|
|
@@ -57,7 +60,9 @@ export function getExternalsAndImportMap(
|
|
|
57
60
|
const globalVar = externalLib.global || libName;
|
|
58
61
|
const importName = externalLib.importName || libName;
|
|
59
62
|
(Array.isArray(importName) ? importName : [importName]).forEach(
|
|
60
|
-
(name) =>
|
|
63
|
+
(name) => {
|
|
64
|
+
externals[name] = globalVar;
|
|
65
|
+
},
|
|
61
66
|
);
|
|
62
67
|
|
|
63
68
|
if (url) {
|
|
@@ -67,7 +72,9 @@ export function getExternalsAndImportMap(
|
|
|
67
72
|
// Importmap 模式:external 映射为包名(由 importmap 解析)
|
|
68
73
|
const importName = externalLib.importName || libName;
|
|
69
74
|
(Array.isArray(importName) ? importName : [importName]).forEach(
|
|
70
|
-
(name) =>
|
|
75
|
+
(name) => {
|
|
76
|
+
externals[name] = libName;
|
|
77
|
+
},
|
|
71
78
|
);
|
|
72
79
|
|
|
73
80
|
if (url) {
|