[原文鏈接]([https://www.jianshu.com/p/28a920a79980](https://www.jianshu.com/p/28a920a79980))
鑒于公司項目越來越大編譯的速度越來越慢,打出來的包也越來越大。webpack4 漸漸的走進了我們的視野,據官方表明,webpack4 新增加了很多默認配置項使開發人員不用編寫 webpack.config.js 就能打包開發。極大的降低了學習成本,并對其進行了打包速度的優化以及壓縮文件大小的優化。此次升級以 [TTK 前端開源框架](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2Fthethreekingdoms) 的 [ttk-app-core 項目](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2Fthethreekingdoms%2Fttk-app-core) 做為實例。歡迎各路大神加入我們。
* * *
文章最末附圖升級前后啟動提升 31% 編譯構建提升 43% 速度,可以看出提升是很明顯的,后續我會對項目進行壓縮優化(因為之前大神已經進行過很多的優化所以目前不知道還能有多少優化的空間),讓我們期待 webpack4 更好的表現吧。
* * *
##### 升級過程
網上升級的帖子也有很多大家可以自行搜索,在此我只記錄一下自己成功升級后的方法。分三步
* 首先區別網上一些通過 npm-check-updates 來查看 package.json 中所有包的最新版本并選擇安裝,我這里只選擇安裝 webpack webpack-cli webpack-dev-server
~~~
npm install -D webpack@latest webpack-cli webpack-dev-server@latest
~~~
* 然后不要著急根據所了解 webpack4 的新變化來修改項目中 webpack.config.js 文件,我選擇啟動/編譯構建我們的項目。一般會在 package.json 的 scripts 中定義為 npm run start / npm run release 這個命令因個人項目定義而異。
* 最后逐一解決步驟2收到的很多很多的報錯。過程中就不一一贅述報錯插件的作用介紹了。如果想了解可以看我的 [plugin 介紹](https://www.jianshu.com/p/bb1b245d522a) (持續更新常用插件的個人理解,如果找不到你想要的請聯系個人郵箱 [547106430@qq.com](https://links.jianshu.com/go?to=mailto%3A547106430%40qq.com) 我們共同學習共同進步)
* * *
##### 踩坑之旅 error
遇到報錯不要慌亂首先看 bash 的輸出報錯是什么,然后 [Bing](https://links.jianshu.com/go?to=https%3A%2F%2Fcn.bing.com%2F) 即可。下述錯誤不進行排序,因為每個人遇到的順序肯定是不一樣的。
**首先進行的是 start**
* ValidationError: Dll Reference Plugin Invalid Options 截圖如下:

webpackerr1.jpg
找到報錯大致意思是 DllRefrencePlugin 這個插件是無效的操作。那么就要先看一下項目中 webpack.config.js 中的配置了
~~~
plugins.push(new webpack.DllReferencePlugin({
context: __dirname,
manifest: merge(require('./vendor/vendor.manifest.json')),
}))
~~~
通過搜索老外的得出來的解決方案:
Simply running webpack --config webpack.config.vendor.js with the latest webpack-cli rebuilt vendor-manifest.json (the DLL), and allowed me to get past the error.
大致意思是我們需要重新生成一下我們 vendor 中的 manifest.json 文件即可,本項目需要在 bash 中執行 npm run dll 期間收到一些 warning 因為不影響流程所以我把他們都放到了最后來講解。然后繼續 start
* webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead. 截圖如下:

webpackerr2.jpg
這個就很明確的告訴我們 webpack.optimize.CommonsChunkPlugin 這個東西被移除了你需要 config.optimization.splitChunks 來代替它。那么首先我就需要注釋掉對應部分的代碼并添加新配置如下:
~~~
/*plugins.push(new webpack.optimize.CommonsChunkPlugin({
names: ['edf'],
filename: '[name].min.js',
minChunks: Infinity
}))*/
//并在配置中增加如下代碼。
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
/*vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},*/
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
},
~~~
然后繼續 start 這次看到進度百分比了說明我的努力已經收到成效了。
* Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead 截圖如下:

webpackerr3.jpg
這個經查閱資料分析是 css 代碼分離出問題了,那么我們使用的插件是 extract-text-webpack-plugin 現在問題就簡單了直接 npm install extract-text-webpack-plugin@latest -D 命令升級即可
然后 start 發現會報一個重復的錯誤,那么繼續查閱資料發現最新版本仍不能滿足 webpack4 我們需要升級成 next 版本,執行命令 npm install extract-text-webpack-plugin@next -D
然后繼續 start Compiled successfully. 成功了!但是打開項目發現樣式錯亂了。這時候我首先想到的就是把 樣式相關的 loader 進行升級,查找了一下我項目大致用到了 css-loader、less、less-loader、file-loader、url-loader、style-loader 不管三七二十一全部升級。然后喜聞樂見的又報錯了
* .bezierEasingMixin(); 截圖如下:
Inline JavaScript is not enabled. Is it set in your options?

webpackerr4.jpg
通過查閱資料我們知道這是 less 升級到 3.0 之后的報錯。解決方案是修改less的配置 options: { javascriptEnabled: true } 對應項目代碼如下:
~~~
plugins.push(new HappyPack({
id: 'css',
// loaders: ['css-loader', clientInformation'less-loader'],
loaders: [{
loader: 'css-loader',
}, {
loader: "less-loader",
options: {
"modifyVars": modifyVars, // 變量
"javascriptEnabled": true
}
}],
threadPool: happyThreadPool, // 變量
}))
~~~
接下來我們繼續 start,這次又啟動成功了。尷尬的是頁面還是錯亂的,所以說上述改進好像沒有生效,但是作為插件升級也就不回退了,理論上是有利于后續打包壓縮優化的。
接下來我們繼續分析和樣式有關的插件 plugin 有什么,我們就找到了 extract-text-webpack-plugin 這個上面讓我們踩了兩次坑的破插件,然后我們查看 github 文檔我們會看到它的 options 有這樣一個屬性說明,截圖如下:

extract-text-webpack-plugin1.jpg
大致意思呢就是當我們使用 CommonsChunkPlugin 插件并且 ExtractTextPlugin.extract 有在公共模塊使用時 allChunks 屬性必須設置為 true。雖然我們已經棄用了 CommonsChunkPlugin 但是還是需要嘗試一下,所以我們修改代碼如下:
~~~
plugins.push(new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
}))
~~~
然后 start,這次又啟動成功了。而且頁面完好,點進項目也沒有出問題。至此我們啟動算是大功告成。接下來是踩在啟動的肩膀上來構建編譯項目。來看項目的打包 release 命令:
~~~
"release": "cross-env NODE_ENV=single npm run build && npm run css && npm run modules && npm run merge:manifest",
"build": "cross-env NODE_ENV=production NODE_ENV=single webpack --progress --colors --display-error-details --config webpack.config.prd.js",
"css": "cross-env NODE_ENV=production NODE_ENV=single webpack --progress --config webpack.config.css.prd.js",
"modules": "npm run module --edf && npm run module --test",
"module": "cross-env NODE_ENV=production webpack --progress --colors --display-error-details --config webpack.config.module.js",
"merge:manifest": "node createManifest.js",
~~~
所以我只需要查看并先按照上述 webpack.config.js、webpack.dll.js 來做修改 webpack.config.prd.js、webpack.config.css.prd.js、webpack.config.module.js、createManifest.js 這四個文件的代碼。
然后執行 release 喜聞樂見的報錯了
* .bezierEasingMixin() 但是這個報錯我們出現過,在 start 的解決方案并不能滿足 release 的打包原因不得而知,我只知道 extract-text-webpack-plugin 插件是個十足的大坑,接下來通過查閱 webpack 的官方文檔我們看到下述說明,截圖如下:

extract-text-webpack-plugin3.jpg
大致意思呢是 webpack4 中抽離 css 用 [mini-css-extract-plugin](https://links.jianshu.com/go?to=https%3A%2F%2Fwebpack.js.org%2Fplugins%2Fmini-css-extract-plugin%2F) 來代替 extract-text-webpack-plugin 這個大坑,雖然查閱資料還有其他解決方案繼續使用 extract-text-webpack-plugin 但是我放棄抵抗了決定棄用它,做如下改動:
~~~
// 首先在 bash 中安裝
npm install -D mini-css-extract-plugin
// 然后引入進來
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 根據官方說明來做代碼調整如下
// 插件替換
/*plugins.push(new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
}))*/
plugins.push(new MiniCssExtractPlugin({ // webpack 4
filename: '[name].css',
chunkFilename: '[id].css',
}))
// module 替換引入
rules: [{
test: /\.(css|less)/,
/*use: ExtractTextPlugin.extract({ // webpack 3
use: ['happypack/loader?id=css']
})*/
use: [MiniCssExtractPlugin.loader, 'happypack/loader?id=css'] // webpack 4
}
~~~
然后先 start 試驗一下啟動成功項目也沒有任何問題,那么我們繼續 release 操作打包成功。啟動 MAMP 啟動服務器來測試一下,沒有任何問題至此大功告成!!!
當然在實際升級過程中并沒有這么順利,走了很多很多的彎路和意想不到的報錯,為此付出了很多的努力,最后總結出這么一套流程。看上去是非常之簡單了。
##### 踩坑之旅 warning
* WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: [https://webpack.js.org/configuration/mode/](https://links.jianshu.com/go?to=https%3A%2F%2Fwebpack.js.org%2Fconfiguration%2Fmode%2F) 截圖如下:

warning1.jpg
這就是 webpack4 讓你在配置文件設置一下你的環境是生產還是開發,我們只需要在配置文件中設置 mode 屬性即可。
* WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
vendor.e282754a.dll.js (1.7 MiB) 截圖如下:

warning2.jpg
這是建議你的入口文件大小限制的,我們只需要告訴它不要管我就可以了,我們需要在配置文件中加入 performance: { hints: false } 的屬性設置即可。
##### 項目啟動/編譯構建升級前后時間對比
* start 啟動 29828ms 對比 43149ms 快了大概 31% 的樣子

升級前start.jpg

升級后start.jpg
* release 編譯構建 52035ms 對比 91424ms 快了大概 43% 的樣子
注:這里 webpack.config.module.js 執行兩次因為我們有兩個 module 模塊。

升級前release1.jpg

升級前release2.jpg

升級前release3.jpg

升級前release4.jpg

升級后release1.jpg

升級后release2.jpg

升級后release3.jpg

升級后release4.jpg
作者:行走的蛋白質
鏈接:https://www.jianshu.com/p/28a920a79980
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。
- 序言
- 環境搭建
- node環境安裝
- npm國內源切換
- git知識學習
- git安裝
- git基本操作
- gitSSH配置
- vscode安裝使用
- 安裝
- git使用
- 前端開發環境
- 安裝腳手架及創建頁面
- 框架源碼目錄結構
- 相關API
- 項目啟動
- 如何運行
- 如何兼容到IE8
- 啟動參數說明
- IE8環境下兼容總結
- 注意的效率問題
- 框架亮點
- 相關技術棧介紹
- 功能強大的UI組件庫
- 數據驅動視圖
- 通用的公共類庫
- 組件視圖生成器
- 嵌入第三方站點
- 簡單易用-react
- 簡單易用-redux
- 1分鐘入門示例(hello world)
- 高級概念
- 入門概念
- 高級概念-1
- 前后端聯調
- 其它常用場景
- 詳細介紹(action、data、reducer)
- action.js
- data.js
- reducer.js
- 進階
- Mock數據
- 引入第三方插件
- 模塊拆分
- iframe接入
- 頁面模型生成器
- webpack@3升級到4.x
- 生產部署
- 生產打包
- nginx部署
- tomcat部署
- hbuilder打包部署
- nodejs部署
- docker部署
- 常見問題
- 兼容IE8
- 自動升級
- 貢獻模板
- 瀏覽器支持統計
- 前端調試
- 注意事項(重要)
- 內存泄漏
- JavaScript內存那點事