在我們的項目開發中,如果使用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
}
本文到此就結束了,使用該插件進行打包優化,速度快了很多,很高興今天和大家一起學習,下次再見~