earthsdk3-assets 3.0.27 → 3.1.0-beta.1

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/README.md CHANGED
@@ -1,160 +1,199 @@
1
- # EarthSDK3 Assets
2
-
3
- EarthSDK3 资源管理插件,支持自动检测并适配 Vite、Webpack、Rspack 等主流构建工具。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- npm install earthsdk3-assets
9
- ```
10
-
11
- ## 特性
12
-
13
- - 🔍 **自动检测构建工具** - 根据项目依赖自动选择对应插件
14
- - ⚡ **支持 Vite** - 原生 ESM,极速开发体验
15
- - 📦 **支持 Webpack** - 兼容 Webpack 5.x
16
- - 🚀 **支持 Rspack** - 字节跳动出品,Webpack API 兼容
17
- - 💾 **增量下载** - 智能缓存,只下载变更资源
18
- - 🎯 **零配置** - 开箱即用,自动注入脚本
19
- - 📁 **不污染项目** - 开发模式不创建物理文件
20
-
21
- ## 使用方法
22
-
23
- ### 自动检测(推荐)
24
-
25
- 插件会自动检测你项目使用的构建工具:
26
-
27
- #### Vite 项目
28
-
29
- ```typescript
30
- // vite.config.ts
31
- import earthsdkAssets from 'earthsdk3-assets';
32
-
33
- export default {
34
- plugins: [
35
- earthsdkAssets()
36
- ]
37
- };
38
- ```
39
-
40
- #### Webpack 项目
41
-
42
- ```javascript
43
- // webpack.config.js
44
- const earthsdkAssets = require('earthsdk3-assets');
45
-
46
- module.exports = {
47
- plugins: [
48
- earthsdkAssets()
49
- ]
50
- };
51
- ```
52
-
53
- #### Rspack 项目
54
-
55
- ```javascript
56
- // rspack.config.js
57
- const earthsdkAssets = require('earthsdk3-assets');
58
-
59
- module.exports = {
60
- plugins: [
61
- earthsdkAssets()
62
- ]
63
- };
64
- ```
65
-
66
- ### 手动指定构建工具
67
-
68
- 如果自动检测失败,可以强制指定:
69
-
70
- ```typescript
71
- // Vite
72
- import earthsdkAssets from 'earthsdk3-assets';
73
- export default {
74
- plugins: [earthsdkAssets({ forceTool: 'vite' })]
75
- };
76
-
77
- // Webpack
78
- const earthsdkAssets = require('earthsdk3-assets');
79
- module.exports = {
80
- plugins: [earthsdkAssets({ forceTool: 'webpack' })]
81
- };
82
-
83
- // Rspack
84
- const earthsdkAssets = require('earthsdk3-assets');
85
- module.exports = {
86
- plugins: [earthsdkAssets({ forceTool: 'rspack' })]
87
- };
88
- ```
89
-
90
- ### 子路径导入
91
-
92
- 也可以直接导入特定构建工具的插件:
93
-
94
- ```typescript
95
- // Vite
96
- import earthsdkAssets from 'earthsdk3-assets/vite';
97
-
98
- // Webpack
99
- const earthsdkAssets = require('earthsdk3-assets/webpack');
100
-
101
- // Rspack
102
- const earthsdkAssets = require('earthsdk3-assets/rspack');
103
- ```
104
-
105
- ## 工作原理
106
-
107
- ### 开发模式
108
-
109
- 1. **资源下载** - 从远程服务器下载 EarthSDK3 所需的静态资源到 `node_modules/earthsdk3-assets/assets/`
110
- 2. **智能缓存** - 使用 MD5 校验,只下载变更的文件
111
- 3. **虚拟路径服务** - 开发服务器提供 `/js/earthsdk3-assets/*` 路径的资源服务,不创建物理文件
112
- 4. **HTML 注入** - 自动在 HTML 中注入 `<script src="js/earthsdk3-assets/earthsdk3-assets.js">`
113
-
114
- ### 生产模式
115
-
116
- 1. **资源拷贝** - 构建时将资源拷贝到 `dist/js/earthsdk3-assets/` 目录
117
- 2. **HTML 注入** - 自动在 HTML 中注入脚本引用
118
-
119
- ## 目录结构
120
-
121
- ```
122
- earthsdk3-assets/
123
- ├── src/
124
- │ ├── core/
125
- │ │ ├── downloadAssets.js # ESM 版本资源下载核心逻辑
126
- │ │ ├── downloadAssets.cjs # CommonJS 版本
127
- │ │ ├── copyAssets.js # ESM 版本文件拷贝工具
128
- │ │ └── copyAssets.cjs # CommonJS 版本
129
- │ ├── plugins/
130
- │ │ ├── vite.js # Vite 插件 (ESM)
131
- │ │ ├── webpack.cjs # Webpack 插件 (CommonJS)
132
- │ │ └── rspack.cjs # Rspack 插件 (CommonJS)
133
- │ ├── index.js # ESM 入口(自动检测)
134
- │ ├── index.cjs # CommonJS 入口
135
- │ └── index.d.ts # TypeScript 类型声明
136
- ├── assets/ # 下载的静态资源
137
- ├── earthsdk3-assets.js # 资源加载器脚本
138
- └── package.json
139
- ```
140
-
141
- ## 构建工具检测优先级
142
-
143
- 插件按以下顺序检测构建工具:
144
-
145
- 1. **Vite** - 检查 `vite` 依赖或 `vite.config.*` 文件
146
- 2. **Rspack** - 检查 `@rspack/core` 依赖或 `rspack.config.*` 文件
147
- 3. **Vue CLI** - 检查 `@vue/cli-service` 依赖(基于 Webpack 5)
148
- 4. **Webpack** - 检查 `webpack` 依赖或 `webpack.config.*` 文件
149
-
150
- ## 注意事项
151
-
152
- - **Webpack/Rspack 项目**需要安装 `html-webpack-plugin` 或 `@rspack/plugin-html` 以支持 HTML 脚本注入
153
- - **Vue CLI 项目**内置 `html-webpack-plugin`,无需额外安装
154
- - **所有构建工具插件均为可选依赖**,未使用的构建工具不会引起报错
155
- - **开发模式**下资源通过虚拟路径访问,不创建物理文件到项目目录
156
- - **生产模式**下资源会拷贝到构建输出目录
157
-
158
- ## 许可证
159
-
1
+ # EarthSDK3 Assets
2
+
3
+ EarthSDK3 资源管理插件,支持自动检测并适配 Vite、Webpack、Rspack 等主流构建工具。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install earthsdk3-assets
9
+ ```
10
+
11
+ ## 特性
12
+
13
+ - 🔍 **自动检测构建工具** - 根据项目依赖自动选择对应插件
14
+ - ⚡ **支持 Vite** - 原生 ESM,极速开发体验
15
+ - 📦 **支持 Webpack** - 兼容 Webpack 5.x
16
+ - 🚀 **支持 Rspack** - 字节跳动出品,Webpack API 兼容
17
+ - 💾 **增量下载** - 智能缓存,只下载变更资源
18
+ - 🎯 **零配置** - 开箱即用,自动注入脚本
19
+ - 📁 **不污染项目** - 开发模式不创建物理文件
20
+ - 🌐 **内网环境支持** - 网络不可用时自动使用本地缓存
21
+ - ⚙️ **灵活配置** - 支持自定义资源路径
22
+
23
+ ## 使用方法
24
+
25
+ ### 自动检测(推荐)
26
+
27
+ 插件会自动检测你项目使用的构建工具:
28
+
29
+ #### Vite 项目
30
+
31
+ ```typescript
32
+ // vite.config.ts
33
+ import earthsdkAssets from 'earthsdk3-assets';
34
+
35
+ export default {
36
+ plugins: [
37
+ earthsdkAssets()
38
+ ]
39
+ };
40
+ ```
41
+
42
+ #### Webpack 项目
43
+
44
+ ```javascript
45
+ // webpack.config.js
46
+ const earthsdkAssets = require('earthsdk3-assets');
47
+
48
+ module.exports = {
49
+ plugins: [
50
+ earthsdkAssets()
51
+ ]
52
+ };
53
+ ```
54
+
55
+ #### Rspack 项目
56
+
57
+ ```javascript
58
+ // rspack.config.js
59
+ const earthsdkAssets = require('earthsdk3-assets');
60
+
61
+ module.exports = {
62
+ plugins: [
63
+ earthsdkAssets()
64
+ ]
65
+ };
66
+ ```
67
+
68
+ ### 手动指定构建工具
69
+
70
+ 如果自动检测失败,可以强制指定:
71
+
72
+ ```typescript
73
+ // Vite
74
+ import earthsdkAssets from 'earthsdk3-assets';
75
+ export default {
76
+ plugins: [earthsdkAssets({ forceTool: 'vite' })]
77
+ };
78
+
79
+ // Webpack
80
+ const earthsdkAssets = require('earthsdk3-assets');
81
+ module.exports = {
82
+ plugins: [earthsdkAssets({ forceTool: 'webpack' })]
83
+ };
84
+
85
+ // Rspack
86
+ const earthsdkAssets = require('earthsdk3-assets');
87
+ module.exports = {
88
+ plugins: [earthsdkAssets({ forceTool: 'rspack' })]
89
+ };
90
+ ```
91
+
92
+ ### 自定义配置
93
+
94
+ ```typescript
95
+ // Vite 示例
96
+ import earthsdkAssets from 'earthsdk3-assets';
97
+
98
+ export default {
99
+ plugins: [
100
+ earthsdkAssets({
101
+ forceTool: 'vite',
102
+ assetsPath: 'custom/assets', // 资源文件拷贝路径,默认为 'earthsdk3-assets'
103
+ scriptSrc: './custom/assets/earthsdk3-assets.js' // script 标签路径
104
+ })
105
+ ]
106
+ };
107
+ ```
108
+
109
+ ### 子路径导入
110
+
111
+ 也可以直接导入特定构建工具的插件:
112
+
113
+ ```typescript
114
+ // Vite
115
+ import earthsdkAssets from 'earthsdk3-assets/vite';
116
+
117
+ // Webpack
118
+ const earthsdkAssets = require('earthsdk3-assets/webpack');
119
+
120
+ // Rspack
121
+ const earthsdkAssets = require('earthsdk3-assets/rspack');
122
+ ```
123
+
124
+ ## 配置选项
125
+
126
+ | 选项 | 类型 | 默认值 | 说明 |
127
+ |------|------|--------|------|
128
+ | `forceTool` | `'vite' \| 'webpack' \| 'rspack' \| 'vue-cli'` | 自动检测 | 强制指定构建工具 |
129
+ | `assetsPath` | `string` | `'earthsdk3-assets'` | 资源文件拷贝到输出目录的路径 |
130
+ | `scriptSrc` | `string` | `'./earthsdk3-assets/earthsdk3-assets.js'` | 注入到 HTML 的 script 标签 src 属性 |
131
+
132
+ ## 工作原理
133
+
134
+ ### 开发模式
135
+
136
+ 1. **资源下载** - 从远程服务器下载 EarthSDK3 所需的静态资源到 `node_modules/earthsdk3-assets/`
137
+ 2. **智能缓存** - 使用 MD5 校验,只下载变更的文件
138
+ 3. **虚拟路径服务** - 开发服务器提供 `/earthsdk3-assets/*` 路径的资源服务,不创建物理文件
139
+ 4. **HTML 注入** - 自动在 HTML 中注入 `<script src="./earthsdk3-assets/earthsdk3-assets.js">`
140
+
141
+ ### 生产模式
142
+
143
+ 1. **资源拷贝** - 构建时根据资源清单将资源拷贝到 `dist/earthsdk3-assets/` 目录
144
+ 2. **HTML 注入** - 自动在 HTML 中注入脚本引用
145
+
146
+ ### 内网环境支持
147
+
148
+ 当项目从外网拷贝到内网环境后,如果无法访问远程资源服务器:
149
+
150
+ 1. 插件会检测本地缓存文件是否存在
151
+ 2. 如果缓存存在,使用本地缓存继续运行
152
+ 3. 如果缓存不存在,抛出异常
153
+
154
+ ## 目录结构
155
+
156
+ ```
157
+ earthsdk3-assets/
158
+ ├── src/
159
+ │ ├── core/
160
+ │ │ ├── downloadAssets.js # ESM 版本资源下载核心逻辑
161
+ │ │ ├── downloadAssets.cjs # CommonJS 版本
162
+ │ │ ├── copyAssets.js # ESM 版本文件拷贝工具
163
+ │ │ └── copyAssets.cjs # CommonJS 版本
164
+ │ ├── plugins/
165
+ │ │ ├── vite.js # Vite 插件 (ESM)
166
+ │ │ ├── webpack.cjs # Webpack 插件 (CommonJS)
167
+ │ │ └── rspack.cjs # Rspack 插件 (CommonJS)
168
+ │ ├── index.js # ESM 入口(自动检测)
169
+ │ ├── index.cjs # CommonJS 入口
170
+ │ └── index.d.ts # TypeScript 类型声明
171
+ ├── glb/ # 下载的 GLB 模型资源
172
+ ├── img/ # 下载的图片资源
173
+ ├── earthsdk3-assets.js # 资源加载器脚本(远程下载)
174
+ ├── .assets-version # 版本缓存文件
175
+ ├── .assets-manifest.json # 资源清单缓存
176
+ └── package.json
177
+ ```
178
+
179
+ ## 构建工具检测优先级
180
+
181
+ 插件按以下顺序检测构建工具:
182
+
183
+ 1. **Vite** - 检查 `vite` 依赖或 `vite.config.*` 文件
184
+ 2. **Rspack** - 检查 `@rspack/core` 依赖或 `rspack.config.*` 文件
185
+ 3. **Vue CLI** - 检查 `@vue/cli-service` 依赖(基于 Webpack 5)
186
+ 4. **Webpack** - 检查 `webpack` 依赖或 `webpack.config.*` 文件
187
+
188
+ ## 注意事项
189
+
190
+ - **Webpack/Rspack 项目**需要安装 `html-webpack-plugin` 或 `@rspack/plugin-html` 以支持 HTML 脚本注入
191
+ - **Vue CLI 项目**内置 `html-webpack-plugin`,无需额外安装
192
+ - **所有构建工具插件均为可选依赖**,未使用的构建工具不会引起报错
193
+ - **开发模式**下资源通过虚拟路径访问,不创建物理文件到项目目录
194
+ - **生产模式**下资源会根据清单文件拷贝到构建输出目录
195
+ - **内网环境**下如果已有缓存,即使无法访问外网也能正常运行
196
+
197
+ ## 许可证
198
+
160
199
  ISC
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "earthsdk3-assets",
3
- "version": "3.0.27",
3
+ "version": "3.1.0-beta.1",
4
4
  "description": "地球可视化实验室 (EarthSDK&CesiumLab) https://www.bjxbsj.cn",
5
5
  "private": false,
6
6
  "type": "module",
@@ -23,7 +23,6 @@
23
23
  },
24
24
  "files": [
25
25
  "src/",
26
- "earthsdk3-assets.js",
27
26
  "package.json"
28
27
  ],
29
28
  "scripts": {
@@ -31,7 +30,7 @@
31
30
  "push-beta": "npm publish --registry https://registry.npmjs.org --tag beta",
32
31
  "push": "npm publish --registry https://registry.npmjs.org"
33
32
  },
34
- "author": "suplyang",
33
+ "author": "xingenjun",
35
34
  "owner": "北京西部世界科技有限公司",
36
35
  "homepage": "www.earthsdk.com",
37
36
  "license": "ISC",
@@ -1,40 +1,83 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
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', 'earthsdk3-assets');
4
+ function copyAssetsToDest(assetsDir, rootDir, outDir, options) {
5
+ options = options || {};
6
+ const assetsPath = options.assetsPath || 'earthsdk3-assets';
7
+ const dest = path.join(outDir, assetsPath);
8
+
9
+ const { cacheFile, manifestCacheFile } = getAssetsPaths(rootDir);
10
+
8
11
  fs.mkdirSync(dest, { recursive: true });
9
12
 
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
- });
13
+ if (!fs.existsSync(manifestCacheFile)) {
14
+ console.warn('[earthsdk-assets] 未找到资源清单文件:', manifestCacheFile);
15
+ return;
16
+ }
17
+
18
+ if (!fs.existsSync(assetsDir)) {
19
+ console.warn('[earthsdk-assets] 资源目录不存在:', assetsDir);
20
+ return;
21
+ }
22
+
23
+ let assetsList;
24
+ try {
25
+ assetsList = JSON.parse(fs.readFileSync(manifestCacheFile, 'utf-8'));
26
+ } catch (err) {
27
+ console.error('[earthsdk-assets] 解析资源清单失败:', err.message);
28
+ return;
29
+ }
30
+
31
+ const filePaths = [];
32
+ collectFilePathsFromManifest(assetsList, '', filePaths);
33
+
34
+ if (filePaths.length === 0) {
35
+ console.warn('[earthsdk-assets] 资源清单为空,没有文件需要拷贝');
36
+ return;
24
37
  }
25
38
 
26
- const sdkSrc = path.join(rootDir, 'earthsdk3-assets.js');
27
- if (fs.existsSync(sdkSrc)) {
28
- fs.cpSync(sdkSrc, path.join(dest, 'earthsdk3-assets.js'));
39
+ let copiedCount = 0;
40
+ for (const filePath of filePaths) {
41
+ const srcPath = path.join(assetsDir, filePath);
42
+ const destPath = path.join(dest, filePath);
43
+
44
+ if (fs.existsSync(srcPath)) {
45
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
46
+ fs.copyFileSync(srcPath, destPath);
47
+ copiedCount++;
48
+ } else {
49
+ console.warn('[earthsdk-assets] 缺失资源文件:', srcPath);
50
+ }
29
51
  }
30
52
 
31
- console.log('[earthsdk-assets] 资源已拷贝到:', dest);
53
+ console.log(`[earthsdk-assets] 已拷贝 ${copiedCount} 个资源文件到: ${dest}`);
54
+ }
55
+
56
+ function collectFilePathsFromManifest(node, currentPath, fileList) {
57
+ for (const key in node) {
58
+ if (!Object.hasOwn(node, key)) {
59
+ continue;
60
+ }
61
+ const value = node[key];
62
+ const nextPath = path.join(currentPath, key);
63
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
64
+ if (typeof value.size === 'number' && typeof value.md5 === 'string') {
65
+ fileList.push(nextPath.replaceAll('\\', '/'));
66
+ } else {
67
+ collectFilePathsFromManifest(value, nextPath, fileList);
68
+ }
69
+ } else if (Array.isArray(value)) {
70
+ for (const fileName of value) {
71
+ fileList.push(path.join(nextPath, fileName).replaceAll('\\', '/'));
72
+ }
73
+ }
74
+ }
32
75
  }
33
76
 
34
77
  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');
78
+ const assetsDir = rootDir;
79
+ const cacheFile = path.resolve(rootDir, '.assets-version');
80
+ const manifestCacheFile = path.resolve(rootDir, '.assets-manifest.json');
38
81
  return { assetsDir, cacheFile, manifestCacheFile };
39
82
  }
40
83
 
@@ -1,39 +1,81 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
- const IGNORE_FILES = new Set(['.assets-version', '.assets-manifest.json']);
5
-
6
- export function copyAssetsToDest(assetsDir, rootDir, outDir) {
7
- const dest = path.join(outDir, 'js', 'earthsdk3-assets');
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
- export 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
- }
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ export function copyAssetsToDest(assetsDir, rootDir, outDir, options = {}) {
5
+ const assetsPath = options.assetsPath || 'earthsdk3-assets';
6
+ const dest = path.join(outDir, assetsPath);
7
+
8
+ const { cacheFile, manifestCacheFile } = getAssetsPaths(rootDir);
9
+
10
+ fs.mkdirSync(dest, { recursive: true });
11
+
12
+ if (!fs.existsSync(manifestCacheFile)) {
13
+ console.warn('[earthsdk-assets] 未找到资源清单文件:', manifestCacheFile);
14
+ return;
15
+ }
16
+
17
+ if (!fs.existsSync(assetsDir)) {
18
+ console.warn('[earthsdk-assets] 资源目录不存在:', assetsDir);
19
+ return;
20
+ }
21
+
22
+ let assetsList;
23
+ try {
24
+ assetsList = JSON.parse(fs.readFileSync(manifestCacheFile, 'utf-8'));
25
+ } catch (err) {
26
+ console.error('[earthsdk-assets] 解析资源清单失败:', err.message);
27
+ return;
28
+ }
29
+
30
+ const filePaths = [];
31
+ collectFilePathsFromManifest(assetsList, '', filePaths);
32
+
33
+ if (filePaths.length === 0) {
34
+ console.warn('[earthsdk-assets] 资源清单为空,没有文件需要拷贝');
35
+ return;
36
+ }
37
+
38
+ let copiedCount = 0;
39
+ for (const filePath of filePaths) {
40
+ const srcPath = path.join(assetsDir, filePath);
41
+ const destPath = path.join(dest, filePath);
42
+
43
+ if (fs.existsSync(srcPath)) {
44
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
45
+ fs.copyFileSync(srcPath, destPath);
46
+ copiedCount++;
47
+ } else {
48
+ console.warn('[earthsdk-assets] 缺失资源文件:', srcPath);
49
+ }
50
+ }
51
+
52
+ console.log(`[earthsdk-assets] 已拷贝 ${copiedCount} 个资源文件到: ${dest}`);
53
+ }
54
+
55
+ function collectFilePathsFromManifest(node, currentPath, fileList) {
56
+ for (const key in node) {
57
+ if (!Object.hasOwn(node, key)) {
58
+ continue;
59
+ }
60
+ const value = node[key];
61
+ const nextPath = path.join(currentPath, key);
62
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
63
+ if (typeof value.size === 'number' && typeof value.md5 === 'string') {
64
+ fileList.push(nextPath.replaceAll('\\', '/'));
65
+ } else {
66
+ collectFilePathsFromManifest(value, nextPath, fileList);
67
+ }
68
+ } else if (Array.isArray(value)) {
69
+ for (const fileName of value) {
70
+ fileList.push(path.join(nextPath, fileName).replaceAll('\\', '/'));
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ export function getAssetsPaths(rootDir) {
77
+ const assetsDir = rootDir;
78
+ const cacheFile = path.resolve(rootDir, '.assets-version');
79
+ const manifestCacheFile = path.resolve(rootDir, '.assets-manifest.json');
80
+ return { assetsDir, cacheFile, manifestCacheFile };
81
+ }
@@ -284,6 +284,12 @@ async function downloadAssets(assetsDir, cacheFile, manifestCacheFile, ignoreFil
284
284
  console.log('[assets] 下载完成');
285
285
  } catch (err) {
286
286
  console.error('[assets] 下载失败:', err.message);
287
+
288
+ if (fs.existsSync(cacheFile) && fs.existsSync(manifestCacheFile) && fs.existsSync(assetsDir)) {
289
+ console.warn('[assets] 使用本地缓存继续运行');
290
+ return;
291
+ }
292
+
287
293
  throw err;
288
294
  }
289
295
  }