在我们的项目开发中,如果使用webpack来打包编译我们的项目,我们都会遇到一个问题,当项目的依赖变得越来越多时,我们会发现webpack的打包速度会越来越慢,怎么去解决这个问题呢。首先我们先思考一个问题,webpack打包的时候是把所有文件都打包,但是对于我们引入的那些第三方库它是不会变的,有必要每次都打包吗?我们是不是可以把这些东西都提取出来,只打包一次,让页面引入我们打包生成的库文件,这样以后每次打包就都把这个第三方的库排除在外了,只在第一次打包的时候打包一次。这个功能的实现就是我们今天要说到的webpack-dllPlugin的使用
新建webpack.dll.js文件
// webpack.dll.js
var path = require('path');
module.exports = {
entry: {
vendor: ['loadsh'] // 这里面放我们需要打包的第三方库文件,数组形式逗号隔开, 这里以lodash为例
},
output: {
path: path.resolve(__dirname, 'dll'), // 讲lodash打包到dll目录下面
filename: '[name].dll.js',
library: '[name]' // 全局变量verdor 会被挂载到window上
}
}
在package.json 文件中配置打包命令
{
"script": {
"build:dll": "webpack --config webpack.dll.js"
}
}
执行命令就在dll目录下生成了vendor.dll.js文件,里面包含我们的lodash
npm run build:dll
我们已经生产了lodash的vendor文件,但是它没有被用到呀,我们需要将它引入到html文件中,使用插件add-asset-html-webpack-plugin。记得一定要先npm install。我们在webpack.config.js里面配置, plugins新增项
// webpack.config.js
plugins: [
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, 'dll/vendor.dll.js') // 引入静态资源路径
})
]
到了这一步,我们已经把生产的库文件引入到html中了,但是我们项目中还是使用的是node_modules 里面的第三方模块, 并没有使用我们打包dll里面的vendor模块。还需要在dll的配置中新增plugins对库文件进行分析,产生一个json的隐射文件, 然后在webpack.congfig.js中就可以使用这个json文件来分析使用哪里的库
1.生成manifest.json映射文件
// webpack.dll.js
var webpack = require('webpack')
plugins: [
// 对要打包的库文件进行分析(路径隐射关系),分析的结果放在dll目录下的manifest.json文件的中
new webpack.DllPlugin({
name: '[name]',
path: path.resolve(__dirname, 'dll/[name].manifest.json') //
})
]
2.webpack.config.js 分析映射文件
// webpack.config.js
var webpack = require('webpack')
plugins: [
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, 'dll/vendor.dll.js') //
}),
// 新增
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dll/vendor.manifest.json')
})
]
代码优化
以上就完成了我们第三库文件打包的分离,只在第一次打包的时候打包。其它时候不打包,极大的加快了我们的webpack性能。
代码优化, 上述代码只打包了一个lodash,如果你想分开打包其它库的时候,这里不多解释直接上代码(完整代码)。
- webpack.dll.js新增打包项
// webpack.dll.js
var path = require('path');
var webpack = require('webpack')
module.exports = {
mode: 'production',
entry: {
vendor: ['lodash'],
react: ['react', 'react-dom'] // 新增
},
output: {
path: path.resolve(__dirname, 'dll'),
filename: '[name].dll.js',
library: '[name]'
},
plugins: [
// 对要打包的库文件进行分析(路径隐射关系),分析的结果放在dll目录下的manifest.json文件的中
new webpack.DllPlugin({
name: '[name]',
path: path.resolve(__dirname, 'dll/[name].manifest.json') //
})
]
}
- webpack.config.ls 代码抽离优化
var fs = require('fs')
var path = require('path');
// 将plugins抽离
let plugins = [new HtmlWebpackPlugin({ template: 'index.html' }), new CleanWebpackPlugin()];
let dll = path.resolve(__dirname, 'dll')
// 获取dll目录下的文件名(有多个dll.js和多个manifest.json)
const files = fs.readdirSync(dll);
if (files && files.length) {
files.forEach((file) => {
// 当该文件是dll.js的文件
if (/.*\.dll.js/.test(file)) {
plugins.push(
new AddAssetHtmlWebpackPlugin({
publicPath: 'js',
outputPath: 'js',
filepath: path.resolve(dll, file)
})
);
}
if (/.*\.manifest.json/.test(file)) {
plugins.push(
new webpack.DllReferencePlugin({
manifest: path.resolve(dll, file)
})
);
}
});
}
module.exports = {
"plugin": plugins
}
本文到此就结束了,使用该插件进行打包优化,速度快了很多,很高兴今天和大家一起学习,下次再见~