Webpack 4 升級與使用
最近一段時間, 在嘗試 easywebpack 工程化方案升級到 Webpack 4 版本,在此期間遇到比較多問題:
- Webpack 4 雖然發布了,但沒有文檔,只能看源代碼
- Webpack 4 相關插件沒有及時適配, 需要提issue,讓作者適配,需要等待
- ssr 構建中遇到問題 6681
- 配置適配兼容,包括 mode, commonsChunk, 默認插件
- 骨架升級測試, 會遇到一些奇怪問題,然後去升級對應的插件
Webpack 4 最新問題(2018-3-27)
- 目前
extract-text-webpack-plugin
最新版本不支持 Webpack 4.3.0 版本. webpack 4.2.0 以下可用。 - 目前從 extract-text-webpack-plugin issues 了解, 未來 extract-text-webpack-plugin 將廢棄,作者建議使用 mini-css-extract-plugin 插件。
- easywebpack 工程化方案近期會適配, 具體盡職見 extract-text-webpack-plugin 不再支持 Webpack 4.3.0
Webpack 4 版本特性
- 配置默認初始化一些配置, 比如 entry 默認 ./src
- 開發模式和發布模式, 插件默認內置
- CommonsChunk 配置簡化
- 使用 ES6 語法,比如 Map, Set, includes
- 新增 WebAssembly 構建支持
- 如果要使用 webpack cli 命令,需要單獨再安裝 webpack-cli
目前 Webpack4 已經基本穩定,可以開始升級,不過還是有些小 bug 在不斷的修復,目前已經 4.1.1。 具體見:https://github.com/webpack/webpack/releases 目前 Webpack 4 的文檔還沒有出來,只能看 Webpack 源碼了。
默認配置
在 Webpack 4 中,不再強制要求指定 entry 和 output 路徑。webpack 4 會默認 entry 為 ./src,output 為 ./dist
構建模式 mode:
Webpack 4 配置, 必須配置 mode 屬性, 可選值有 development,production,none
development 默認開啟插件(無需配置):
- NamedModulesPlugin->optimization.namedModules
- development 模式 使用 eval 構建 module,用來提升構建速度
- webpack.DefinePlugin 插件的 process.env.NODE_ENV 的值不需要再定義,默認是 development
production 默認開啟插件(無需配置):
- NoEmitOnErrorsPlugin->optimization.noEmitOnErrors
- ModuleConcatenationPlugin->optimization.concatenateModules
- webpack.DefinePlugin 插件的 process.env.NODE_ENV 的值不需要再定義,默認是 production
公共代碼提取
Webpack3的commonschunk hash問題非常的不雅,使用複雜, Webpack 4 直接將
CommonsChunkPlugin 插件直接改為 optimization.splitChunks和 optimization.runtimeChunk 兩個配置- Webpack 3
plugins:[ new webpack.optimize.CommonsChunkPlugin({ names: common}), new webpack.optimize.CommonsChunkPlugin({ name: runtime, chunks:[common]})]
- Webpack 4
optimization: { splitChunks: { chunks: all, name: common, }, runtimeChunk: { name: runtime, } }
壓縮
壓縮插件更新到 uglifyjs-webpack-plugin 1.0 版本,支持多進程壓縮,緩存以及es6語法,無需單獨安裝轉換器。當 mode=production 默認開啟壓縮,無需配置。可以通過 optimization.minimize
和 optimization.minimizer
自定義配置。測試發現,第二次打包時間是第一次打包的一半左右。
optimization.minimize
是否啟用壓縮optimization.minimizer
制定壓縮庫, 默認uglifyjs-webpack-plugin 1.0
optimization: { minimize:true}
Webpack4 代碼: WebpackOptionsDefaulte.js#L261
優化配置
Webpack 4 默認內置了一些配置, 但額外又增加了一些配置,比如 optimization 配置屬性,差不多 20 各左右的屬性配置, 具體看webpack/schemas/WebpackOptions.json
sideEffects 構建大小優化
Webpack 4 提供了 sideEffects 的配置,引入的第三方插件在 package.json 裡面配置 sideEffects:false 後,據說是可以大幅度地減小打包出的文件的體積,具體待驗證。
目前初步了解 sideEffects 的信息:sideEffects:false 表示該模塊無副作用。當你需要導入,但不需要導出任何東西時,但需要在導入時做其他事情(必然初始化,pollyfill等),這就是導入模塊的副作用. 目前對這個理解的不多,具體在第三方庫的構建上面沒有一個直觀的感受,需要繼續深入了解。
目前查到的資料:https://stackoverflow.com/questions/41127479/es6-import-for-side-effects-meaning
插件事件註冊與調用
Webpack4 代碼層面最大的變化是整個Plugin的事件註冊和事件觸發機制完全重寫了,導致大部分第三方插件都要修改才能用,有些插件作者一兩年都沒有更新,提了issue只能耐心等待,如果要用只能自己硬著頭皮去翻源碼然後PR了。 到目前為止, 常用的插件都已經適配。
Webpack3:
註冊:
compiler.plugin(『done』,callback)
觸發:
compilitation.applyPlugins(『done』,params)
Webpack4:
- 註冊:
compiler.hooks.done.tap(『mypluinname』,callback)
- 觸發:
compiler.hooks.done.call()
常用插件版本升級
- eslint-loader: ^ 2.0.0
- file-loader:^1.1.10
- vue-loader: ^14.1.1
- webpack-hot-middleware
- extract-text-webpack-plugin: ^4.0.0-beta.0
- html-webpack-plugin : ^3.0.6
工程化支持
easywebpack 前端工程化方案已經支持 Webpack4 配置, 對應方案是 ^4.x.x 版本。
如果你之前已經使用 easywebpack(webpack3)工程化方案, 你只需要按照版本發布指引升級或刪除 package.json 對應插件依賴即可。 webpack.config.js
無需修改,easywebpack 4 已經向下兼容了。已經適配 Webpack4 的骨架項目代碼在對應的 webpack4 分支,有需要可以玩玩。詳細版本請見:easywebpack 版本發布歷史
- egg-vue-webpack-boilerplate 基於 Egg + Vue + Webpack4 多頁面SSR項目
- egg-react-webpack-boilerplate 基於 Egg + React + Webpack4 多頁面SSR項目
- webpack-static-html HTML靜態多頁面 Webpack 構建工程化解決方案骨架
已有項目升級
- 安裝 `easywebpack-cli` 最新版本進行升級
npm i easywebpack-cli -g
- 升級依賴
easy upgrade
重新安裝依賴後,運行即可。
參考資料
https://github.com/webpack/webpack/releases
https://medium.com/webpack/webpack-4-released-today-6cdb994702d4
https://github.com/dwqs/blog/issues/60
推薦閱讀:
※我如何將 Webpack 包大小縮減一半
※Start React with Webpack
※webpack增量打包
※Tree-Shaking性能優化實踐 - 原理篇
※webpack3之Scope Hoisting