webpack打包優化
標簽(空格分隔): 前端 webpack vue
理順思路
一句話概述:
優點:把依賴庫提前打包出來並保留引用,打包功能模塊時不再打包依賴庫,只引用依賴,從而減少打包時間。思想來源:知乎專欄-徹底解決Webpack打包性能問題
缺點:本方式產生了依賴包的js,要在html之初引入,和懶加載的觀念有所沖突。懶加載是在需要的時候才請求資源,而本方式提前把某些可能不需要的資源加載了進來。
優化目標:
目標:
是為了減少發布到用於測試的“偽生產環境”時打包業務模塊過程中npm run testbuild的時間【頻繁執行】
並不是減少本地開發環境npm run dev的時間
也不是減少發布到“生產環境”時打包業務模塊過程中npm run build的時間【不頻繁,上線才執行】
注:關於npm run testbuild
由於我們開發的項目在在微信瀏覽器內打開,並且使用了微信的jssdk,所以需要發布到真實的微信環境進行測試(這個動作我們要經常進行)。但是這只是我們開發人員才知曉的微信公眾號(和我們項目對外服務的公眾號是等價的,只不過用於真正發布前測試)
所以對於有些朋友,不頻繁執行打包操作的話,可能並不需要進行本優化,為了懶加載,甚至不應該進行本優化。
另容易誤解的地方有:
本地開發目前不需要優化,所以本優化和webpack.config.js無關
生產環境需要懶加載,我們不希望該環境一開始就加載所有的依賴包,所以本次優化和npm run build使用的webpack.production.js無關
和需要經常執行的打包發布到測試生產環境的操作npm run testbuild有關,所以我們新建了webpack.dll.config.js和webpack.dll.production.js。所做的優化基本圍繞這兩個文件進行。
涉及的文件:
新建webpack.dll.config.js:這是打包依賴包的配置文件
新建webpack.dll.production.js:這是npm run testbuild時執行的配置文件,使用webpack.DllReferencePlugin引用了提前打包好的依賴包
修改package.json:新增dllconfig命令、testbuild命令
修改~pathto/index.html:通過script標簽引入打包好的依賴包文件。生產環境不使用本優化,不引入依賴包的js,測試生產環境使用的本優化,引入依賴包的js。
修改.gitignore:忽略webpack.dll.config.js打包依賴包過程中產生的manifest.json文件
優化結果
優化效果:npm run build的時間為110秒左右,npm run testbuild的為50秒左右。
副作用:需要在測試生產環境的套模板頁面另引入一個多余的js:即之前打包的依賴包。
注意:可以考慮把依賴包放在靜態資源服務器上,每回修改webpack.dll.config.js時才執行一次npm run dllconfig並上傳。
操作步驟
1.創建依賴包的webpack配置文件 webpack.dll.config.js(名字可以改)
/**
* @file 使用DllPlugin把常用依賴單獨打包,提高webpack打包效率
* @author Liu Junyang
* 在應用到這些依賴包的后端套模板的html需要使用script標簽引用output的filename的js文件
*/
var path = require('path')
const webpack = require('webpack');
const vendors = [
'vue',
'vue-router',
'vue-resource',
'vue-touch',
'mint-ui',
'swiper_3.4.0_hack',
'hack_swiper'
];
module.exports = {
output: {
path: 'static',
filename: '[name].js',
library: '[name]',
},
entry: {
"vendors": vendors,
},
plugins: [
new webpack.DllPlugin({
path: 'manifest.json',
name: '[name]',
context: __dirname,
}),
],
resolve: {
alias: {
'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.min.js'),
'style': path.resolve(__dirname, './src/style'),
'module': path.resolve(__dirname, './src/module'),
'libs': path.resolve(__dirname, './src/libs'),
'layout': path.resolve(__dirname, './src/layout'),
'images': path.resolve(__dirname, './src/images'),
'pages': path.resolve(__dirname, './src/pages')
},
fallback: path.resolve(__dirname, './src/util')
},
};
2.命令行執行webpack --config webpack.dll.config.js打包依賴包
3.在業務打包的webpack配置文件中通過DllReferencePlugin在打包的時候引用依賴包
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false // remove all comments
},
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
}
}),
new webpack.ProvidePlugin({
$: 'zepto/dist/zepto.min.js',
jQuery: 'zepto/dist/zepto.min.js'
}),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./manifest.json'),
})
]
4.在html文件中通過script標簽引入依賴包
{% if STATIC_JS_DEBUG %}
<script src="/static/vue/vendors.js"></script>
{% endif %}
5.關於package.json中的命令
{
"scripts": {
"dev": "webpack-dev-server --inline --hot --quiet --display-error-details",
"dllconfig": "rm -rf static/* && webpack --config webpack.dll.config.js",
"testbuild": "npm run dllconfig && webpack --progress --hide-modules --config webpack.dll.production.js",
"build": "rm -rf static/* && webpack --progress --hide-modules --config webpack.production.js",
"ontestline": "npm run testbuild && npm run html && ./bin/online",
"online": "npm run build && npm run html && ./bin/online"
}
}
