祝你們新年快樂,萬事如意,新年發大財😊😊javascript
臨近春節,公司不少同事都提早回家過年,剩餘人員根據禪道去修改bug,當bug修正完畢之後,咱們須要從新打包給運維,上測試服給測試同事提測,可是因爲項目本體比較龐大,因此打包時間太過漫長(二十五分鐘以上😭),因此有了打包優化的想法(其實想法早就有了,可是由於平時工做計劃比較充實,因此一直沒有去完成這個工做),此次正好有時間,因此去從新考慮了這個問題!html
話很少說,直接開始正文吧vue
先給你們看一下項目的目錄結構:java
就是正常的項目結構,簡單說一下吧:node
項目打包時間長,緣由無外乎就是項目總體比較龐大、依賴複雜、組件以前拆分不夠合理。jquery
對於這三個問題呢,咱們能夠針對下面這幾個方面去作一下處理:webpack
有了總體的思路,那麼開搞就能夠啦 去webpack文檔去看了一下有一個DllPlugin,這個插件就是幫助咱們解決問題的關鍵,下面是我webpack.dll.config的代碼:ios
var path = require("path");
var webpack = require("webpack");
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
// 你想要打包的模塊的數組
entry: {
vendor: ['vue', 'lodash', 'vuex', 'axios', 'vue-router', 'iview', 'element-ui',
'echarts','xlsx','jquery','vue-fullcalendar','vue-cookie','handsontable']
},
output: {
path: path.join(__dirname, '../dist/vendor-dll-js'), // 打包後文件輸出的位置
filename: '[name].dll.js',
library: '[name]_library'
// vendor.dll.js中暴露出的全局變量名。
// 主要是給DllPlugin中的name使用,
// 故這裏須要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '.', '[name]-manifest.json'),
name: '[name]_library',
context: __dirname
}),
// 壓縮打包的文件,與該文章主線無關
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
};
複製代碼
咱們須要將項目中具備重用性的包抽離出來,放在vendor數組裏面,而後在下面output裏面定義一下打包輸出的文件路徑,而後在resolve裏面配置解析參數,最後定義使用的DllPlugin插件,UglifyJsPlugin是壓縮js的插件git
Dllplugin裏的path,會輸出一個vendor-manifest.json,這是用來作關聯id的,打包的時候不會打包進去,因此不用放到static裏 而後運行一下 webpack -p --progress --config build/webpack.dll.conf.js
github
成功之後,static下會有dll.vendor.js,根目錄下會有vendor.manifest.json 各自打開看一下,就會看到依賴庫的源碼和匹配id
ok,到這裏,抽離依賴庫的事情就完成了,那麼接下來問題就是怎麼引用呢,怎麼在dev和build跑呢?
這裏補了一點dll和commonsChunk概念上的區別,commonsChunk之因此慢和大,是由於每次run的時候,都會去作一次打包,而實際上咱們不會一直去更新咱們引用的依賴庫,因此dll的作法就等因而,事先先打包好依賴庫,而後只對每次都修改的js作打包。
繼續上面的步驟,咱們須要根據生成的json文件去修改webpack.base.config文件:
const manifest = require('../vendor-manifest.json')
......
plugins: [
new webpack.DllReferencePlugin({
manifest
})
]
複製代碼
而後打開index.html,在底部加上<script src="./static/dll.vendor.js"></script>
;
執行一下npm run build
,一塊兒正常的話,表示你的操做是正確的。
至此優化的問題基本已經解決了,可是在處理過程當中須要進行復制粘貼,還要對index.html文件進行操做,若是是對於項目不熟悉的人來進行開發項目的話,就會出現一些小的問題,因此我決定繼續往下研究一下:
思路仍是上面的思路,咱們下面須要進行的操做呢就是對與以前的處理進行優化,經過配置文件,和命令去實現咱們想要的效果
首先咱們將上面 webpack.dll.config 文件裏面的entry配置項拿出來,在config文件夾下新建一個dll.js
module.exports = {
entry: {
// 這裏的依賴順序必須是:對象從上往下依賴,數組從右到左依賴(若是互不依賴的能夠忽略順序)
ui: ['iview', 'element-ui'],
tool: ['lodash', 'jquery', 'axios', 'vue-fullcalendar'],
vue: ['vue', 'vuex', 'vue-router', 'vue-cookie'],
xlsx: ['xlsx'],
echarts: ['echarts'],
other: ['handsontable'],
},
outFile: '../static/dll'
};
複製代碼
這裏面其實就是咱們一開始寫的entry的配置項,根據這個js去打包的文件有一個順序,就是我總結的這個:
這裏的依賴順序必須是:對象從上往下依賴,數組從右到左依賴(若是互不依賴的能夠忽略順序)
若是不按照這個順序去寫的話,會出現依賴錯誤的問題!!!
而後在output裏面再進行一下配置:
output: {
path: path.join(__dirname, dllConfig.outFile), // 打包後文件輸出的位置
filename: '[name].dll.[chunkhash].js',
library: '[name]_library'
// 主要是給DllPlugin中的name使用,
// 故這裏須要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
複製代碼
這樣在執行webpack -p --progress --config build/webpack.dll.conf.js
指令的時候會生成以下:
要實現命令操做以後不進行復制粘貼操做就須要使用webpack的 HtmlWebpackPlugin插件
在plugins裏面配置一下HtmlWebpackPlugin
new HtmlWebpackPlugin({
filename: path.join(__dirname, '../', config.dev.index),
template: 'index.ejs',
inject: false
}),
複製代碼
而後在根目錄添加一個index.ejs模版(ejsGitHub地址), index.ejs中代碼以下:
<body>
<div id="app"></div>
<!-- dll files will be auto injected -->
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %><script type="text/javascript" src="/<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
複製代碼
最後須要在config文件夾下的index.js進行一下修改: 在dev中添加:index: 'index.html',
項目在執行dev指令或者build指令以前須要先執行:webpack -p --progress --config build/webpack.dll.conf.js
在dll指令結束後 執行其餘操做就能夠完美的玩耍了😊
至此代碼打包優化的整個過程就基本結束了,測試一下,15分鐘左右就能夠完成打包,比以前打包快了將近10分鐘,能夠說是很是成功的一次嘗試!!
最後祝各位勤勞、睿智、悶騷正念,外表冷漠心裏狂熱,顏值負分,人設冰點的程序猿們,節日快樂!