之前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.jsonconst 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
加入版本号的参数
复制代码
最后一步,在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, }), ],};复制代码