记一次dll构建时机优化
2019-03-13 本文已影响0人
天驱丶
之前dll文件是在构建机器上每次都重新构建一次,后来发现是可以根据packages的版本号进行对比,从而判断是否需要重新构建dll。
所以写了一个文件在每次提交时判断是否需要重新构建
优化dll构建
build.dll.js
'use strict';
function exec(cmd) {
// 将输出实时打印在控制台
require('child_process').execSync(cmd, { stdio: [0, 1, 2] });
}
const fs = require('fs');
const chalk = require('chalk');
const _ = require('lodash');
// 项目package.json
const packageJson = require('../package.json');
// 用于判断的版本记录文件
const dllJson = require('./build.dll.json');
const dllConfig = require('./webpack.dll.config');
console.log(chalk.yellow(' 正在检查是否需要更新dll文件'));
// 可能webpack.dll.config有多个入口
const vendors = Object.values(dllConfig.entry).reduce((result, it) => result.concat(it), []);
const oldPackages = dllJson.packages;
const newPackages = _.pick(packageJson.dependencies, vendors);
const isEqual = _.isEqual(oldPackages, newPackages);
if (!isEqual) {
console.log(chalk.cyan(' => 正在重新构建\n'));
// 执行dll
exec('npm run build:dll');
// 构建后将新的版本记录写入文件,version用于HtmlWebpackPlugin写入index.html
fs.writeFileSync(
'build/build.dll.json',
JSON.stringify({ packages: newPackages, version: dllJson.version + 1 }, null, 2)
);
console.log(chalk.green(' => 构建完成\n'));
} else {
console.log(chalk.green(' => 不需要重新构建\n'));
}
build.dll.json
{
"packages": {
"vuex": "^2.3.1",
"vue-router": "^2.3.1",
"vue-tables-2": "^0.6.64",
"echarts": "^3.8.5"
},
"version": 4
}
之后为了自动的改动vendor.dll.js
在index.html
的版本号(用于浏览器缓存),需要在webpack.dev.conf.js
和webpack.prod.conf.js
加入HtmlWebpackPlugin
参数
new HtmlWebpackPlugin({
// ...省略
customInfo: {
vendorVersion: vendorVersion,
},
}),
在index.html
加入版本号的参数
<script src="/static/js/vendor.dll.js?v=<%= htmlWebpackPlugin.options.customInfo.vendorVersion %>"></script>
最后一步,在pre-commit
加上执行这个文件(需要装husky),这样每次提交就会先进行检查,如果需要构建就会将构建后的文件上传git
npm i -D husky
"husky": {
"hooks": {
"pre-commit": "node build/build.dll.js
}
}
总结
这样虽然会减少线上构建的时间,但是因为vendor.dll.js
是在本地构建的,可能会出现本地和线上版本不同的问题,之后可以想想怎么进一步改造
附件(webpack.dll.config.js)
'use strict';
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const context = path.join(__dirname, '..');
module.exports = {
// 你想要打包的模块的数组
entry: {
vendor1: [
'vuex',
'vue-router',
'lodash',
'vue-tables-2',
],
vendor2: [
'echarts',
],
},
output: {
path: path.join(context, 'static/js'), // 打包后文件输出的位置
filename: '[name].dll.js',
library: '[name]_library',
// vendor.dll.js中暴露出的全局变量名。
// 主要是给DllPlugin中的name使用,
// 故这里需要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '.', '[name]-manifest.json'),
name: '[name]_library',
context: context,
}),
// 压缩打包的文件
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
},
},
sourceMap: false,
parallel: true,
}),
],
};