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。 具體見:github.com/webpack/webp 目前 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.minimizeoptimization.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等),這就是導入模塊的副作用. 目前對這個理解的不多,具體在第三方庫的構建上面沒有一個直觀的感受,需要繼續深入了解。

目前查到的資料:stackoverflow.com/quest

插件事件註冊與調用

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

重新安裝依賴後,運行即可。

參考資料

github.com/webpack/webp

medium.com/webpack/webp

github.com/dwqs/blog/is


推薦閱讀:

我如何將 Webpack 包大小縮減一半
Start React with Webpack
webpack增量打包
Tree-Shaking性能優化實踐 - 原理篇
webpack3之Scope Hoisting

TAG:webpack | 前端工程化 | 前端開發框架和庫 |