本文將詳細介紹從webpack3到webpack4的升級過程javascript
相比於webpack3,webpack4能夠零配置運行,打包速度比以前提升了90%,能夠直接到ES6的代碼進行無用代碼剔除,新增的optimization使用簡單css
在將來,CSS、HTMl和文件都會成爲原生模塊html
【0配置】前端
webpack4
設置了默認值,以便無配置啓動項目vue
entry 默認值是 ./src/ output.path 默認值是 ./dist mode 默認值是 production
【模塊類型】java
webpack4提供了5種模塊類型node
json: 可經過 require 和 import 導入的 JSON 格式的數據(默認爲 .json 的文件)
webassembly: WebAssembly 模塊,(目前是 .wasm 文件的默認類型)
javascript/auto: (webpack 3中的默認類型)支持全部的JS模塊系統:CommonJS、AMD。 javascript/esm: EcmaScript模塊(默認 .mjs 文件)。 javascript/dynamic: 僅支持 CommonJS & AMD。
相比於webpack3,webpack4新增了一個mode配置選擇,用來表示配置模式的選擇狀況webpack
module.exports = { mode: 'production' }
包括生產環境production、開發環境devolopment和自定義none這三個選擇可選git
【開發模式】github
瀏覽器調試工具
註釋、開發階段的詳細錯誤日誌和提示
快速和優化的增量構建機制
開啓 output.pathinfo 在 bundle 中顯示模塊信息
開啓 NamedModulesPlugin
開啓 NoEmitOnErrorsPlugin
【生產模式】
啓用全部優化代碼的功能 更小的bundle大小 去除只在開發階段運行的代碼 關閉內存緩存 Scope hoisting 和 Tree-shaking 開啓 NoEmitOnErrorsPlugin 開啓 ModuleConcatenationPlugin 開啓 optimization.minimize
【none】
禁用全部的默認設置
從webpack4開始官方移除了commonchunk插件,改用了optimization屬性進行更加靈活的配置,下面來介紹optimization下的一些經常使用配置項
【minimize】
利用unglifyjsWebpackPlugin插件來壓縮模塊,生產環境下該值默認爲true
optimization: { minimize: false }
【minimier】
可使用其餘插件來執行壓縮功能
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { //... optimization: { minimizer: [ new UglifyJsPlugin({ /* your config */ }) ] } };
【splitChunks】
webpack4默認使用splitChunksPlugin插件來實現代碼分割功能,來替代webpack3中的commonChunksPlugin插件
module.exports = { //... optimization: { splitChunks: { chunks: 'async', minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } }
【runtimeChunk】
經過設置 runtimeChunk: true 來爲每個入口默認添加一個只包含 runtime 的 chunk
經過提供字符串值,可使用插件的預設模式
signal: 建立一個被全部生成的塊共享的runtime文件
multiple: 爲共同的塊建立多個runtime文件
缺省值爲false,表示每一個入口塊默認內嵌runtime代碼
runtimeChunk { name: "runtime" }
【noEmitOnErrors】
只要在編譯時出現錯誤,就使用noEmitOnErrors屬性來跳過emit 階段,用來替代NoEmitOnErrorsPlugin
插件
【nameModules】
使用可讀的模塊標識,方便更好的調試。webpack在開發模式下默認開啓,生產模式下默認關閉,用來替代 NamedModulesPlugin
插件
module.exports = { //... optimization: { namedModules: true } };
下面就基於vue-cli的項目對webpack配置進行升級
一、升級nodejs
使用 webpack4 時,必須保證 Node.js 版本 >= 8.9.4,由於 webpack4 使用了大量的ES6語法,這些語法在 nodejs新版 v8 中獲得了原生支持
二、升級webpack主要部件,包括webpack、webpack-bundle-analyzer、webpack-dev-server、webpack-merge
升級的操做很簡單,先刪除,再安裝便可。但要注意的是webpack4版本中 cli 工具分離成了 webpack
核心庫 與 webpack-cli
命令行工具兩個模塊,須要使用 CLI
,必安裝 webpack-cli
至項目中
cnpm uninstall -D webpack webpack-bundle-analyzer webpack-dev-server webpack-merge
cnpm install -D webpack webpack-cli webpack-bundle-analyzer webpack-dev-server webpack-merge
三、升級webpack相關插件,包括copy-webpack-plugin、css-loader、eslint-loader、file-loader、html-webpack-plugin、url-loader、friendly-errors-webpack-plugin、optimize-css-assets-webpack-plugin、uglifyjs-webpack-plugin
cnpm uninstall -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
cnpm install -D copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin
四、升級vue-loader
因爲vue-loader升級到版本15後,配置有較多的變化,穩妥起見,能夠只將vue-loader升級到14.4.2
cnpm uninstall -D vue-loader cnpm uninstall -D vue-loader@14.4.2
五、替換webpack相關插件,extract-text-webpack-plugin替換爲mini-css-extract-plugin
cnpm uninstall -D extract-text-webpack-plugin
cnpm install -D mini-css-extract-plugin
下面對配置文件的修改進行詳細說明:
一、webpack.base.conf.js文件
增長node:process.env.NODE_ENV便可
module.exports = { + mode: process.env.NODE_ENV, ...
二、webpack.prop.conf.js文件
該文件的配置項較爲複雜
(1)將ExtractTextPlugin替換爲MiniCssExtraPlugin
+ const MiniCssExtractPlugin = require("mini-css-extract-plugin") - const ExtractTextPlugin = require('extract-text-webpack-plugin') ... - new ExtractTextPlugin({ + new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: true, }), ...
(2)刪除UglifyJsPlugin配置項
- const UglifyJsPlugin = require('uglifyjs-webpack-plugin') ... - new UglifyJsPlugin({ - uglifyOptions: { - compress: { - warnings: false - } - }, - sourceMap: config.build.productionSourceMap, - parallel: true - })
(3)刪除CommonsChunkPlugin配置項
- new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks (module) { - return ( - module.resource && - /\.js$/.test(module.resource) && - module.resource.indexOf( - path.join(__dirname, '../node_modules') - ) === 0 - ) - } - }), - new webpack.optimize.CommonsChunkPlugin({ - name: 'manifest', - minChunks: Infinity - }), - new webpack.optimize.CommonsChunkPlugin({ - name: 'app', - async: 'vendor-async', - children: true, - minChunks: 3 - }), ...
(4)添加optimization配置項
+ optimization: { + splitChunks: { + chunks: 'async', + minSize: 30000, + minChunks: 1, + maxAsyncRequests: 5, + maxInitialRequests: 3, + automaticNameDelimiter: '~', + name: true, + cacheGroups: { + vendors: { + test: /[\\/]node_modules[\\/]/, + priority: -10 + }, + default: { + minChunks: 2, + priority: -20, + reuseExistingChunk: true + } + } + }, + runtimeChunk: { name: 'runtime' } + },
詳細配置移步前端小站源碼