hw-weapp-compiler 1.0.22 → 1.0.24
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 +48 -87
- package/build/config/getConfig.js +0 -3
- package/build/dev.js +1 -7
- package/build/loader/wxml-loader.js +6 -8
- package/build/plugin/index.js +9 -35
- package/build/prod.js +3 -3
- package/build/utils/cleanDistForDev.js +1 -1
- package/build/utils/createCompilerHandler.js +1 -21
- package/build/utils/getWxmlAssets.js +56 -67
- package/build/utils/storage.js +7 -29
- package/build/utils/upload.js +306 -102
- package/build/webpack.config.js +16 -18
- package/index.js +24 -13
- package/package.json +6 -7
- package/test/upload.js +92 -0
- package/test-support/mini-program.js +0 -49
- package/test-support/project.js +0 -25
- package/test-support/webpack.js +0 -80
package/README.md
CHANGED
|
@@ -1,119 +1,80 @@
|
|
|
1
|
-
#
|
|
1
|
+
# weapp-compiler
|
|
2
2
|
|
|
3
|
-
基于 webpack 5 的原生微信小程序构建工具,支持 JavaScript、Less、WXML、WXS、分包、npm 组件和可选的 OBS/OSS 静态资源上传。
|
|
4
3
|
|
|
5
|
-
##
|
|
4
|
+
## 版本改动
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
- 必须存在 `src/app.json` 和 `src/app.js`
|
|
6
|
+
1. **OpenSSL 3.0 兼容**: Node.js >= 17 时自动注入 `--openssl-legacy-provider`
|
|
7
|
+
2. **wxml-loader 空值守卫**: `loadModule` 失败时不再崩溃
|
|
10
8
|
|
|
11
9
|
## 安装
|
|
12
10
|
|
|
13
11
|
```bash
|
|
14
|
-
npm
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
升级版本后如果出现 `Cannot find module`,请删除业务项目中旧的安装产物并重新执行 `npm install`,确保传递依赖与 lockfile 同步。
|
|
18
|
-
|
|
19
|
-
在业务项目的 `package.json` 中添加:
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"scripts": {
|
|
24
|
-
"dev": "hw-weapp dev",
|
|
25
|
-
"build": "hw-weapp build"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
12
|
+
npm i weapp-compiler@2.x -D
|
|
28
13
|
```
|
|
29
14
|
|
|
30
15
|
## 使用
|
|
31
16
|
|
|
32
17
|
```bash
|
|
33
|
-
#
|
|
34
|
-
npm run dev
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
#
|
|
41
|
-
npm run build
|
|
42
|
-
npm run build -- --development
|
|
43
|
-
npm run build -- --simulation
|
|
18
|
+
# 开发调试
|
|
19
|
+
npm run dev # 测试环境
|
|
20
|
+
npm run dev -s # 预发环境
|
|
21
|
+
npm run dev -p # 生产环境
|
|
22
|
+
|
|
23
|
+
# 生产发布
|
|
24
|
+
npm run build -d # 测试环境
|
|
25
|
+
npm run build -s # 预发环境
|
|
26
|
+
npm run build # 生产环境
|
|
44
27
|
```
|
|
45
28
|
|
|
46
|
-
可用选项:
|
|
47
|
-
|
|
48
|
-
- `-d, --development`:测试环境
|
|
49
|
-
- `-s, --simulation`:预发环境
|
|
50
|
-
- `-p, --production`:生产环境
|
|
51
|
-
- `-a, --analyzer`:打开 webpack bundle analyzer
|
|
52
|
-
- `-q, --quiet`:关闭 webpack 进度输出
|
|
53
|
-
|
|
54
|
-
最终环境会通过 `process.env.BUILD_ENV` 注入代码,并记录到 `dist/weapp.env.json`。
|
|
55
|
-
|
|
56
29
|
## 配置
|
|
57
30
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```js
|
|
61
|
-
module.exports = {};
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
完整示例:
|
|
31
|
+
项目根目录下创建 `.weapp.js`:
|
|
65
32
|
|
|
66
33
|
```js
|
|
67
34
|
const path = require('path');
|
|
68
35
|
|
|
69
36
|
module.exports = {
|
|
37
|
+
// 路径别名
|
|
70
38
|
alias: {
|
|
71
39
|
'@utils': path.resolve(__dirname, 'src/utils'),
|
|
40
|
+
'@config': path.resolve(__dirname, 'src/config'),
|
|
72
41
|
},
|
|
42
|
+
// 资源公共路径
|
|
73
43
|
publicPath: 'https://cdn.example.com/weapp/',
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
:
|
|
44
|
+
// 要同步的目录
|
|
45
|
+
copyFiles: [{
|
|
46
|
+
from: 'images',
|
|
47
|
+
to: 'images',
|
|
48
|
+
}],
|
|
49
|
+
// OBS 或 OSS 配置(二选一)
|
|
50
|
+
obsConfig: {
|
|
51
|
+
access_key_id: 'XXX',
|
|
52
|
+
secret_access_key: 'XXX',
|
|
53
|
+
server: 'XXX',
|
|
54
|
+
bucket: 'XXX',
|
|
55
|
+
dir: 'weapp',
|
|
56
|
+
// 可选:单次 SDK 请求超时、重试次数,以及编译器无进展兜底超时(秒)
|
|
57
|
+
timeout: 15,
|
|
58
|
+
max_retry_count: 1,
|
|
59
|
+
operation_timeout: 35,
|
|
60
|
+
},
|
|
61
|
+
ossConfig: {
|
|
62
|
+
region: '<Your region>',
|
|
63
|
+
accessKeyId: '<Your AccessKeyId>',
|
|
64
|
+
accessKeySecret: '<Your AccessKeySecret>',
|
|
65
|
+
bucket: '<Your Bucket>',
|
|
66
|
+
dir: 'weapp',
|
|
67
|
+
},
|
|
97
68
|
};
|
|
98
69
|
```
|
|
99
70
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
## 开发监听限制
|
|
103
|
-
|
|
104
|
-
修改已有文件可以正常增量构建。开发监听期间新增页面、组件、分包,或后创建同名 `.less`、`.wxss`、`.wxml`、`.json` 文件后,需要重新启动 `dev`。生产 `build` 每次都会重新读取完整项目配置。
|
|
105
|
-
|
|
106
|
-
## 微信开发者工具配置
|
|
107
|
-
|
|
108
|
-
如果资源使用 CDN 上传,可以在 `src/project.config.json` 中忽略本地产物:
|
|
71
|
+
在 `project.config.json` 中忽略构建产物:
|
|
109
72
|
|
|
110
73
|
```json
|
|
111
|
-
{
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
]
|
|
117
|
-
}
|
|
74
|
+
"packOptions": {
|
|
75
|
+
"ignore": [
|
|
76
|
+
{ "type": "folder", "value": "assets" },
|
|
77
|
+
{ "type": "regexp", "value": "\\.map$" }
|
|
78
|
+
]
|
|
118
79
|
}
|
|
119
80
|
```
|
package/build/dev.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const webpack = require('webpack');
|
|
2
|
-
const chalk = require('chalk');
|
|
3
2
|
const { ENV } = require('./config/constants');
|
|
4
3
|
const webpackConfig = require('./webpack.config');
|
|
5
4
|
const { createCompilerHandler } = require('./utils/createCompilerHandler');
|
|
@@ -21,7 +20,7 @@ module.exports = async (opts) => {
|
|
|
21
20
|
),
|
|
22
21
|
);
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
compiler.watch(
|
|
25
24
|
{
|
|
26
25
|
aggregateTimeout: 300,
|
|
27
26
|
poll: false,
|
|
@@ -29,9 +28,4 @@ module.exports = async (opts) => {
|
|
|
29
28
|
},
|
|
30
29
|
createCompilerHandler('dev'),
|
|
31
30
|
);
|
|
32
|
-
|
|
33
|
-
if (!opts || opts.quiet !== true) {
|
|
34
|
-
console.log(chalk.cyan('dev 正在监听文件变化'));
|
|
35
|
-
}
|
|
36
|
-
return watching;
|
|
37
31
|
};
|
|
@@ -34,14 +34,12 @@ module.exports = async function loader(source) {
|
|
|
34
34
|
return src ? [attr, src] : null;
|
|
35
35
|
}),
|
|
36
36
|
);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const [attr, src] = resolvedAssets[index];
|
|
44
|
-
content = content.split(attr).join(withPublicPath(src));
|
|
37
|
+
for (let index = 0; index < assetResults.length; index += 1) {
|
|
38
|
+
const result = assetResults[index];
|
|
39
|
+
if (result) {
|
|
40
|
+
const [attr, src] = result;
|
|
41
|
+
content = content.split(attr).join(withPublicPath(src));
|
|
42
|
+
}
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
// wxml文件 - 并行 loadModule
|
package/build/plugin/index.js
CHANGED
|
@@ -9,25 +9,10 @@ const { RawSource } = require('webpack-sources');
|
|
|
9
9
|
|
|
10
10
|
const { addToUploadQueue } = require('../utils/upload');
|
|
11
11
|
const { compatiblePath } = require('../utils/compatiblePath');
|
|
12
|
-
const {
|
|
12
|
+
const { PATTERNS, ASSET_EXT_PATTERN, ASSETS_DIR } = require('../config/constants');
|
|
13
13
|
|
|
14
14
|
const pluginName = 'WeappCompilerPlugin';
|
|
15
15
|
|
|
16
|
-
async function uploadCompilationAssets(stats, compiler, assets, upload = addToUploadQueue) {
|
|
17
|
-
if (stats.hasErrors() || assets.length === 0) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
await upload(assets);
|
|
23
|
-
} catch (error) {
|
|
24
|
-
if (compiler.options.mode === ENV.PROD) {
|
|
25
|
-
throw error;
|
|
26
|
-
}
|
|
27
|
-
compiler.getInfrastructureLogger(pluginName).error(error);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
16
|
/**
|
|
32
17
|
* 检测产物中存在哪些公共模块和分包模块
|
|
33
18
|
*/
|
|
@@ -91,19 +76,13 @@ function injectGlobalModules(content, assetName, flags) {
|
|
|
91
76
|
|
|
92
77
|
// runtime 暴露到全局
|
|
93
78
|
if (assetName === 'runtime.js') {
|
|
94
|
-
const runtimeCachePattern = /\b(var|let|const)\s+__webpack_module_cache__\s*=\s*\{\};/;
|
|
95
|
-
if (!runtimeCachePattern.test(result)) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
'无法注入微信小程序 runtime:当前 webpack 产物中缺少 module cache 标记,请检查 webpack 版本',
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
79
|
result = result.replace(
|
|
101
|
-
|
|
102
|
-
|
|
80
|
+
'var __webpack_module_cache__ = {};',
|
|
81
|
+
`
|
|
103
82
|
if (!global.__webpack_module_cache__) {
|
|
104
83
|
global.__webpack_module_cache__ = {};
|
|
105
84
|
}
|
|
106
|
-
|
|
85
|
+
var __webpack_module_cache__ = global.__webpack_module_cache__;
|
|
107
86
|
global.__webpack_require__ = __webpack_require__;
|
|
108
87
|
`,
|
|
109
88
|
);
|
|
@@ -116,13 +95,13 @@ function injectGlobalModules(content, assetName, flags) {
|
|
|
116
95
|
'Function("r", "regeneratorRuntime = r")(runtime);',
|
|
117
96
|
'global.regeneratorRuntime = runtime',
|
|
118
97
|
);
|
|
119
|
-
if (
|
|
98
|
+
if (!/require('\.\/commons\.js')/.test(result) && flags.hasCommonJs) {
|
|
120
99
|
result = `require('./commons.js');\n${result}`;
|
|
121
100
|
}
|
|
122
|
-
if (
|
|
101
|
+
if (!/require('\.\/vendors\.js')/.test(result) && flags.hasVendorJs) {
|
|
123
102
|
result = `require('./vendors.js');\n${result}`;
|
|
124
103
|
}
|
|
125
|
-
if (
|
|
104
|
+
if (!/require('\.\/runtime\.js')/.test(result) && flags.hasRuntimeJs) {
|
|
126
105
|
result = `require('./runtime.js');\n${result}`;
|
|
127
106
|
}
|
|
128
107
|
}
|
|
@@ -188,10 +167,9 @@ class WeappPlugin {
|
|
|
188
167
|
apply(compiler) {
|
|
189
168
|
let obsAssets = [];
|
|
190
169
|
|
|
191
|
-
compiler.hooks.done.
|
|
192
|
-
|
|
170
|
+
compiler.hooks.done.tap(pluginName, () => {
|
|
171
|
+
addToUploadQueue([...obsAssets]);
|
|
193
172
|
obsAssets = [];
|
|
194
|
-
await uploadCompilationAssets(stats, compiler, assets);
|
|
195
173
|
});
|
|
196
174
|
|
|
197
175
|
compiler.hooks.compilation.tap(pluginName, (compilation) => {
|
|
@@ -250,7 +228,3 @@ class WeappPlugin {
|
|
|
250
228
|
}
|
|
251
229
|
|
|
252
230
|
module.exports = WeappPlugin;
|
|
253
|
-
module.exports._internals = {
|
|
254
|
-
injectGlobalModules,
|
|
255
|
-
uploadCompilationAssets,
|
|
256
|
-
};
|
package/build/prod.js
CHANGED
|
@@ -3,7 +3,7 @@ const TerserPlugin = require('terser-webpack-plugin');
|
|
|
3
3
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
|
4
4
|
const { ENV } = require('./config/constants');
|
|
5
5
|
const webpackConfig = require('./webpack.config');
|
|
6
|
-
const { createCompilerHandler
|
|
6
|
+
const { createCompilerHandler } = require('./utils/createCompilerHandler');
|
|
7
7
|
|
|
8
8
|
module.exports = async (opts) => {
|
|
9
9
|
// 生产环境禁用 filesystem cache,与 dev 同源:output.clean 后复用旧缓存会导致副作用产物漏生成,
|
|
@@ -16,7 +16,7 @@ module.exports = async (opts) => {
|
|
|
16
16
|
devtool: false,
|
|
17
17
|
output: {
|
|
18
18
|
clean: {
|
|
19
|
-
keep: /^weapp\.env\.json$/,
|
|
19
|
+
keep: /^(project\.config\.json|weapp\.env\.json)$/,
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
optimization: {
|
|
@@ -34,5 +34,5 @@ module.exports = async (opts) => {
|
|
|
34
34
|
),
|
|
35
35
|
);
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
compiler.run(createCompilerHandler('build'));
|
|
38
38
|
};
|
|
@@ -2,7 +2,7 @@ const path = require('path');
|
|
|
2
2
|
const fse = require('fs-extra');
|
|
3
3
|
const { DIST_DIR } = require('../config/constants');
|
|
4
4
|
|
|
5
|
-
const KEEP_FILES = new Set(['weapp.env.json']);
|
|
5
|
+
const KEEP_FILES = new Set(['project.config.json', 'weapp.env.json']);
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 开发模式启动时清理 dist 旧产物。
|
|
@@ -48,26 +48,6 @@ function createCompilerHandler(label, { failOnError = label === 'build' } = {})
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/**
|
|
52
|
-
* 运行一次 webpack 编译,并等待异步 done 钩子及 compiler.close 完成。
|
|
53
|
-
* 上传任务挂在 done.tapPromise 上,生产命令必须等待这里结束,才能可靠输出上传错误。
|
|
54
|
-
*/
|
|
55
|
-
function runCompilerOnce(compiler, handler) {
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
compiler.run((runError, stats) => {
|
|
58
|
-
compiler.close((closeError) => {
|
|
59
|
-
try {
|
|
60
|
-
handler(runError || closeError, stats);
|
|
61
|
-
resolve(stats);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
reject(error);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
51
|
module.exports = {
|
|
71
52
|
createCompilerHandler,
|
|
72
|
-
|
|
73
|
-
};
|
|
53
|
+
};
|
|
@@ -3,43 +3,27 @@ const path = require('path');
|
|
|
3
3
|
const fse = require('fs-extra');
|
|
4
4
|
const { ASSET_EXT_PATTERN, PATTERNS, SRC_DIR } = require('../config/constants');
|
|
5
5
|
|
|
6
|
-
function extractStyleUrls(style) {
|
|
7
|
-
const urls = [];
|
|
8
|
-
const urlPattern = /url\(\s*(?:(['"])(.*?)\1|([^)]*?))\s*\)/gi;
|
|
9
|
-
let match;
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line no-cond-assign
|
|
12
|
-
while ((match = urlPattern.exec(style)) !== null) {
|
|
13
|
-
const value = (match[2] !== undefined ? match[2] : match[3]).trim();
|
|
14
|
-
if (value) {
|
|
15
|
-
urls.push(value);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return urls;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
6
|
function getWxmlAssets(filePath, content) {
|
|
22
7
|
const resolvePath = (attr, dir) => {
|
|
23
|
-
return new Promise((resolve
|
|
8
|
+
return new Promise((resolve) => {
|
|
24
9
|
const isAbsolutePath = PATTERNS.ABSOLUTE_PATH.test(attr);
|
|
25
10
|
const request = isAbsolutePath ? attr.replace(PATTERNS.ABSOLUTE_PATH, '') : attr;
|
|
26
11
|
const resolveContext = isAbsolutePath ? SRC_DIR : dir;
|
|
27
12
|
|
|
28
13
|
this.resolve(resolveContext, request, async (err, result) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const fallbackPath = path.resolve(resolveContext, request);
|
|
14
|
+
let res = result;
|
|
15
|
+
if (err) {
|
|
16
|
+
const fallbackPath = path.resolve(resolveContext, request);
|
|
33
17
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
18
|
+
if (await fse.pathExists(fallbackPath)) {
|
|
19
|
+
res = fallbackPath;
|
|
20
|
+
resolve(res);
|
|
21
|
+
} else {
|
|
22
|
+
this.emitError(err);
|
|
23
|
+
resolve(res);
|
|
39
24
|
}
|
|
25
|
+
} else {
|
|
40
26
|
resolve(res);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
reject(error);
|
|
43
27
|
}
|
|
44
28
|
});
|
|
45
29
|
});
|
|
@@ -47,7 +31,8 @@ function getWxmlAssets(filePath, content) {
|
|
|
47
31
|
return new Promise((resolve, reject) => {
|
|
48
32
|
let allAttrs = [];
|
|
49
33
|
const parser = new htmlparser2.Parser({
|
|
50
|
-
onopentag: (name, attributes) => {
|
|
34
|
+
onopentag: async (name, attributes) => {
|
|
35
|
+
const reg = /url\(.*\)/g;
|
|
51
36
|
const { style } = attributes;
|
|
52
37
|
|
|
53
38
|
allAttrs = allAttrs.concat(
|
|
@@ -58,55 +43,60 @@ function getWxmlAssets(filePath, content) {
|
|
|
58
43
|
);
|
|
59
44
|
|
|
60
45
|
if (style) {
|
|
61
|
-
|
|
46
|
+
const styles = attributes.style.split(';');
|
|
47
|
+
styles.forEach((styleItem) => {
|
|
48
|
+
(styleItem.match(reg) || []).forEach((item) => {
|
|
49
|
+
allAttrs.push(
|
|
50
|
+
item
|
|
51
|
+
.replace(/^(url\(”)/g, '')
|
|
52
|
+
.replace(/^(url\(')/g, '')
|
|
53
|
+
.replace(/^(url\()/g, '')
|
|
54
|
+
.replace(/(“\)|'\)|\))$/g, ''),
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
62
58
|
}
|
|
63
59
|
},
|
|
64
60
|
onerror: (err) => {
|
|
65
61
|
reject(err);
|
|
66
62
|
},
|
|
67
63
|
onend: async () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.filter((item) => !/^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(item))
|
|
75
|
-
.filter((item) => !/{{.*}}/.test(item))
|
|
76
|
-
.filter((item) => !/\+.*\+/.test(item));
|
|
64
|
+
const filteredAttrs = allAttrs
|
|
65
|
+
.filter((item) => !!item)
|
|
66
|
+
.map((item) => item.split('?')[0])
|
|
67
|
+
.filter((item) => !/^(http:|https:)/.test(item))
|
|
68
|
+
.filter((item) => !/{{.*}}/.test(item))
|
|
69
|
+
.filter((item) => !/\+.*\+/.test(item));
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
const assets = filteredAttrs.filter((item) => ASSET_EXT_PATTERN.test(item));
|
|
72
|
+
const wxmls = filteredAttrs.filter((item) => PATTERNS.WXS_EXT.test(item) || PATTERNS.WXML_EXT.test(item));
|
|
80
73
|
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
const assetsImports = [];
|
|
75
|
+
const wxmlsImports = [];
|
|
83
76
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// 并行解析 asset 路径
|
|
96
|
-
const assetResults = await Promise.all(
|
|
97
|
-
assets.map(async (attr) => {
|
|
98
|
-
const result = await resolvePath(attr, path.parse(filePath).dir);
|
|
99
|
-
return result ? [attr, result] : null;
|
|
100
|
-
}),
|
|
101
|
-
);
|
|
102
|
-
for (let index = 0; index < assetResults.length; index += 1) {
|
|
103
|
-
if (assetResults[index]) assetsImports.push(assetResults[index]);
|
|
104
|
-
}
|
|
77
|
+
// 并行解析 wxml 路径
|
|
78
|
+
const wxmlResults = await Promise.all(
|
|
79
|
+
wxmls.map(async (attr) => {
|
|
80
|
+
const result = await resolvePath(attr, path.parse(filePath).dir);
|
|
81
|
+
return result ? [attr, result] : null;
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
for (let index = 0; index < wxmlResults.length; index += 1) {
|
|
85
|
+
if (wxmlResults[index]) wxmlsImports.push(wxmlResults[index]);
|
|
86
|
+
}
|
|
105
87
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
// 并行解析 asset 路径
|
|
89
|
+
const assetResults = await Promise.all(
|
|
90
|
+
assets.map(async (attr) => {
|
|
91
|
+
const result = await resolvePath(attr, path.parse(filePath).dir);
|
|
92
|
+
return result ? [attr, result] : null;
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
for (let index = 0; index < assetResults.length; index += 1) {
|
|
96
|
+
if (assetResults[index]) assetsImports.push(assetResults[index]);
|
|
109
97
|
}
|
|
98
|
+
|
|
99
|
+
resolve([assetsImports, wxmlsImports]);
|
|
110
100
|
},
|
|
111
101
|
});
|
|
112
102
|
parser.write(content);
|
|
@@ -116,5 +106,4 @@ function getWxmlAssets(filePath, content) {
|
|
|
116
106
|
|
|
117
107
|
module.exports = {
|
|
118
108
|
getWxmlAssets,
|
|
119
|
-
extractStyleUrls,
|
|
120
109
|
};
|
package/build/utils/storage.js
CHANGED
|
@@ -4,40 +4,18 @@ const { debounce } = require('throttle-debounce');
|
|
|
4
4
|
|
|
5
5
|
const tempDir = path.resolve(process.cwd(), '.temp');
|
|
6
6
|
const uploadJsonDir = path.join(tempDir, 'upload.json');
|
|
7
|
-
const uploadJsonTempDir = `${uploadJsonDir}.${process.pid}.tmp`;
|
|
8
7
|
let uploadJson = {};
|
|
8
|
+
const writeUploadJsonDebounce = debounce(300, () => {
|
|
9
|
+
fs.writeJSONSync(uploadJsonDir, uploadJson);
|
|
10
|
+
});
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
fs.writeJSONSync(uploadJsonTempDir, uploadJson);
|
|
13
|
-
fs.renameSync(uploadJsonTempDir, uploadJsonDir);
|
|
14
|
-
} catch (error) {
|
|
15
|
-
try {
|
|
16
|
-
fs.removeSync(uploadJsonTempDir);
|
|
17
|
-
} catch (cleanupError) {
|
|
18
|
-
console.warn('清理上传缓存临时文件失败:', cleanupError);
|
|
19
|
-
}
|
|
20
|
-
console.warn('写入上传缓存失败,本次构建将继续:', error);
|
|
21
|
-
}
|
|
12
|
+
if (!fs.existsSync(tempDir)) {
|
|
13
|
+
fs.mkdirSync(tempDir);
|
|
22
14
|
}
|
|
23
|
-
|
|
24
|
-
const writeUploadJsonDebounce = debounce(300, writeUploadJson);
|
|
25
|
-
|
|
26
|
-
fs.ensureDirSync(tempDir);
|
|
27
15
|
if (!fs.existsSync(uploadJsonDir)) {
|
|
28
|
-
|
|
16
|
+
fs.writeJSONSync(uploadJsonDir, uploadJson);
|
|
29
17
|
} else {
|
|
30
|
-
|
|
31
|
-
const stored = fs.readJSONSync(uploadJsonDir);
|
|
32
|
-
if (!stored || Array.isArray(stored) || typeof stored !== 'object') {
|
|
33
|
-
throw new TypeError('上传缓存必须是 JSON 对象');
|
|
34
|
-
}
|
|
35
|
-
uploadJson = stored;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
console.warn('上传缓存已损坏,将重建缓存:', error);
|
|
38
|
-
uploadJson = {};
|
|
39
|
-
writeUploadJson();
|
|
40
|
-
}
|
|
18
|
+
uploadJson = fs.readJSONSync(uploadJsonDir);
|
|
41
19
|
}
|
|
42
20
|
|
|
43
21
|
module.exports = {
|