hw-weapp-compiler 1.0.0
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 +76 -0
- package/build/config/env.js +7 -0
- package/build/config/getAppConfig.js +11 -0
- package/build/config/getAssets.js +1 -0
- package/build/config/getConfig.js +73 -0
- package/build/config/getContext.js +5 -0
- package/build/config/getEntrys.js +90 -0
- package/build/config/getEnv.js +5 -0
- package/build/config/getOutput.js +7 -0
- package/build/config/getResourceAccept.js +1 -0
- package/build/dev.js +34 -0
- package/build/loader/js-loader.js +37 -0
- package/build/loader/wxml-loader.js +44 -0
- package/build/loader/wxs-loader.js +25 -0
- package/build/plugin/index.js +231 -0
- package/build/prod.js +34 -0
- package/build/utils/buildEnv.js +31 -0
- package/build/utils/compatiblePath.js +13 -0
- package/build/utils/getWxmlAssets.js +107 -0
- package/build/utils/isNodeModulesUsingComponent.js +17 -0
- package/build/utils/isSubpackage.js +22 -0
- package/build/utils/loadModule.js +19 -0
- package/build/utils/recordEnv.js +11 -0
- package/build/utils/storage.js +29 -0
- package/build/utils/traverseDir.js +21 -0
- package/build/utils/upload.js +194 -0
- package/build/webpack.config.js +381 -0
- package/index.js +47 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# weapp-compiler
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## 版本改动
|
|
5
|
+
|
|
6
|
+
1. **OpenSSL 3.0 兼容**: Node.js >= 17 时自动注入 `--openssl-legacy-provider`
|
|
7
|
+
2. **wxml-loader 空值守卫**: `loadModule` 失败时不再崩溃
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i weapp-compiler@2.x -D
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 使用
|
|
16
|
+
|
|
17
|
+
```bash
|
|
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 # 生产环境
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 配置
|
|
30
|
+
|
|
31
|
+
项目根目录下创建 `.weapp.js`:
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const path = require('path');
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
// 路径别名
|
|
38
|
+
alias: {
|
|
39
|
+
'@utils': path.resolve(__dirname, 'src/utils'),
|
|
40
|
+
'@config': path.resolve(__dirname, 'src/config'),
|
|
41
|
+
},
|
|
42
|
+
// 资源公共路径
|
|
43
|
+
publicPath: 'https://cdn.example.com/weapp/',
|
|
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
|
+
},
|
|
57
|
+
ossConfig: {
|
|
58
|
+
region: '<Your region>',
|
|
59
|
+
accessKeyId: '<Your AccessKeyId>',
|
|
60
|
+
accessKeySecret: '<Your AccessKeySecret>',
|
|
61
|
+
bucket: '<Your Bucket>',
|
|
62
|
+
dir: 'weapp',
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
在 `project.config.json` 中忽略构建产物:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
"packOptions": {
|
|
71
|
+
"ignore": [
|
|
72
|
+
{ "type": "folder", "value": "assets" },
|
|
73
|
+
{ "type": "regexp", "value": "\\.map$" }
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fse = require('fs-extra');
|
|
3
|
+
const getContext = require('./getContext');
|
|
4
|
+
|
|
5
|
+
const appConfig = fse.readJSONSync(path.resolve(getContext(), 'app.json'));
|
|
6
|
+
|
|
7
|
+
function getAppConfig() {
|
|
8
|
+
return appConfig;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = getAppConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = () => 'assets';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fse = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const weapp = path.resolve(process.cwd(), '.weapp.js');
|
|
6
|
+
|
|
7
|
+
let config = {};
|
|
8
|
+
|
|
9
|
+
if (fse.existsSync(weapp)) {
|
|
10
|
+
// eslint-disable-next-line
|
|
11
|
+
config = require(weapp);
|
|
12
|
+
} else {
|
|
13
|
+
throw Error(
|
|
14
|
+
chalk.green(`
|
|
15
|
+
请在项目根目录新建 .weapp.js 配置文件
|
|
16
|
+
|
|
17
|
+
内容如下:
|
|
18
|
+
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
// 路径别名
|
|
23
|
+
alias: {
|
|
24
|
+
'@utils': path.resolve(__dirname, 'src/utils'),
|
|
25
|
+
'@config': path.resolve(__dirname, 'src/config'),
|
|
26
|
+
'@template': path.resolve(__dirname, 'src/template'),
|
|
27
|
+
'@images': path.resolve(__dirname, 'src/images'),
|
|
28
|
+
'@obsimage': path.resolve(__dirname, 'src/wxs_fila/images'),
|
|
29
|
+
'@obs': path.resolve(__dirname, 'src/wxs_fila'),
|
|
30
|
+
'@obsjson': path.resolve(__dirname, 'src/wxs_fila/json'),
|
|
31
|
+
},
|
|
32
|
+
// 资源公共路径
|
|
33
|
+
publicPath: 'https://img.test.com/weapp-compiler-test/',
|
|
34
|
+
// 要同步的目录
|
|
35
|
+
copyFiles: [{
|
|
36
|
+
from: 'images',
|
|
37
|
+
to: 'images',
|
|
38
|
+
}],
|
|
39
|
+
// 华为OBS配置
|
|
40
|
+
obsConfig: {
|
|
41
|
+
access_key_id: 'XXXXXXXX',
|
|
42
|
+
secret_access_key: 'XXXXXXXX',
|
|
43
|
+
server: 'XXXXXXXX',
|
|
44
|
+
bucket: 'XXXXXXXX',
|
|
45
|
+
dir: 'weapp-compiler-test',
|
|
46
|
+
},
|
|
47
|
+
// 阿里OSS配置
|
|
48
|
+
ossConfig: {
|
|
49
|
+
region: '<Your region>',
|
|
50
|
+
accessKeyId: '<Your AccessKeyId>',
|
|
51
|
+
accessKeySecret: '<Your AccessKeySecret>',
|
|
52
|
+
bucket: '<Your Bucket>',
|
|
53
|
+
dir: 'weapp-compiler-test',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
`),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
const alias = {
|
|
60
|
+
...(config.alias || {}),
|
|
61
|
+
};
|
|
62
|
+
Object.keys(config.alias || {}).forEach((key) => {
|
|
63
|
+
alias[`alias(${key})`] = alias[key];
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
function getConfig() {
|
|
67
|
+
return {
|
|
68
|
+
...config,
|
|
69
|
+
alias,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = getConfig;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fse = require('fs-extra');
|
|
3
|
+
const getContext = require('./getContext');
|
|
4
|
+
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();
|
|
10
|
+
const appConfig = getAppConfig();
|
|
11
|
+
|
|
12
|
+
const entrys = {
|
|
13
|
+
app: path.resolve(context, 'app'),
|
|
14
|
+
};
|
|
15
|
+
const addUsingComponents = (components, parent) => {
|
|
16
|
+
Object.keys(components).forEach((key) => {
|
|
17
|
+
let filePath = components[key];
|
|
18
|
+
|
|
19
|
+
if (!/^(plugin:|plugin-private:|weui-miniprogram)/g.test(filePath)) {
|
|
20
|
+
if (/^\//g.test(filePath)) {
|
|
21
|
+
filePath = path.resolve(context, filePath.replace(/^\//g, ''));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (fse.existsSync(`${path.resolve(parent, filePath)}.js`)) {
|
|
25
|
+
filePath = path.resolve(parent, filePath);
|
|
26
|
+
} else {
|
|
27
|
+
try {
|
|
28
|
+
filePath = require.resolve(filePath);
|
|
29
|
+
filePath = filePath.replace(/(\.js)$/g, '');
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(error);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (fse.existsSync(`${filePath}.json`)) {
|
|
37
|
+
// eslint-disable-next-line
|
|
38
|
+
readUsingComponents(`${filePath}.json`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let entryKey = filePath;
|
|
42
|
+
|
|
43
|
+
if (/\/node_modules\//g.test(filePath) || /\\node_modules\\/g.test(filePath)) {
|
|
44
|
+
// eslint-disable-next-line
|
|
45
|
+
entryKey = compatiblePath(filePath).split('/node_modules/')[1];
|
|
46
|
+
|
|
47
|
+
addNodeModulesUsingComponent(entryKey);
|
|
48
|
+
} else {
|
|
49
|
+
entryKey = path.relative(context, filePath);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
entryKey = compatiblePath(entryKey);
|
|
53
|
+
|
|
54
|
+
entrys[entryKey] = filePath;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const readUsingComponents = (file) => {
|
|
59
|
+
const json = fse.readJSONSync(file);
|
|
60
|
+
|
|
61
|
+
if (json.usingComponents) {
|
|
62
|
+
addUsingComponents(json.usingComponents, path.parse(file).dir);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// pages
|
|
67
|
+
(appConfig.pages || []).forEach((page) => {
|
|
68
|
+
entrys[page] = path.resolve(context, page);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// tabbar
|
|
72
|
+
if (fse.existsSync(path.resolve(context, 'custom-tab-bar/index.js'))) {
|
|
73
|
+
entrys['custom-tab-bar/index'] = path.resolve(context, 'custom-tab-bar/index');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// subpackages
|
|
77
|
+
(appConfig.subpackages || []).forEach((pkg) => {
|
|
78
|
+
(pkg.pages || []).forEach((page) => {
|
|
79
|
+
entrys[compatiblePath(path.join(pkg.root, page))] = path.resolve(context, pkg.root, page);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// usingComponents
|
|
84
|
+
traverseDir(context).forEach((item) => {
|
|
85
|
+
if (/(\.json)$/g.test(item)) {
|
|
86
|
+
readUsingComponents(item);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
module.exports = () => entrys;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = () => /\.(png|jpg|gif|jpeg|svg|ttf|woff|eot|woff2|otf|mp3|mp4|wav|json|html)$/i;
|
package/build/dev.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
const ENV = require('./config/env');
|
|
4
|
+
const webpackConfig = require('./webpack.config');
|
|
5
|
+
|
|
6
|
+
module.exports = (opts) => {
|
|
7
|
+
const compiler = webpack(
|
|
8
|
+
webpackConfig(
|
|
9
|
+
{
|
|
10
|
+
mode: ENV.DEV,
|
|
11
|
+
devtool: 'cheap-module-source-map',
|
|
12
|
+
},
|
|
13
|
+
opts || {},
|
|
14
|
+
),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
compiler.watch({}, (err, stats) => {
|
|
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
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fse = require('fs-extra');
|
|
3
|
+
const getEntrys = require('../config/getEntrys');
|
|
4
|
+
const loadModule = require('../utils/loadModule');
|
|
5
|
+
|
|
6
|
+
const entrys = getEntrys();
|
|
7
|
+
|
|
8
|
+
module.exports = async function loader(source) {
|
|
9
|
+
this.cacheable(true);
|
|
10
|
+
const callback = this.async();
|
|
11
|
+
const filePath = this.resourcePath;
|
|
12
|
+
const fileInfo = path.parse(filePath);
|
|
13
|
+
const sourceStr = source.toString();
|
|
14
|
+
|
|
15
|
+
const imports = [sourceStr];
|
|
16
|
+
|
|
17
|
+
if (Object.values(entrys).indexOf(path.resolve(fileInfo.dir, fileInfo.name)) !== -1) {
|
|
18
|
+
const exts = ['.less', '.wxss', '.css', '.json', '.wxml'];
|
|
19
|
+
|
|
20
|
+
for (let index = 0; index < exts.length; index += 1) {
|
|
21
|
+
const ext = exts[index];
|
|
22
|
+
const otherFilePath = path.resolve(fileInfo.dir, fileInfo.name + ext);
|
|
23
|
+
|
|
24
|
+
if (await fse.pathExists(otherFilePath)) {
|
|
25
|
+
if (['.less', '.wxss', '.css'].indexOf(ext) !== -1) {
|
|
26
|
+
imports.unshift(`import './${fileInfo.name}${ext}'\n`);
|
|
27
|
+
} else {
|
|
28
|
+
await loadModule.call(this, otherFilePath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
callback(null, imports.join(''));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports.raw = true;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const getWxmlAssets = require('../utils/getWxmlAssets');
|
|
2
|
+
const loadModule = require('../utils/loadModule');
|
|
3
|
+
|
|
4
|
+
module.exports = async function loader(source) {
|
|
5
|
+
this.cacheable(true);
|
|
6
|
+
const callback = this.async();
|
|
7
|
+
const filePath = this.resourcePath;
|
|
8
|
+
let content = source.toString();
|
|
9
|
+
const {
|
|
10
|
+
_compiler: {
|
|
11
|
+
options: {
|
|
12
|
+
output: { publicPath },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
} = this;
|
|
16
|
+
const withPublicPath = (str) => {
|
|
17
|
+
if (!str) return '';
|
|
18
|
+
const match = str.match(/"(.*)"/g);
|
|
19
|
+
if (!match) return str;
|
|
20
|
+
return `${publicPath === 'auto' ? '' : publicPath}${match[0].replace(/"/g, '')}`;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const [assets, wxmls] = await getWxmlAssets.call(this, filePath, content);
|
|
24
|
+
|
|
25
|
+
// 资源文件
|
|
26
|
+
for (let index = 0; index < assets.length; index += 1) {
|
|
27
|
+
const [attr, file] = assets[index];
|
|
28
|
+
const src = await loadModule.call(this, file);
|
|
29
|
+
|
|
30
|
+
if (src) {
|
|
31
|
+
content = content.replace(attr, withPublicPath(src, publicPath));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// wxml文件
|
|
36
|
+
for (let index = 0; index < wxmls.length; index += 1) {
|
|
37
|
+
const [, file] = wxmls[index];
|
|
38
|
+
|
|
39
|
+
await loadModule.call(this, file);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
callback(null, content);
|
|
43
|
+
};
|
|
44
|
+
module.exports.raw = true;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const loadModule = require('../utils/loadModule');
|
|
3
|
+
|
|
4
|
+
module.exports = async function loader(source) {
|
|
5
|
+
this.cacheable(true);
|
|
6
|
+
const callback = this.async();
|
|
7
|
+
const filePath = this.resourcePath;
|
|
8
|
+
const content = source.toString();
|
|
9
|
+
const fileInfo = path.parse(filePath);
|
|
10
|
+
|
|
11
|
+
const requires = content.match(/require\(("|').*("|')\)/g) || [];
|
|
12
|
+
|
|
13
|
+
for (let index = 0; index < requires.length; index += 1) {
|
|
14
|
+
const item = requires[index];
|
|
15
|
+
|
|
16
|
+
const file = path.resolve(
|
|
17
|
+
fileInfo.dir,
|
|
18
|
+
item.replace(/^((require\(')|(require\("))/g, '').replace(/(('\))|("\)))$/g, ''),
|
|
19
|
+
);
|
|
20
|
+
await loadModule.bind(this)(file);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
callback(null, content);
|
|
24
|
+
};
|
|
25
|
+
module.exports.raw = true;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const UglifyJS = require('uglify-js');
|
|
3
|
+
const hasha = require('hasha');
|
|
4
|
+
const { RawSource } = require('webpack-sources');
|
|
5
|
+
|
|
6
|
+
const { isNodeModulesUsingComponent } = require('../utils/isNodeModulesUsingComponent');
|
|
7
|
+
const getAssets = require('../config/getAssets');
|
|
8
|
+
const { addToUploadQueue } = require('../utils/upload');
|
|
9
|
+
const getResourceAccept = require('../config/getResourceAccept');
|
|
10
|
+
const compatiblePath = require('../utils/compatiblePath');
|
|
11
|
+
const ENV = require('../config/env');
|
|
12
|
+
|
|
13
|
+
const assetsDir = getAssets();
|
|
14
|
+
const pluginName = 'WeappCompilerPlugin';
|
|
15
|
+
const contentCache = {};
|
|
16
|
+
|
|
17
|
+
class WeappPlugin {
|
|
18
|
+
// eslint-disable-next-line
|
|
19
|
+
constructor() {}
|
|
20
|
+
|
|
21
|
+
// eslint-disable-next-line
|
|
22
|
+
apply(compiler) {
|
|
23
|
+
// const { RawSource } = compiler.webpack.sources;
|
|
24
|
+
|
|
25
|
+
let obsAssets = [];
|
|
26
|
+
|
|
27
|
+
compiler.hooks.done.tap(pluginName, () => {
|
|
28
|
+
addToUploadQueue([...obsAssets]);
|
|
29
|
+
obsAssets = [];
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
compiler.hooks.compilation.tap(pluginName, (compilation) => {
|
|
33
|
+
compilation.hooks.afterProcessAssets.tap(
|
|
34
|
+
{
|
|
35
|
+
name: pluginName,
|
|
36
|
+
},
|
|
37
|
+
(assets) => {
|
|
38
|
+
obsAssets = obsAssets.concat(
|
|
39
|
+
Object.keys(assets).filter((key) => {
|
|
40
|
+
return getResourceAccept().test(key) && new RegExp(`${assetsDir}/`, 'g').test(key);
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
compilation.hooks.processAssets.tap(
|
|
47
|
+
{
|
|
48
|
+
name: pluginName,
|
|
49
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
|
50
|
+
},
|
|
51
|
+
async (assets) => {
|
|
52
|
+
// this callback will run against assets added later by plugins.
|
|
53
|
+
const items = Object.entries(assets)
|
|
54
|
+
.map(([name, source]) => {
|
|
55
|
+
return {
|
|
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];
|
|
74
|
+
|
|
75
|
+
if (hasCommonWxss === false && item.name === 'commons.wxss') {
|
|
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
|
+
}
|
|
107
|
+
|
|
108
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
109
|
+
const asset = items[index];
|
|
110
|
+
|
|
111
|
+
const assetName = compatiblePath(asset.name);
|
|
112
|
+
const isJs = /(\.(js))$/g.test(assetName);
|
|
113
|
+
const { source } = asset;
|
|
114
|
+
let content = source.source();
|
|
115
|
+
|
|
116
|
+
if (content.toString) {
|
|
117
|
+
content = content.toString();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 注入全局引用模块
|
|
121
|
+
if (isJs) {
|
|
122
|
+
if (!/(var self = global;)/g.test(content)) {
|
|
123
|
+
content = `var self = global; \n${content}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
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
|
+
compilation.updateAsset(asset.name, new RawSource(content));
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = WeappPlugin;
|