hw-weapp-compiler 1.0.7 → 1.0.8
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 +4 -4
- package/build/config/getEntries.js +32 -10
- package/build/dev.js +1 -1
- package/build/loader/wxml-loader.js +1 -1
- package/build/plugin/index.js +13 -51
- package/build/prod.js +1 -1
- package/build/utils/createCompilerHandler.js +9 -1
- package/build/utils/getWxmlAssets.js +10 -4
- package/build/utils/loadModule.js +2 -2
- package/index.js +0 -0
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -17,12 +17,12 @@ npm i weapp-compiler@2.x -D
|
|
|
17
17
|
```bash
|
|
18
18
|
# 开发调试
|
|
19
19
|
npm run dev # 测试环境
|
|
20
|
-
npm run dev -s
|
|
21
|
-
npm run dev -p
|
|
20
|
+
npm run dev -- -s # 预发环境
|
|
21
|
+
npm run dev -- -p # 生产环境
|
|
22
22
|
|
|
23
23
|
# 生产发布
|
|
24
|
-
npm run build -d
|
|
25
|
-
npm run build -s
|
|
24
|
+
npm run build -- -d # 测试环境
|
|
25
|
+
npm run build -- -s # 预发环境
|
|
26
26
|
npm run build # 生产环境
|
|
27
27
|
```
|
|
28
28
|
|
|
@@ -2,7 +2,6 @@ const path = require('path');
|
|
|
2
2
|
const fse = require('fs-extra');
|
|
3
3
|
const { addNodeModulesUsingComponent } = require('../utils/isNodeModulesUsingComponent');
|
|
4
4
|
const { compatiblePath } = require('../utils/compatiblePath');
|
|
5
|
-
const { traverseDir } = require('../utils/traverseDir');
|
|
6
5
|
const { getAppConfig } = require('./getAppConfig');
|
|
7
6
|
const { PATTERNS, SRC_DIR } = require('./constants');
|
|
8
7
|
const appConfig = getAppConfig();
|
|
@@ -10,8 +9,17 @@ const appConfig = getAppConfig();
|
|
|
10
9
|
const entries = {
|
|
11
10
|
app: path.resolve(SRC_DIR, 'app'),
|
|
12
11
|
};
|
|
12
|
+
const visitedJsonFiles = new Set();
|
|
13
|
+
const entryFiles = [entries.app];
|
|
14
|
+
|
|
15
|
+
const addEntry = (entryKey, filePath) => {
|
|
16
|
+
entries[compatiblePath(entryKey)] = filePath;
|
|
17
|
+
entryFiles.push(filePath);
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
const addUsingComponents = (components, parent) => {
|
|
14
21
|
Object.keys(components).forEach((key) => {
|
|
22
|
+
const originalFilePath = components[key];
|
|
15
23
|
let filePath = components[key];
|
|
16
24
|
|
|
17
25
|
if (!PATTERNS.PLUGIN_PATH.test(filePath)) {
|
|
@@ -26,8 +34,9 @@ const addUsingComponents = (components, parent) => {
|
|
|
26
34
|
filePath = require.resolve(filePath);
|
|
27
35
|
filePath = filePath.replace(PATTERNS.JS_EXT, '');
|
|
28
36
|
} catch (error) {
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
throw new Error(
|
|
38
|
+
`解析 usingComponents "${key}" 的组件路径 "${originalFilePath}" 失败,父级目录:${parent}\n${error.message}`,
|
|
39
|
+
);
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
|
|
@@ -53,35 +62,48 @@ const addUsingComponents = (components, parent) => {
|
|
|
53
62
|
});
|
|
54
63
|
};
|
|
55
64
|
const readUsingComponents = (file) => {
|
|
65
|
+
const jsonFile = path.resolve(file);
|
|
66
|
+
|
|
67
|
+
if (visitedJsonFiles.has(jsonFile)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
visitedJsonFiles.add(jsonFile);
|
|
72
|
+
|
|
56
73
|
const json = fse.readJSONSync(file);
|
|
57
74
|
|
|
58
75
|
if (json.usingComponents) {
|
|
59
76
|
addUsingComponents(json.usingComponents, path.parse(file).dir);
|
|
60
77
|
}
|
|
61
78
|
};
|
|
79
|
+
const readEntryUsingComponents = (filePath) => {
|
|
80
|
+
const jsonFile = `${filePath}.json`;
|
|
81
|
+
|
|
82
|
+
if (fse.existsSync(jsonFile)) {
|
|
83
|
+
readUsingComponents(jsonFile);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
62
86
|
|
|
63
87
|
// pages
|
|
64
88
|
(appConfig.pages || []).forEach((page) => {
|
|
65
|
-
|
|
89
|
+
addEntry(page, path.resolve(SRC_DIR, page));
|
|
66
90
|
});
|
|
67
91
|
|
|
68
92
|
// tabbar
|
|
69
93
|
if (fse.existsSync(path.resolve(SRC_DIR, 'custom-tab-bar/index.js'))) {
|
|
70
|
-
|
|
94
|
+
addEntry('custom-tab-bar/index', path.resolve(SRC_DIR, 'custom-tab-bar/index'));
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
// subpackages
|
|
74
98
|
(appConfig.subpackages || []).forEach((pkg) => {
|
|
75
99
|
(pkg.pages || []).forEach((page) => {
|
|
76
|
-
|
|
100
|
+
addEntry(path.join(pkg.root, page), path.resolve(SRC_DIR, pkg.root, page));
|
|
77
101
|
});
|
|
78
102
|
});
|
|
79
103
|
|
|
80
104
|
// usingComponents
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
readUsingComponents(item);
|
|
84
|
-
}
|
|
105
|
+
entryFiles.forEach((filePath) => {
|
|
106
|
+
readEntryUsingComponents(filePath);
|
|
85
107
|
});
|
|
86
108
|
|
|
87
109
|
function getEntries() {
|
package/build/dev.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = (opts) => {
|
|
|
10
10
|
if (fse.existsSync(DIST_DIR)) {
|
|
11
11
|
const files = fse.readdirSync(DIST_DIR);
|
|
12
12
|
files.forEach((item) => {
|
|
13
|
-
if (
|
|
13
|
+
if (!/^(project\.config\.json|weapp\.env\.json)$/.test(item)) {
|
|
14
14
|
fse.removeSync(path.resolve(DIST_DIR, item));
|
|
15
15
|
}
|
|
16
16
|
});
|
|
@@ -38,7 +38,7 @@ module.exports = async function loader(source) {
|
|
|
38
38
|
const result = assetResults[index];
|
|
39
39
|
if (result) {
|
|
40
40
|
const [attr, src] = result;
|
|
41
|
-
content = content.
|
|
41
|
+
content = content.split(attr).join(withPublicPath(src));
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
package/build/plugin/index.js
CHANGED
|
@@ -2,20 +2,16 @@
|
|
|
2
2
|
* WeappPlugin - 微信小程序 webpack 构建插件
|
|
3
3
|
*
|
|
4
4
|
* 负责在构建产物中注入公共模块引用、runtime 全局暴露、分包公共模块引用,
|
|
5
|
-
*
|
|
5
|
+
* 确保小程序运行时能正确加载 webpack 产物。
|
|
6
6
|
*/
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const UglifyJS = require('uglify-js');
|
|
9
|
-
const hasha = require('hasha');
|
|
10
8
|
const { RawSource } = require('webpack-sources');
|
|
11
9
|
|
|
12
|
-
const { isNodeModulesUsingComponent } = require('../utils/isNodeModulesUsingComponent');
|
|
13
10
|
const { addToUploadQueue } = require('../utils/upload');
|
|
14
11
|
const { compatiblePath } = require('../utils/compatiblePath');
|
|
15
|
-
const {
|
|
12
|
+
const { PATTERNS, ASSET_EXT_PATTERN, ASSETS_DIR } = require('../config/constants');
|
|
16
13
|
|
|
17
14
|
const pluginName = 'WeappCompilerPlugin';
|
|
18
|
-
const contentCache = {};
|
|
19
15
|
|
|
20
16
|
/**
|
|
21
17
|
* 检测产物中存在哪些公共模块和分包模块
|
|
@@ -123,6 +119,15 @@ function injectGlobalModules(content, assetName, flags) {
|
|
|
123
119
|
return result;
|
|
124
120
|
}
|
|
125
121
|
|
|
122
|
+
function getRelativeModulePath(from, to) {
|
|
123
|
+
const relativePath = compatiblePath(path.relative(from, to));
|
|
124
|
+
|
|
125
|
+
if (/^(\.\/|\.\.\/)/.test(relativePath)) {
|
|
126
|
+
return relativePath;
|
|
127
|
+
}
|
|
128
|
+
return `./${relativePath}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
126
131
|
/**
|
|
127
132
|
* 注入分包公共模块引用
|
|
128
133
|
*/
|
|
@@ -141,18 +146,14 @@ function injectSubpackageRequires(content, assetName, subpackages) {
|
|
|
141
146
|
PATTERNS.JS_EXT.test(assetName) &&
|
|
142
147
|
!/'subpackage_common\.js'\);/.test(result)
|
|
143
148
|
) {
|
|
144
|
-
result = `require('${
|
|
145
|
-
path.relative(path.parse(assetName).dir, res.js),
|
|
146
|
-
)}');\n${result}`;
|
|
149
|
+
result = `require('${getRelativeModulePath(path.parse(assetName).dir, res.js)}');\n${result}`;
|
|
147
150
|
}
|
|
148
151
|
if (
|
|
149
152
|
res.wxss &&
|
|
150
153
|
PATTERNS.WXSS_EXT.test(assetName) &&
|
|
151
154
|
!/'subpackage_common\.wxss';/.test(result)
|
|
152
155
|
) {
|
|
153
|
-
result = `@import '${
|
|
154
|
-
path.relative(path.parse(assetName).dir, res.wxss),
|
|
155
|
-
)}';\n${result}`;
|
|
156
|
+
result = `@import '${getRelativeModulePath(path.parse(assetName).dir, res.wxss)}';\n${result}`;
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
});
|
|
@@ -160,43 +161,6 @@ function injectSubpackageRequires(content, assetName, subpackages) {
|
|
|
160
161
|
return result;
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
/**
|
|
164
|
-
* 在开发模式下压缩公共模块代码
|
|
165
|
-
*/
|
|
166
|
-
function minifyCommonModules(content, assetName, isJs, isDev) {
|
|
167
|
-
if (!isDev) {
|
|
168
|
-
return content;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const isCommon = assetName === 'commons.js' || assetName === 'vendors.js';
|
|
172
|
-
const isNodeModule = isNodeModulesUsingComponent(assetName);
|
|
173
|
-
|
|
174
|
-
if (!isCommon && !isNodeModule) {
|
|
175
|
-
return content;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!isJs) {
|
|
179
|
-
return content;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const hash = hasha(content);
|
|
183
|
-
if (contentCache[assetName] && contentCache[assetName].hash === hash) {
|
|
184
|
-
return contentCache[assetName].content;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const result = UglifyJS.minify(content, {
|
|
188
|
-
mangle: false,
|
|
189
|
-
compress: {
|
|
190
|
-
drop_console: false,
|
|
191
|
-
drop_debugger: false,
|
|
192
|
-
},
|
|
193
|
-
sourceMap: false,
|
|
194
|
-
}).code;
|
|
195
|
-
|
|
196
|
-
contentCache[assetName] = { hash, content: result };
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
164
|
class WeappPlugin {
|
|
201
165
|
constructor() {}
|
|
202
166
|
|
|
@@ -237,7 +201,6 @@ class WeappPlugin {
|
|
|
237
201
|
await Promise.all(
|
|
238
202
|
items.map(async (asset) => {
|
|
239
203
|
const assetName = compatiblePath(asset.name);
|
|
240
|
-
const isJs = PATTERNS.JS_EXT.test(assetName);
|
|
241
204
|
let content = asset.source.source();
|
|
242
205
|
|
|
243
206
|
if (content.toString) {
|
|
@@ -246,7 +209,6 @@ class WeappPlugin {
|
|
|
246
209
|
|
|
247
210
|
content = injectGlobalModules(content, assetName, flags);
|
|
248
211
|
content = injectSubpackageRequires(content, assetName, subpackages);
|
|
249
|
-
content = minifyCommonModules(content, assetName, isJs, compiler.options.mode === ENV.DEV);
|
|
250
212
|
|
|
251
213
|
compilation.updateAsset(asset.name, new RawSource(content));
|
|
252
214
|
}),
|
package/build/prod.js
CHANGED
|
@@ -4,11 +4,18 @@ const chalk = require('chalk');
|
|
|
4
4
|
* 创建 webpack 编译结果回调处理器
|
|
5
5
|
* @param {string} label - 构建阶段标签,如 'dev' 或 'build'
|
|
6
6
|
*/
|
|
7
|
-
function createCompilerHandler(label) {
|
|
7
|
+
function createCompilerHandler(label, { failOnError = label === 'build' } = {}) {
|
|
8
|
+
const markFailed = () => {
|
|
9
|
+
if (failOnError) {
|
|
10
|
+
process.exitCode = 1;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
8
14
|
return (err, stats) => {
|
|
9
15
|
if (err) {
|
|
10
16
|
console.error(chalk.red(`${label} failed with fatal error:`));
|
|
11
17
|
console.error(err);
|
|
18
|
+
markFailed();
|
|
12
19
|
return;
|
|
13
20
|
}
|
|
14
21
|
|
|
@@ -20,6 +27,7 @@ function createCompilerHandler(label) {
|
|
|
20
27
|
}),
|
|
21
28
|
);
|
|
22
29
|
console.error(chalk.red(`${label} completed with errors`));
|
|
30
|
+
markFailed();
|
|
23
31
|
return;
|
|
24
32
|
}
|
|
25
33
|
|
|
@@ -6,11 +6,17 @@ const { ASSET_EXT_PATTERN, PATTERNS, SRC_DIR } = require('../config/constants');
|
|
|
6
6
|
function getWxmlAssets(filePath, content) {
|
|
7
7
|
const resolvePath = (attr, dir) => {
|
|
8
8
|
return new Promise((resolve) => {
|
|
9
|
-
|
|
9
|
+
const isAbsolutePath = PATTERNS.ABSOLUTE_PATH.test(attr);
|
|
10
|
+
const request = isAbsolutePath ? attr.replace(PATTERNS.ABSOLUTE_PATH, '') : attr;
|
|
11
|
+
const resolveContext = isAbsolutePath ? SRC_DIR : dir;
|
|
12
|
+
|
|
13
|
+
this.resolve(resolveContext, request, async (err, result) => {
|
|
10
14
|
let res = result;
|
|
11
15
|
if (err) {
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const fallbackPath = path.resolve(resolveContext, request);
|
|
17
|
+
|
|
18
|
+
if (await fse.pathExists(fallbackPath)) {
|
|
19
|
+
res = fallbackPath;
|
|
14
20
|
resolve(res);
|
|
15
21
|
} else {
|
|
16
22
|
this.emitError(err);
|
|
@@ -63,7 +69,7 @@ function getWxmlAssets(filePath, content) {
|
|
|
63
69
|
.filter((item) => !/\+.*\+/.test(item));
|
|
64
70
|
|
|
65
71
|
const assets = filteredAttrs.filter((item) => ASSET_EXT_PATTERN.test(item));
|
|
66
|
-
const wxmls =
|
|
72
|
+
const wxmls = filteredAttrs.filter((item) => PATTERNS.WXS_EXT.test(item) || PATTERNS.WXML_EXT.test(item));
|
|
67
73
|
|
|
68
74
|
const assetsImports = [];
|
|
69
75
|
const wxmlsImports = [];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
function loadModule(file) {
|
|
2
|
-
return new Promise((resolve) => {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
3
|
this.addDependency(file);
|
|
4
4
|
this.loadModule(file, (err, src) => {
|
|
5
5
|
if (err) {
|
|
6
6
|
this.emitError(err);
|
|
7
|
-
|
|
7
|
+
reject(err);
|
|
8
8
|
} else {
|
|
9
9
|
resolve(src);
|
|
10
10
|
}
|
package/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hw-weapp-compiler",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "基于 webpack5 的小程序构建工具,兼容 Node.js 14~24",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"esdk-obs-nodejs": "^3.21.3",
|
|
30
30
|
"file-loader": "^6.2.0",
|
|
31
31
|
"fs-extra": "^9.1.0",
|
|
32
|
-
"hasha": "^5.2.2",
|
|
33
32
|
"htmlparser2": "^6.0.1",
|
|
34
33
|
"less": "^4.1.1",
|
|
35
34
|
"less-loader": "^8.0.0",
|
|
@@ -40,7 +39,6 @@
|
|
|
40
39
|
"progress": "^2.0.3",
|
|
41
40
|
"terser-webpack-plugin": "^5.6.1",
|
|
42
41
|
"throttle-debounce": "^3.0.1",
|
|
43
|
-
"uglify-js": "^3.14.2",
|
|
44
42
|
"url-loader": "^4.1.1",
|
|
45
43
|
"webpack": "^5.61.0",
|
|
46
44
|
"webpack-bundle-analyzer": "^4.4.0",
|