hw-weapp-compiler 1.0.0 → 1.0.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/build/config/constants.js +37 -0
- package/build/config/getAppConfig.js +9 -4
- package/build/config/getConfig.js +3 -1
- package/build/config/{getEntrys.js → getEntries.js} +26 -23
- package/build/dev.js +3 -19
- package/build/loader/js-loader.js +10 -4
- package/build/loader/wxml-loader.js +8 -2
- package/build/loader/wxs-loader.js +7 -1
- package/build/plugin/index.js +197 -169
- package/build/prod.js +3 -19
- package/build/utils/buildEnv.js +10 -2
- package/build/utils/compatiblePath.js +3 -1
- package/build/utils/createCompilerHandler.js +29 -0
- package/build/utils/getWxmlAssets.js +9 -17
- package/build/utils/isSubpackage.js +6 -4
- package/build/utils/loadModule.js +4 -7
- package/build/utils/traverseDir.js +3 -1
- package/build/utils/upload.js +14 -22
- package/build/webpack.config.js +51 -74
- package/index.js +1 -1
- package/package.json +1 -3
- package/build/config/env.js +0 -7
- package/build/config/getAssets.js +0 -1
- package/build/config/getContext.js +0 -5
- package/build/config/getEnv.js +0 -5
- package/build/config/getOutput.js +0 -7
- package/build/config/getResourceAccept.js +0 -1
- package/build/utils/recordEnv.js +0 -11
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
const ENV = {
|
|
4
|
+
DEV: 'development',
|
|
5
|
+
PROD: 'production',
|
|
6
|
+
SIMULATION: 'simulation',
|
|
7
|
+
UNKNOWN: 'unknown',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const PATTERNS = {
|
|
11
|
+
NODE_MODULES: /node_modules/,
|
|
12
|
+
JS_EXT: /\.js$/,
|
|
13
|
+
WXSS_EXT: /\.wxss$/,
|
|
14
|
+
WXML_EXT: /\.wxml$/,
|
|
15
|
+
WXS_EXT: /\.wxs$/,
|
|
16
|
+
LESS_EXT: /\.less$/,
|
|
17
|
+
CSS_EXT: /\.css$/,
|
|
18
|
+
JSON_EXT: /\.json$/,
|
|
19
|
+
STYLE_EXTS: /\.(less|wxss|css)$/i,
|
|
20
|
+
PLUGIN_PATH: /^(plugin:|plugin-private:|weui-miniprogram)/,
|
|
21
|
+
ABSOLUTE_PATH: /^\//,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const ASSET_EXT_PATTERN = /\.(png|jpg|gif|jpeg|svg|ttf|woff|eot|woff2|otf|mp3|mp4|wav|html)$/i;
|
|
25
|
+
|
|
26
|
+
const SRC_DIR = path.resolve(process.cwd(), 'src');
|
|
27
|
+
const DIST_DIR = path.resolve(process.cwd(), 'dist');
|
|
28
|
+
const ASSETS_DIR = 'assets';
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
ENV,
|
|
32
|
+
PATTERNS,
|
|
33
|
+
ASSET_EXT_PATTERN,
|
|
34
|
+
SRC_DIR,
|
|
35
|
+
DIST_DIR,
|
|
36
|
+
ASSETS_DIR,
|
|
37
|
+
};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fse = require('fs-extra');
|
|
3
|
-
const
|
|
3
|
+
const { SRC_DIR } = require('./constants');
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
let _appConfig = null;
|
|
6
6
|
|
|
7
7
|
function getAppConfig() {
|
|
8
|
-
|
|
8
|
+
if (!_appConfig) {
|
|
9
|
+
_appConfig = fse.readJSONSync(path.resolve(SRC_DIR, 'app.json'));
|
|
10
|
+
}
|
|
11
|
+
return _appConfig;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
module.exports =
|
|
14
|
+
module.exports = {
|
|
15
|
+
getAppConfig,
|
|
16
|
+
};
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fse = require('fs-extra');
|
|
3
|
-
const getContext = require('./getContext');
|
|
4
3
|
const { addNodeModulesUsingComponent } = require('../utils/isNodeModulesUsingComponent');
|
|
5
|
-
const compatiblePath = require('../utils/compatiblePath');
|
|
6
|
-
const traverseDir = require('../utils/traverseDir');
|
|
7
|
-
const getAppConfig = require('./getAppConfig');
|
|
8
|
-
|
|
9
|
-
const context = getContext();
|
|
4
|
+
const { compatiblePath } = require('../utils/compatiblePath');
|
|
5
|
+
const { traverseDir } = require('../utils/traverseDir');
|
|
6
|
+
const { getAppConfig } = require('./getAppConfig');
|
|
7
|
+
const { PATTERNS, SRC_DIR } = require('./constants');
|
|
10
8
|
const appConfig = getAppConfig();
|
|
11
9
|
|
|
12
|
-
const
|
|
13
|
-
app: path.resolve(
|
|
10
|
+
const entries = {
|
|
11
|
+
app: path.resolve(SRC_DIR, 'app'),
|
|
14
12
|
};
|
|
15
13
|
const addUsingComponents = (components, parent) => {
|
|
16
14
|
Object.keys(components).forEach((key) => {
|
|
17
15
|
let filePath = components[key];
|
|
18
16
|
|
|
19
|
-
if (
|
|
20
|
-
if (
|
|
21
|
-
filePath = path.resolve(
|
|
17
|
+
if (!PATTERNS.PLUGIN_PATH.test(filePath)) {
|
|
18
|
+
if (PATTERNS.ABSOLUTE_PATH.test(filePath)) {
|
|
19
|
+
filePath = path.resolve(SRC_DIR, filePath.replace(PATTERNS.ABSOLUTE_PATH, ''));
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
if (fse.existsSync(`${path.resolve(parent, filePath)}.js`)) {
|
|
@@ -26,7 +24,7 @@ const addUsingComponents = (components, parent) => {
|
|
|
26
24
|
} else {
|
|
27
25
|
try {
|
|
28
26
|
filePath = require.resolve(filePath);
|
|
29
|
-
filePath = filePath.replace(
|
|
27
|
+
filePath = filePath.replace(PATTERNS.JS_EXT, '');
|
|
30
28
|
} catch (error) {
|
|
31
29
|
console.error(error);
|
|
32
30
|
return;
|
|
@@ -40,18 +38,17 @@ const addUsingComponents = (components, parent) => {
|
|
|
40
38
|
|
|
41
39
|
let entryKey = filePath;
|
|
42
40
|
|
|
43
|
-
if (
|
|
44
|
-
// eslint-disable-next-line
|
|
41
|
+
if (PATTERNS.NODE_MODULES.test(filePath)) {
|
|
45
42
|
entryKey = compatiblePath(filePath).split('/node_modules/')[1];
|
|
46
43
|
|
|
47
44
|
addNodeModulesUsingComponent(entryKey);
|
|
48
45
|
} else {
|
|
49
|
-
entryKey = path.relative(
|
|
46
|
+
entryKey = path.relative(SRC_DIR, filePath);
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
entryKey = compatiblePath(entryKey);
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
entries[entryKey] = filePath;
|
|
55
52
|
}
|
|
56
53
|
});
|
|
57
54
|
};
|
|
@@ -65,26 +62,32 @@ const readUsingComponents = (file) => {
|
|
|
65
62
|
|
|
66
63
|
// pages
|
|
67
64
|
(appConfig.pages || []).forEach((page) => {
|
|
68
|
-
|
|
65
|
+
entries[page] = path.resolve(SRC_DIR, page);
|
|
69
66
|
});
|
|
70
67
|
|
|
71
68
|
// tabbar
|
|
72
|
-
if (fse.existsSync(path.resolve(
|
|
73
|
-
|
|
69
|
+
if (fse.existsSync(path.resolve(SRC_DIR, 'custom-tab-bar/index.js'))) {
|
|
70
|
+
entries['custom-tab-bar/index'] = path.resolve(SRC_DIR, 'custom-tab-bar/index');
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
// subpackages
|
|
77
74
|
(appConfig.subpackages || []).forEach((pkg) => {
|
|
78
75
|
(pkg.pages || []).forEach((page) => {
|
|
79
|
-
|
|
76
|
+
entries[compatiblePath(path.join(pkg.root, page))] = path.resolve(SRC_DIR, pkg.root, page);
|
|
80
77
|
});
|
|
81
78
|
});
|
|
82
79
|
|
|
83
80
|
// usingComponents
|
|
84
|
-
traverseDir(
|
|
85
|
-
if (
|
|
81
|
+
traverseDir(SRC_DIR).forEach((item) => {
|
|
82
|
+
if (PATTERNS.JSON_EXT.test(item)) {
|
|
86
83
|
readUsingComponents(item);
|
|
87
84
|
}
|
|
88
85
|
});
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
function getEntries() {
|
|
88
|
+
return entries;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
getEntries,
|
|
93
|
+
};
|
package/build/dev.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
1
|
const webpack = require('webpack');
|
|
3
|
-
const ENV = require('./config/
|
|
2
|
+
const { ENV } = require('./config/constants');
|
|
4
3
|
const webpackConfig = require('./webpack.config');
|
|
4
|
+
const { createCompilerHandler } = require('./utils/createCompilerHandler');
|
|
5
5
|
|
|
6
6
|
module.exports = (opts) => {
|
|
7
7
|
const compiler = webpack(
|
|
@@ -14,21 +14,5 @@ module.exports = (opts) => {
|
|
|
14
14
|
),
|
|
15
15
|
);
|
|
16
16
|
|
|
17
|
-
compiler.watch({}, (
|
|
18
|
-
if (err) {
|
|
19
|
-
console.error(err);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (stats.hasErrors()) {
|
|
24
|
-
console.log(
|
|
25
|
-
stats.toString({
|
|
26
|
-
chunks: false, // Makes the build much quieter
|
|
27
|
-
colors: true, // Shows colors in the console
|
|
28
|
-
}),
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
console.log(chalk.green(`completed in ${(stats.endTime - stats.startTime) / 1000} seconds`));
|
|
33
|
-
});
|
|
17
|
+
compiler.watch({}, createCompilerHandler('dev'));
|
|
34
18
|
};
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-loader - 微信小程序 JS 加载器
|
|
3
|
+
*
|
|
4
|
+
* 为页面/组件入口 JS 自动注入同名的样式文件 import 和依赖模块,
|
|
5
|
+
* 确保小程序运行时能正确加载关联资源。
|
|
6
|
+
*/
|
|
1
7
|
const path = require('path');
|
|
2
8
|
const fse = require('fs-extra');
|
|
3
|
-
const
|
|
4
|
-
const loadModule = require('../utils/loadModule');
|
|
9
|
+
const { getEntries } = require('../config/getEntries');
|
|
10
|
+
const { loadModule } = require('../utils/loadModule');
|
|
5
11
|
|
|
6
|
-
const
|
|
12
|
+
const entries = getEntries();
|
|
7
13
|
|
|
8
14
|
module.exports = async function loader(source) {
|
|
9
15
|
this.cacheable(true);
|
|
@@ -14,7 +20,7 @@ module.exports = async function loader(source) {
|
|
|
14
20
|
|
|
15
21
|
const imports = [sourceStr];
|
|
16
22
|
|
|
17
|
-
if (Object.values(
|
|
23
|
+
if (Object.values(entries).indexOf(path.resolve(fileInfo.dir, fileInfo.name)) !== -1) {
|
|
18
24
|
const exts = ['.less', '.wxss', '.css', '.json', '.wxml'];
|
|
19
25
|
|
|
20
26
|
for (let index = 0; index < exts.length; index += 1) {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* wxml-loader - 微信小程序 wxml 模板加载器
|
|
3
|
+
*
|
|
4
|
+
* 解析 wxml 文件中的资源引用(图片等)和 wxml/wxs 引用,
|
|
5
|
+
* 将资源路径替换为构建产物路径,并将引用的 wxml/wxs 模块加入依赖。
|
|
6
|
+
*/
|
|
7
|
+
const { getWxmlAssets } = require('../utils/getWxmlAssets');
|
|
8
|
+
const { loadModule } = require('../utils/loadModule');
|
|
3
9
|
|
|
4
10
|
module.exports = async function loader(source) {
|
|
5
11
|
this.cacheable(true);
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wxs-loader - 微信小程序 wxs 脚本加载器
|
|
3
|
+
*
|
|
4
|
+
* 解析 wxs 文件中的 require 调用,将被引用的模块加入 webpack 依赖图,
|
|
5
|
+
* 确保构建时 wxs 的依赖被正确追踪。
|
|
6
|
+
*/
|
|
1
7
|
const path = require('path');
|
|
2
|
-
const loadModule = require('../utils/loadModule');
|
|
8
|
+
const { loadModule } = require('../utils/loadModule');
|
|
3
9
|
|
|
4
10
|
module.exports = async function loader(source) {
|
|
5
11
|
this.cacheable(true);
|
package/build/plugin/index.js
CHANGED
|
@@ -1,27 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeappPlugin - 微信小程序 webpack 构建插件
|
|
3
|
+
*
|
|
4
|
+
* 负责在构建产物中注入公共模块引用、runtime 全局暴露、分包公共模块引用,
|
|
5
|
+
* 以及在开发模式下压缩公共模块代码。
|
|
6
|
+
*/
|
|
1
7
|
const path = require('path');
|
|
2
8
|
const UglifyJS = require('uglify-js');
|
|
3
9
|
const hasha = require('hasha');
|
|
4
10
|
const { RawSource } = require('webpack-sources');
|
|
5
11
|
|
|
6
12
|
const { isNodeModulesUsingComponent } = require('../utils/isNodeModulesUsingComponent');
|
|
7
|
-
const getAssets = require('../config/getAssets');
|
|
8
13
|
const { addToUploadQueue } = require('../utils/upload');
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const ENV = require('../config/env');
|
|
14
|
+
const { compatiblePath } = require('../utils/compatiblePath');
|
|
15
|
+
const { ENV, PATTERNS, ASSET_EXT_PATTERN, ASSETS_DIR } = require('../config/constants');
|
|
12
16
|
|
|
13
|
-
const assetsDir = getAssets();
|
|
14
17
|
const pluginName = 'WeappCompilerPlugin';
|
|
15
18
|
const contentCache = {};
|
|
16
19
|
|
|
20
|
+
/**
|
|
21
|
+
* 检测产物中存在哪些公共模块和分包模块
|
|
22
|
+
*/
|
|
23
|
+
function detectCommonModules(items) {
|
|
24
|
+
const flags = {
|
|
25
|
+
hasCommonWxss: false,
|
|
26
|
+
hasVendorWxss: false,
|
|
27
|
+
hasCommonJs: false,
|
|
28
|
+
hasVendorJs: false,
|
|
29
|
+
hasRuntimeJs: false,
|
|
30
|
+
};
|
|
31
|
+
const subpackages = {};
|
|
32
|
+
|
|
33
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
34
|
+
const item = items[index];
|
|
35
|
+
|
|
36
|
+
if (!flags.hasCommonWxss && item.name === 'commons.wxss') {
|
|
37
|
+
flags.hasCommonWxss = true;
|
|
38
|
+
}
|
|
39
|
+
if (!flags.hasVendorWxss && item.name === 'vendors_wxss.wxss') {
|
|
40
|
+
flags.hasVendorWxss = true;
|
|
41
|
+
}
|
|
42
|
+
if (!flags.hasCommonJs && item.name === 'commons.js') {
|
|
43
|
+
flags.hasCommonJs = true;
|
|
44
|
+
}
|
|
45
|
+
if (!flags.hasVendorJs && item.name === 'vendors.js') {
|
|
46
|
+
flags.hasVendorJs = true;
|
|
47
|
+
}
|
|
48
|
+
if (!flags.hasRuntimeJs && item.name === 'runtime.js') {
|
|
49
|
+
flags.hasRuntimeJs = true;
|
|
50
|
+
}
|
|
51
|
+
if (/subpackage_common/.test(item.name)) {
|
|
52
|
+
const pathInfo = path.parse(item.name);
|
|
53
|
+
const dir = compatiblePath(pathInfo.dir);
|
|
54
|
+
|
|
55
|
+
if (!subpackages[dir]) {
|
|
56
|
+
subpackages[dir] = { js: '', wxss: '' };
|
|
57
|
+
}
|
|
58
|
+
if (PATTERNS.JS_EXT.test(item.name)) {
|
|
59
|
+
subpackages[dir].js = compatiblePath(item.name);
|
|
60
|
+
}
|
|
61
|
+
if (PATTERNS.WXSS_EXT.test(item.name)) {
|
|
62
|
+
subpackages[dir].wxss = compatiblePath(item.name);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { flags, subpackages };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 注入全局引用模块和公共模块到各个 JS/WXSS 文件
|
|
72
|
+
*/
|
|
73
|
+
function injectGlobalModules(content, assetName, flags) {
|
|
74
|
+
let result = content;
|
|
75
|
+
|
|
76
|
+
// 注入全局 var self = global
|
|
77
|
+
if (PATTERNS.JS_EXT.test(assetName) && !/(var self = global;)/.test(result)) {
|
|
78
|
+
result = `var self = global; \n${result}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// runtime 暴露到全局
|
|
82
|
+
if (assetName === 'runtime.js') {
|
|
83
|
+
result = result.replace(
|
|
84
|
+
'var __webpack_module_cache__ = {};',
|
|
85
|
+
`
|
|
86
|
+
if (!global.__webpack_module_cache__) {
|
|
87
|
+
global.__webpack_module_cache__ = {};
|
|
88
|
+
}
|
|
89
|
+
var __webpack_module_cache__ = global.__webpack_module_cache__;
|
|
90
|
+
global.__webpack_require__ = __webpack_require__;
|
|
91
|
+
`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 注入公共模块 js
|
|
96
|
+
if (assetName === 'app.js') {
|
|
97
|
+
// sdk2.17.3 window 下没有 regeneratorRuntime
|
|
98
|
+
result = result.replace(
|
|
99
|
+
'Function("r", "regeneratorRuntime = r")(runtime);',
|
|
100
|
+
'global.regeneratorRuntime = runtime',
|
|
101
|
+
);
|
|
102
|
+
if (!/require('\.\/commons\.js')/.test(result) && flags.hasCommonJs) {
|
|
103
|
+
result = `require('./commons.js');\n${result}`;
|
|
104
|
+
}
|
|
105
|
+
if (!/require('\.\/vendors\.js')/.test(result) && flags.hasVendorJs) {
|
|
106
|
+
result = `require('./vendors.js');\n${result}`;
|
|
107
|
+
}
|
|
108
|
+
if (!/require('\.\/runtime\.js')/.test(result) && flags.hasRuntimeJs) {
|
|
109
|
+
result = `require('./runtime.js');\n${result}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 注入公共模块 css
|
|
114
|
+
if (assetName === 'app.wxss') {
|
|
115
|
+
if (!/@import '\.\/commons\.wxss'/.test(result) && flags.hasCommonWxss) {
|
|
116
|
+
result = `@import './commons.wxss';\n${result}`;
|
|
117
|
+
}
|
|
118
|
+
if (!/@import '\.\/vendors_wxss\.wxss'/.test(result) && flags.hasVendorWxss) {
|
|
119
|
+
result = `@import './vendors_wxss.wxss';\n${result}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 注入分包公共模块引用
|
|
128
|
+
*/
|
|
129
|
+
function injectSubpackageRequires(content, assetName, subpackages) {
|
|
130
|
+
let result = content;
|
|
131
|
+
|
|
132
|
+
Object.keys(subpackages).forEach((subpackage) => {
|
|
133
|
+
const res = subpackages[subpackage];
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
assetName.startsWith(subpackage) &&
|
|
137
|
+
!/(subpackage_common\.(js|wxss))$/.test(assetName)
|
|
138
|
+
) {
|
|
139
|
+
if (
|
|
140
|
+
res.js &&
|
|
141
|
+
PATTERNS.JS_EXT.test(assetName) &&
|
|
142
|
+
!/'subpackage_common\.js'\);/.test(result)
|
|
143
|
+
) {
|
|
144
|
+
result = `require('${compatiblePath(
|
|
145
|
+
path.relative(path.parse(assetName).dir, res.js),
|
|
146
|
+
)}');\n${result}`;
|
|
147
|
+
}
|
|
148
|
+
if (
|
|
149
|
+
res.wxss &&
|
|
150
|
+
PATTERNS.WXSS_EXT.test(assetName) &&
|
|
151
|
+
!/'subpackage_common\.wxss';/.test(result)
|
|
152
|
+
) {
|
|
153
|
+
result = `@import '${compatiblePath(
|
|
154
|
+
path.relative(path.parse(assetName).dir, res.wxss),
|
|
155
|
+
)}';\n${result}`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
|
|
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
|
+
|
|
17
200
|
class WeappPlugin {
|
|
18
|
-
// eslint-disable-next-line
|
|
19
201
|
constructor() {}
|
|
20
202
|
|
|
21
|
-
// eslint-disable-next-line
|
|
22
203
|
apply(compiler) {
|
|
23
|
-
// const { RawSource } = compiler.webpack.sources;
|
|
24
|
-
|
|
25
204
|
let obsAssets = [];
|
|
26
205
|
|
|
27
206
|
compiler.hooks.done.tap(pluginName, () => {
|
|
@@ -37,7 +216,7 @@ class WeappPlugin {
|
|
|
37
216
|
(assets) => {
|
|
38
217
|
obsAssets = obsAssets.concat(
|
|
39
218
|
Object.keys(assets).filter((key) => {
|
|
40
|
-
return
|
|
219
|
+
return ASSET_EXT_PATTERN.test(key) && key.includes(`${ASSETS_DIR}/`);
|
|
41
220
|
}),
|
|
42
221
|
);
|
|
43
222
|
},
|
|
@@ -49,177 +228,26 @@ class WeappPlugin {
|
|
|
49
228
|
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
|
50
229
|
},
|
|
51
230
|
async (assets) => {
|
|
52
|
-
// this callback will run against assets added later by plugins.
|
|
53
231
|
const items = Object.entries(assets)
|
|
54
|
-
.map(([name, source]) => {
|
|
55
|
-
|
|
56
|
-
name,
|
|
57
|
-
source,
|
|
58
|
-
};
|
|
59
|
-
})
|
|
60
|
-
.filter((item) => {
|
|
61
|
-
return /(\.(js|wxss))$/g.test(item.name);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
let hasCommonWxss = false;
|
|
65
|
-
let hasVendorWxss = false;
|
|
66
|
-
let hasCommonJs = false;
|
|
67
|
-
let hasRuntimeJs = false;
|
|
68
|
-
let hasVendorJs = false;
|
|
69
|
-
const subpackages = {};
|
|
70
|
-
|
|
71
|
-
// 检测公共模块
|
|
72
|
-
for (let index = 0; index < items.length; index += 1) {
|
|
73
|
-
const item = items[index];
|
|
232
|
+
.map(([name, source]) => ({ name, source }))
|
|
233
|
+
.filter((item) => PATTERNS.JS_EXT.test(item.name) || PATTERNS.WXSS_EXT.test(item.name));
|
|
74
234
|
|
|
75
|
-
|
|
76
|
-
hasCommonWxss = true;
|
|
77
|
-
}
|
|
78
|
-
if (hasVendorWxss === false && item.name === 'vendors_wxss.wxss') {
|
|
79
|
-
hasVendorWxss = true;
|
|
80
|
-
}
|
|
81
|
-
if (hasCommonJs === false && item.name === 'commons.js') {
|
|
82
|
-
hasCommonJs = true;
|
|
83
|
-
}
|
|
84
|
-
if (hasVendorJs === false && item.name === 'vendors.js') {
|
|
85
|
-
hasVendorJs = true;
|
|
86
|
-
}
|
|
87
|
-
if (hasRuntimeJs === false && item.name === 'runtime.js') {
|
|
88
|
-
hasRuntimeJs = true;
|
|
89
|
-
}
|
|
90
|
-
if (/subpackage_common/g.test(item.name)) {
|
|
91
|
-
const pathInfo = path.parse(item.name);
|
|
92
|
-
|
|
93
|
-
if (!subpackages[compatiblePath(pathInfo.dir)]) {
|
|
94
|
-
subpackages[compatiblePath(pathInfo.dir)] = {
|
|
95
|
-
js: '',
|
|
96
|
-
wxss: '',
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
if (/(\.js)$/g.test(item.name)) {
|
|
100
|
-
subpackages[compatiblePath(pathInfo.dir)].js = compatiblePath(item.name);
|
|
101
|
-
}
|
|
102
|
-
if (/(\.wxss)$/g.test(item.name)) {
|
|
103
|
-
subpackages[compatiblePath(pathInfo.dir)].wxss = compatiblePath(item.name);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
235
|
+
const { flags, subpackages } = detectCommonModules(items);
|
|
107
236
|
|
|
108
237
|
for (let index = 0; index < items.length; index += 1) {
|
|
109
238
|
const asset = items[index];
|
|
110
|
-
|
|
111
239
|
const assetName = compatiblePath(asset.name);
|
|
112
|
-
const isJs =
|
|
113
|
-
|
|
114
|
-
let content = source.source();
|
|
240
|
+
const isJs = PATTERNS.JS_EXT.test(assetName);
|
|
241
|
+
let content = asset.source.source();
|
|
115
242
|
|
|
116
243
|
if (content.toString) {
|
|
117
244
|
content = content.toString();
|
|
118
245
|
}
|
|
119
246
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
content = `var self = global; \n${content}`;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
247
|
+
content = injectGlobalModules(content, assetName, flags);
|
|
248
|
+
content = injectSubpackageRequires(content, assetName, subpackages);
|
|
249
|
+
content = minifyCommonModules(content, assetName, isJs, compiler.options.mode === ENV.DEV);
|
|
126
250
|
|
|
127
|
-
// runtime 暴露到全局
|
|
128
|
-
if (assetName === 'runtime.js') {
|
|
129
|
-
content = content.replace(
|
|
130
|
-
'var __webpack_module_cache__ = {};',
|
|
131
|
-
`
|
|
132
|
-
if (!global.__webpack_module_cache__) {
|
|
133
|
-
global.__webpack_module_cache__ = {};
|
|
134
|
-
}
|
|
135
|
-
var __webpack_module_cache__ = global.__webpack_module_cache__;
|
|
136
|
-
global.__webpack_require__ = __webpack_require__;
|
|
137
|
-
`,
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// 注入公共模块 js
|
|
142
|
-
if (assetName === 'app.js') {
|
|
143
|
-
// sdk2.17.3 window 下没有 regeneratorRuntime
|
|
144
|
-
content = content.replace(
|
|
145
|
-
'Function("r", "regeneratorRuntime = r")(runtime);',
|
|
146
|
-
'global.regeneratorRuntime = runtime',
|
|
147
|
-
);
|
|
148
|
-
if (!/require('\.\/commons\.js')/g.test(content) && hasCommonJs) {
|
|
149
|
-
content = `require('./commons.js');\n${content}`;
|
|
150
|
-
}
|
|
151
|
-
if (!/require('\.\/vendors\.js')/g.test(content) && hasVendorJs) {
|
|
152
|
-
content = `require('./vendors.js');\n${content}`;
|
|
153
|
-
}
|
|
154
|
-
if (!/require('\.\/runtime\.js')/g.test(content) && hasRuntimeJs) {
|
|
155
|
-
content = `require('./runtime.js');\n${content}`;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// 注入公共模块 css
|
|
160
|
-
if (assetName === 'app.wxss') {
|
|
161
|
-
if (!/@import '\.\/commons\.wxss'/g.test(content) && hasCommonWxss) {
|
|
162
|
-
content = `@import './commons.wxss';\n${content}`;
|
|
163
|
-
}
|
|
164
|
-
if (!/@import '\.\/vendors_wxss\.wxss'/g.test(content) && hasVendorWxss) {
|
|
165
|
-
content = `@import './vendors_wxss.wxss';\n${content}`;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// 分包注入公共模块
|
|
170
|
-
Object.keys(subpackages).forEach((subpackage) => {
|
|
171
|
-
const res = subpackages[subpackage];
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
assetName.startsWith(subpackage) &&
|
|
175
|
-
!/(subpackage_common\.(js|wxss))$/g.test(assetName)
|
|
176
|
-
) {
|
|
177
|
-
if (
|
|
178
|
-
res.js &&
|
|
179
|
-
/(\.js)$/g.test(assetName) &&
|
|
180
|
-
!/'subpackage_common\.js'\);/g.test(content)
|
|
181
|
-
) {
|
|
182
|
-
content = `require('${compatiblePath(
|
|
183
|
-
path.relative(path.parse(assetName).dir, res.js),
|
|
184
|
-
)}');\n${content}`;
|
|
185
|
-
}
|
|
186
|
-
if (
|
|
187
|
-
res.wxss &&
|
|
188
|
-
/(\.wxss)$/g.test(assetName) &&
|
|
189
|
-
!/'subpackage_common\.wxss';/g.test(content)
|
|
190
|
-
) {
|
|
191
|
-
content = `@import '${compatiblePath(
|
|
192
|
-
path.relative(path.parse(assetName).dir, res.wxss),
|
|
193
|
-
)}';\n${content}`;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// 压缩 公共模块
|
|
199
|
-
if (
|
|
200
|
-
(assetName === 'commons.js' ||
|
|
201
|
-
assetName === 'vendors.js' ||
|
|
202
|
-
isNodeModulesUsingComponent(asset.name)) &&
|
|
203
|
-
compiler.options.mode === ENV.DEV
|
|
204
|
-
) {
|
|
205
|
-
const hash = hasha(content);
|
|
206
|
-
if (contentCache[assetName] && contentCache[assetName].hash === hash) {
|
|
207
|
-
content = contentCache[assetName].content;
|
|
208
|
-
} else if (isJs) {
|
|
209
|
-
content = UglifyJS.minify(content, {
|
|
210
|
-
mangle: false,
|
|
211
|
-
compress: {
|
|
212
|
-
drop_console: false,
|
|
213
|
-
drop_debugger: false,
|
|
214
|
-
},
|
|
215
|
-
sourceMap: false,
|
|
216
|
-
}).code;
|
|
217
|
-
contentCache[assetName] = {
|
|
218
|
-
hash,
|
|
219
|
-
content,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
251
|
compilation.updateAsset(asset.name, new RawSource(content));
|
|
224
252
|
}
|
|
225
253
|
},
|