earthsdk3-assets 3.0.16 → 3.0.18
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "earthsdk3-assets",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.18",
|
|
4
4
|
"description": "地球可视化实验室 (EarthSDK&CesiumLab) https://www.bjxbsj.cn",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"import": "./src/plugins/vite.js"
|
|
16
16
|
},
|
|
17
17
|
"./webpack": {
|
|
18
|
-
"require": "./src/plugins/webpack.
|
|
18
|
+
"require": "./src/plugins/webpack.cjs"
|
|
19
19
|
},
|
|
20
20
|
"./rspack": {
|
|
21
|
-
"require": "./src/plugins/rspack.
|
|
21
|
+
"require": "./src/plugins/rspack.cjs"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const IGNORE_FILES = new Set(['.assets-version', '.assets-manifest.json']);
|
|
5
|
+
|
|
6
|
+
function copyAssetsToDest(assetsDir, rootDir, outDir) {
|
|
7
|
+
const dest = path.join(outDir, 'js');
|
|
8
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
9
|
+
|
|
10
|
+
if (fs.existsSync(assetsDir)) {
|
|
11
|
+
fs.cpSync(assetsDir, path.join(dest, 'assets'), {
|
|
12
|
+
recursive: true,
|
|
13
|
+
filter(src) {
|
|
14
|
+
const baseName = path.basename(src);
|
|
15
|
+
if (IGNORE_FILES.has(baseName)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (baseName.endsWith('.download') || baseName.endsWith('.tmp')) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sdkSrc = path.join(rootDir, 'earthsdk3-assets.js');
|
|
27
|
+
if (fs.existsSync(sdkSrc)) {
|
|
28
|
+
fs.cpSync(sdkSrc, path.join(dest, 'earthsdk3-assets.js'));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log('[earthsdk-assets] 资源已拷贝到:', dest);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getAssetsPaths(rootDir) {
|
|
35
|
+
const assetsDir = path.resolve(rootDir, 'assets');
|
|
36
|
+
const cacheFile = path.resolve(assetsDir, '.assets-version');
|
|
37
|
+
const manifestCacheFile = path.resolve(assetsDir, '.assets-manifest.json');
|
|
38
|
+
return { assetsDir, cacheFile, manifestCacheFile };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { copyAssetsToDest, getAssetsPaths };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const http = require('http');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const MANIFEST_URL = "https://114.242.26.126:1000/EarthSDK/earthsdk3-assets/assets-list.json";
|
|
8
|
+
const BASE_URL = MANIFEST_URL.substring(0, MANIFEST_URL.lastIndexOf('/'));
|
|
9
|
+
const CONCURRENCY = 6;
|
|
10
|
+
const MAX_RETRIES = 3;
|
|
11
|
+
|
|
12
|
+
const agent = new https.Agent({
|
|
13
|
+
rejectUnauthorized: false
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function getProtocol(url) {
|
|
17
|
+
if (url.startsWith('https://')) {
|
|
18
|
+
return https;
|
|
19
|
+
}
|
|
20
|
+
if (url.startsWith('http://')) {
|
|
21
|
+
return http;
|
|
22
|
+
}
|
|
23
|
+
throw new Error('不支持的协议: ' + url);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function stableStringify(obj) {
|
|
27
|
+
if (Array.isArray(obj)) {
|
|
28
|
+
return `[${obj.map(stableStringify).join(',')}]`;
|
|
29
|
+
}
|
|
30
|
+
if (obj && typeof obj === 'object') {
|
|
31
|
+
return `{${Object.keys(obj).sort().map(
|
|
32
|
+
k => `"${k}":${stableStringify(obj[k])}`
|
|
33
|
+
).join(',')}}`;
|
|
34
|
+
}
|
|
35
|
+
return JSON.stringify(obj);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function fetchJson(url) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const request = getProtocol(url).get(url, { agent }, (response) => {
|
|
41
|
+
if (response.statusCode !== 200) {
|
|
42
|
+
reject(new Error(`HTTP ${response.statusCode}: ${url}`));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let data = '';
|
|
46
|
+
response.on('data', chunk => {
|
|
47
|
+
data += chunk;
|
|
48
|
+
});
|
|
49
|
+
response.on('end', () => {
|
|
50
|
+
try {
|
|
51
|
+
resolve(JSON.parse(data));
|
|
52
|
+
} catch {
|
|
53
|
+
reject(new Error(`JSON 解析失败: ${url}`));
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
response.on('error', reject);
|
|
57
|
+
});
|
|
58
|
+
request.setTimeout(15000, () => {
|
|
59
|
+
request.destroy(new Error('请求超时'));
|
|
60
|
+
});
|
|
61
|
+
request.on('error', reject);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function collectTasks(node, currentPath, tasks, outDir) {
|
|
66
|
+
for (const key in node) {
|
|
67
|
+
if (!Object.hasOwn(node, key)) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const value = node[key];
|
|
71
|
+
const nextPath = path.join(currentPath, key);
|
|
72
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
73
|
+
if (typeof value.size === 'number' && typeof value.md5 === 'string') {
|
|
74
|
+
const filePath = nextPath.replaceAll('\\', '/');
|
|
75
|
+
pushTask(filePath, tasks, outDir);
|
|
76
|
+
} else {
|
|
77
|
+
collectTasks(value, nextPath, tasks, outDir);
|
|
78
|
+
}
|
|
79
|
+
} else if (Array.isArray(value)) {
|
|
80
|
+
for (const fileName of value) {
|
|
81
|
+
const filePath = path.join(nextPath, fileName).replaceAll('\\', '/');
|
|
82
|
+
pushTask(filePath, tasks, outDir);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function collectFilePaths(node, currentPath, fileSet) {
|
|
89
|
+
for (const key in node) {
|
|
90
|
+
if (!Object.hasOwn(node, key)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const value = node[key];
|
|
94
|
+
const nextPath = path.join(currentPath, key);
|
|
95
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
96
|
+
if (typeof value.size === 'number' && typeof value.md5 === 'string') {
|
|
97
|
+
fileSet.add(nextPath.replaceAll('\\', '/'));
|
|
98
|
+
} else {
|
|
99
|
+
collectFilePaths(value, nextPath, fileSet);
|
|
100
|
+
}
|
|
101
|
+
} else if (Array.isArray(value)) {
|
|
102
|
+
for (const fileName of value) {
|
|
103
|
+
fileSet.add(path.join(nextPath, fileName).replaceAll('\\', '/'));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function collectDownloadTasks(newNode, oldNode, currentPath, tasks, outDir) {
|
|
110
|
+
for (const key in newNode) {
|
|
111
|
+
if (!Object.hasOwn(newNode, key)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const newValue = newNode[key];
|
|
115
|
+
const oldValue = oldNode && Object.hasOwn(oldNode, key) ? oldNode[key] : null;
|
|
116
|
+
const nextPath = path.join(currentPath, key);
|
|
117
|
+
if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {
|
|
118
|
+
if (typeof newValue.size === 'number' && typeof newValue.md5 === 'string') {
|
|
119
|
+
const filePath = nextPath.replaceAll('\\', '/');
|
|
120
|
+
if (!oldValue || typeof oldValue !== 'object' || oldValue.size !== newValue.size || oldValue.md5 !== newValue.md5) {
|
|
121
|
+
pushTask(filePath, tasks, outDir);
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
collectDownloadTasks(newValue, oldValue, nextPath, tasks, outDir);
|
|
125
|
+
}
|
|
126
|
+
} else if (Array.isArray(newValue)) {
|
|
127
|
+
for (const fileName of newValue) {
|
|
128
|
+
const filePath = path.join(nextPath, fileName).replaceAll('\\', '/');
|
|
129
|
+
const oldArray = Array.isArray(oldValue) ? oldValue : [];
|
|
130
|
+
if (!oldArray.includes(fileName)) {
|
|
131
|
+
pushTask(filePath, tasks, outDir);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function pushTask(filePath, tasks, outDir) {
|
|
139
|
+
const outputPath = path.join(outDir, filePath);
|
|
140
|
+
tasks.push({
|
|
141
|
+
url: `${BASE_URL}/${filePath}`,
|
|
142
|
+
outputPath
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function downloadFile(url, outputPath) {
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
149
|
+
const tempPath = outputPath + '.download';
|
|
150
|
+
const file = fs.createWriteStream(tempPath);
|
|
151
|
+
const request = getProtocol(url).get(url, { agent }, (response) => {
|
|
152
|
+
if (response.statusCode !== 200) {
|
|
153
|
+
file.close();
|
|
154
|
+
try {
|
|
155
|
+
fs.unlinkSync(tempPath);
|
|
156
|
+
} catch { }
|
|
157
|
+
reject(new Error(`HTTP ${response.statusCode}: ${url}`));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
response.pipe(file);
|
|
161
|
+
file.on('finish', () => {
|
|
162
|
+
file.close(() => {
|
|
163
|
+
fs.rmSync(outputPath, { force: true });
|
|
164
|
+
fs.renameSync(tempPath, outputPath);
|
|
165
|
+
resolve();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
file.on('error', (err) => {
|
|
169
|
+
try {
|
|
170
|
+
fs.unlinkSync(tempPath);
|
|
171
|
+
} catch { }
|
|
172
|
+
reject(err);
|
|
173
|
+
});
|
|
174
|
+
response.on('error', (err) => {
|
|
175
|
+
try {
|
|
176
|
+
fs.unlinkSync(tempPath);
|
|
177
|
+
} catch { }
|
|
178
|
+
reject(err);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
request.setTimeout(15000, () => {
|
|
182
|
+
request.destroy(new Error('请求超时'));
|
|
183
|
+
});
|
|
184
|
+
request.on('error', (err) => {
|
|
185
|
+
try {
|
|
186
|
+
fs.unlinkSync(tempPath);
|
|
187
|
+
} catch { }
|
|
188
|
+
reject(err);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function downloadWithRetry(url, outputPath, retries) {
|
|
194
|
+
for (let i = 0; i < retries; i++) {
|
|
195
|
+
try {
|
|
196
|
+
await downloadFile(url, outputPath);
|
|
197
|
+
return;
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (i === retries - 1) {
|
|
200
|
+
console.error(`[assets] 下载失败(已重试${retries}次): ${url}`);
|
|
201
|
+
throw err;
|
|
202
|
+
}
|
|
203
|
+
console.warn(`[assets] 重试(${i + 1}/${retries}): ${url}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function downloadWithConcurrency(tasks, limit) {
|
|
209
|
+
const queue = [...tasks];
|
|
210
|
+
const workers = new Array(limit).fill(null).map(async () => {
|
|
211
|
+
while (queue.length) {
|
|
212
|
+
const task = queue.shift();
|
|
213
|
+
if (!task) {
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
await downloadWithRetry(task.url, task.outputPath, MAX_RETRIES);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
await Promise.all(workers);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function downloadAssets(assetsDir, cacheFile, manifestCacheFile, ignoreFiles) {
|
|
223
|
+
try {
|
|
224
|
+
const newAssetsList = await fetchJson(MANIFEST_URL);
|
|
225
|
+
const newHash = crypto.createHash('md5').update(
|
|
226
|
+
stableStringify(newAssetsList)
|
|
227
|
+
).digest('hex');
|
|
228
|
+
|
|
229
|
+
let oldAssetsList = null;
|
|
230
|
+
if (fs.existsSync(manifestCacheFile)) {
|
|
231
|
+
try {
|
|
232
|
+
oldAssetsList = JSON.parse(fs.readFileSync(manifestCacheFile, 'utf-8'));
|
|
233
|
+
} catch {
|
|
234
|
+
oldAssetsList = null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (fs.existsSync(cacheFile) && fs.readFileSync(cacheFile, 'utf-8').trim() === newHash) {
|
|
239
|
+
console.log('[assets] 资源未变化,跳过下载');
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const downloadTasks = [];
|
|
244
|
+
const deletePaths = [];
|
|
245
|
+
|
|
246
|
+
if (oldAssetsList && fs.existsSync(assetsDir)) {
|
|
247
|
+
const newFiles = new Set();
|
|
248
|
+
const oldFiles = new Set();
|
|
249
|
+
collectFilePaths(newAssetsList, '', newFiles);
|
|
250
|
+
collectFilePaths(oldAssetsList, '', oldFiles);
|
|
251
|
+
|
|
252
|
+
for (const filePath of oldFiles) {
|
|
253
|
+
if (!newFiles.has(filePath)) {
|
|
254
|
+
deletePaths.push(filePath);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
collectDownloadTasks(newAssetsList, oldAssetsList, '', downloadTasks, assetsDir);
|
|
258
|
+
} else {
|
|
259
|
+
collectTasks(newAssetsList, '', downloadTasks, assetsDir);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (deletePaths.length > 0) {
|
|
263
|
+
console.log(`[assets] 删除 ${deletePaths.length} 个文件...`);
|
|
264
|
+
for (const filePath of deletePaths) {
|
|
265
|
+
const fullPath = path.join(assetsDir, filePath);
|
|
266
|
+
try {
|
|
267
|
+
fs.rmSync(fullPath, { force: true });
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.warn(`[assets] 删除文件失败: ${fullPath}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (downloadTasks.length > 0) {
|
|
275
|
+
console.log(`[assets] 共 ${downloadTasks.length} 个文件需要下载...`);
|
|
276
|
+
await downloadWithConcurrency(downloadTasks, CONCURRENCY);
|
|
277
|
+
} else {
|
|
278
|
+
console.log('[assets] 无需下载新文件');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
fs.mkdirSync(assetsDir, { recursive: true });
|
|
282
|
+
fs.writeFileSync(cacheFile, newHash, 'utf-8');
|
|
283
|
+
fs.writeFileSync(manifestCacheFile, JSON.stringify(newAssetsList, null, 2), 'utf-8');
|
|
284
|
+
console.log('[assets] 下载完成');
|
|
285
|
+
} catch (err) {
|
|
286
|
+
console.error('[assets] 下载失败:', err.message);
|
|
287
|
+
throw err;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
module.exports = { downloadAssets, MANIFEST_URL, BASE_URL, CONCURRENCY, MAX_RETRIES };
|
package/src/index.cjs
CHANGED
|
@@ -68,11 +68,11 @@ function earthsdkAssets(options = {}) {
|
|
|
68
68
|
|
|
69
69
|
switch (tool) {
|
|
70
70
|
case 'webpack': {
|
|
71
|
-
const WebpackPlugin = require('./plugins/webpack.
|
|
71
|
+
const WebpackPlugin = require('./plugins/webpack.cjs');
|
|
72
72
|
return new WebpackPlugin(options);
|
|
73
73
|
}
|
|
74
74
|
case 'rspack': {
|
|
75
|
-
const RspackPlugin = require('./plugins/rspack.
|
|
75
|
+
const RspackPlugin = require('./plugins/rspack.cjs');
|
|
76
76
|
return new RspackPlugin(options);
|
|
77
77
|
}
|
|
78
78
|
case 'vite':
|
|
@@ -87,12 +87,12 @@ function earthsdkAssets(options = {}) {
|
|
|
87
87
|
|
|
88
88
|
// 导出各平台专用插件
|
|
89
89
|
function webpackPlugin(options = {}) {
|
|
90
|
-
const WebpackPlugin = require('./plugins/webpack.
|
|
90
|
+
const WebpackPlugin = require('./plugins/webpack.cjs');
|
|
91
91
|
return new WebpackPlugin(options);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function rspackPlugin(options = {}) {
|
|
95
|
-
const RspackPlugin = require('./plugins/rspack.
|
|
95
|
+
const RspackPlugin = require('./plugins/rspack.cjs');
|
|
96
96
|
return new RspackPlugin(options);
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// 但为了清晰,单独提供 Rspack 入口
|
|
6
|
-
|
|
7
|
-
async function loadCore() {
|
|
8
|
-
const { downloadAssets } = await import('../core/downloadAssets.js');
|
|
9
|
-
const { copyAssetsToDest, getAssetsPaths } = await import('../core/copyAssets.js');
|
|
10
|
-
return { downloadAssets, copyAssetsToDest, getAssetsPaths };
|
|
11
|
-
}
|
|
3
|
+
const { downloadAssets } = require('../core/downloadAssets.cjs');
|
|
4
|
+
const { copyAssetsToDest, getAssetsPaths } = require('../core/copyAssets.cjs');
|
|
12
5
|
|
|
13
6
|
const ROOT_DIR = path.resolve(__dirname, '../..');
|
|
14
7
|
let hasDownloaded = false;
|
|
@@ -18,7 +11,6 @@ async function ensureAssets(assetsDir, cacheFile, manifestCacheFile) {
|
|
|
18
11
|
return;
|
|
19
12
|
}
|
|
20
13
|
hasDownloaded = true;
|
|
21
|
-
const { downloadAssets } = await loadCore();
|
|
22
14
|
await downloadAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
23
15
|
}
|
|
24
16
|
|
|
@@ -29,10 +21,8 @@ class EarthsdkAssetsRspackPlugin {
|
|
|
29
21
|
}
|
|
30
22
|
|
|
31
23
|
apply(compiler) {
|
|
32
|
-
const { getAssetsPaths } = require('../core/copyAssets.js');
|
|
33
24
|
const { assetsDir, cacheFile, manifestCacheFile } = getAssetsPaths(ROOT_DIR);
|
|
34
25
|
|
|
35
|
-
// 1. 下载资源(编译前)
|
|
36
26
|
compiler.hooks.beforeRun.tapPromise('EarthsdkAssetsRspackPlugin', async () => {
|
|
37
27
|
await ensureAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
38
28
|
});
|
|
@@ -41,14 +31,11 @@ class EarthsdkAssetsRspackPlugin {
|
|
|
41
31
|
await ensureAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
42
32
|
});
|
|
43
33
|
|
|
44
|
-
// 2. 获取输出目录
|
|
45
34
|
compiler.hooks.afterEnvironment.tap('EarthsdkAssetsRspackPlugin', () => {
|
|
46
35
|
this.outDir = compiler.options.output.path || 'dist';
|
|
47
36
|
});
|
|
48
37
|
|
|
49
|
-
// 3. 注入 HTML(需要 @rspack/plugin-html 或 html-webpack-plugin)
|
|
50
38
|
compiler.hooks.compilation.tap('EarthsdkAssetsRspackPlugin', (compilation) => {
|
|
51
|
-
// Rspack 内置 html 插件或兼容 html-webpack-plugin
|
|
52
39
|
let HtmlPlugin;
|
|
53
40
|
try {
|
|
54
41
|
HtmlPlugin = require('@rspack/plugin-html');
|
|
@@ -79,13 +66,10 @@ class EarthsdkAssetsRspackPlugin {
|
|
|
79
66
|
}
|
|
80
67
|
});
|
|
81
68
|
|
|
82
|
-
// 4. 拷贝资源到产物目录
|
|
83
69
|
compiler.hooks.afterEmit.tapPromise('EarthsdkAssetsRspackPlugin', async () => {
|
|
84
|
-
const { copyAssetsToDest } = await loadCore();
|
|
85
70
|
copyAssetsToDest(assetsDir, ROOT_DIR, this.outDir);
|
|
86
71
|
});
|
|
87
72
|
|
|
88
|
-
// 5. Dev Server 中间件(@rspack/dev-server)
|
|
89
73
|
compiler.hooks.afterEnvironment.tap('EarthsdkAssetsRspackPlugin', () => {
|
|
90
74
|
const devServer = compiler.options.devServer;
|
|
91
75
|
if (devServer) {
|
|
@@ -127,4 +111,4 @@ class EarthsdkAssetsRspackPlugin {
|
|
|
127
111
|
}
|
|
128
112
|
|
|
129
113
|
module.exports = EarthsdkAssetsRspackPlugin;
|
|
130
|
-
module.exports.default = EarthsdkAssetsRspackPlugin;
|
|
114
|
+
module.exports.default = EarthsdkAssetsRspackPlugin;
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
async function loadCore() {
|
|
6
|
-
const { downloadAssets } = await import('../core/downloadAssets.js');
|
|
7
|
-
const { copyAssetsToDest, getAssetsPaths } = await import('../core/copyAssets.js');
|
|
8
|
-
return { downloadAssets, copyAssetsToDest, getAssetsPaths };
|
|
9
|
-
}
|
|
3
|
+
const { downloadAssets } = require('../core/downloadAssets.cjs');
|
|
4
|
+
const { copyAssetsToDest, getAssetsPaths } = require('../core/copyAssets.cjs');
|
|
10
5
|
|
|
11
6
|
const ROOT_DIR = path.resolve(__dirname, '../..');
|
|
12
7
|
let hasDownloaded = false;
|
|
@@ -16,7 +11,6 @@ async function ensureAssets(assetsDir, cacheFile, manifestCacheFile) {
|
|
|
16
11
|
return;
|
|
17
12
|
}
|
|
18
13
|
hasDownloaded = true;
|
|
19
|
-
const { downloadAssets } = await loadCore();
|
|
20
14
|
await downloadAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
21
15
|
}
|
|
22
16
|
|
|
@@ -29,7 +23,6 @@ class EarthsdkAssetsWebpackPlugin {
|
|
|
29
23
|
apply(compiler) {
|
|
30
24
|
const { assetsDir, cacheFile, manifestCacheFile } = getAssetsPaths(ROOT_DIR);
|
|
31
25
|
|
|
32
|
-
// 1. 下载资源(编译前)
|
|
33
26
|
compiler.hooks.beforeRun.tapPromise('EarthsdkAssetsWebpackPlugin', async () => {
|
|
34
27
|
await ensureAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
35
28
|
});
|
|
@@ -38,12 +31,10 @@ class EarthsdkAssetsWebpackPlugin {
|
|
|
38
31
|
await ensureAssets(assetsDir, cacheFile, manifestCacheFile);
|
|
39
32
|
});
|
|
40
33
|
|
|
41
|
-
// 2. 获取输出目录
|
|
42
34
|
compiler.hooks.afterEnvironment.tap('EarthsdkAssetsWebpackPlugin', () => {
|
|
43
35
|
this.outDir = compiler.options.output.path || 'dist';
|
|
44
36
|
});
|
|
45
37
|
|
|
46
|
-
// 3. 注入 HTML(需要 html-webpack-plugin)
|
|
47
38
|
compiler.hooks.compilation.tap('EarthsdkAssetsWebpackPlugin', (compilation) => {
|
|
48
39
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
49
40
|
|
|
@@ -65,19 +56,15 @@ class EarthsdkAssetsWebpackPlugin {
|
|
|
65
56
|
}
|
|
66
57
|
});
|
|
67
58
|
|
|
68
|
-
// 4. 拷贝资源到产物目录
|
|
69
59
|
compiler.hooks.afterEmit.tapPromise('EarthsdkAssetsWebpackPlugin', async () => {
|
|
70
|
-
const { copyAssetsToDest } = await loadCore();
|
|
71
60
|
copyAssetsToDest(assetsDir, ROOT_DIR, this.outDir);
|
|
72
61
|
});
|
|
73
62
|
|
|
74
|
-
// 5. Dev Server 中间件(webpack-dev-server)
|
|
75
63
|
compiler.hooks.afterEnvironment.tap('EarthsdkAssetsWebpackPlugin', () => {
|
|
76
64
|
const devServer = compiler.options.devServer;
|
|
77
65
|
if (devServer) {
|
|
78
66
|
const originalSetup = devServer.setupMiddlewares;
|
|
79
67
|
devServer.setupMiddlewares = (middlewares, devServer) => {
|
|
80
|
-
// 添加 earthsdk-assets 中间件
|
|
81
68
|
devServer.app.use('/js', (req, res, next) => {
|
|
82
69
|
try {
|
|
83
70
|
const filePath = path.resolve(ROOT_DIR, '.' + decodeURIComponent(req.url));
|
|
@@ -113,12 +100,5 @@ class EarthsdkAssetsWebpackPlugin {
|
|
|
113
100
|
}
|
|
114
101
|
}
|
|
115
102
|
|
|
116
|
-
function getAssetsPaths(rootDir) {
|
|
117
|
-
const assetsDir = path.resolve(rootDir, 'assets');
|
|
118
|
-
const cacheFile = path.resolve(assetsDir, '.assets-version');
|
|
119
|
-
const manifestCacheFile = path.resolve(assetsDir, '.assets-manifest.json');
|
|
120
|
-
return { assetsDir, cacheFile, manifestCacheFile };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
103
|
module.exports = EarthsdkAssetsWebpackPlugin;
|
|
124
|
-
module.exports.default = EarthsdkAssetsWebpackPlugin;
|
|
104
|
+
module.exports.default = EarthsdkAssetsWebpackPlugin;
|