之前dll文件是在構(gòu)建機(jī)器上每次都重新構(gòu)建一次谆刨,后來發(fā)現(xiàn)是可以根據(jù)packages的版本號(hào)進(jìn)行對比渺鹦,從而判斷是否需要重新構(gòu)建dll舀透。
所以寫了一個(gè)文件在每次提交時(shí)判斷是否需要重新構(gòu)建
優(yōu)化dll構(gòu)建
build.dll.js
'use strict';
function exec(cmd) {
// 將輸出實(shí)時(shí)打印在控制臺(tái)
require('child_process').execSync(cmd, { stdio: [0, 1, 2] });
}
const fs = require('fs');
const chalk = require('chalk');
const _ = require('lodash');
// 項(xiàng)目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有多個(gè)入口
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(' => 正在重新構(gòu)建\n'));
// 執(zhí)行dll
exec('npm run build:dll');
// 構(gòu)建后將新的版本記錄寫入文件,version用于HtmlWebpackPlugin寫入index.html
fs.writeFileSync(
'build/build.dll.json',
JSON.stringify({ packages: newPackages, version: dllJson.version + 1 }, null, 2)
);
console.log(chalk.green(' => 構(gòu)建完成\n'));
} else {
console.log(chalk.green(' => 不需要重新構(gòu)建\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
}
之后為了自動(dòng)的改動(dòng)vendor.dll.js
在index.html
的版本號(hào)(用于瀏覽器緩存)密任,需要在webpack.dev.conf.js
和webpack.prod.conf.js
加入HtmlWebpackPlugin
參數(shù)
new HtmlWebpackPlugin({
// ...省略
customInfo: {
vendorVersion: vendorVersion,
},
}),
在index.html
加入版本號(hào)的參數(shù)
<script src="/static/js/vendor.dll.js?v=<%= htmlWebpackPlugin.options.customInfo.vendorVersion %>"></script>
最后一步颜启,在pre-commit
加上執(zhí)行這個(gè)文件(需要裝husky),這樣每次提交就會(huì)先進(jìn)行檢查浪讳,如果需要構(gòu)建就會(huì)將構(gòu)建后的文件上傳git
npm i -D husky
"husky": {
"hooks": {
"pre-commit": "node build/build.dll.js
}
}
總結(jié)
這樣雖然會(huì)減少線上構(gòu)建的時(shí)間缰盏,但是因?yàn)?code>vendor.dll.js是在本地構(gòu)建的,可能會(huì)出現(xiàn)本地和線上版本不同的問題淹遵,之后可以想想怎么進(jìn)一步改造
附件(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 = {
// 你想要打包的模塊的數(shù)組
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,
}),
],
};