一、Node版本依賴重新調整
官方不再支持node4以下的版本,依賴node的環境版本>=6.11.5,當然考慮到最佳的es6特性實現,建議node版本可以升級到V8.9.4或以上版本,具體更新說明部分可以見:webpack4更新日誌
"engines": {
"node": ">=6.11.5" // >=8.9.4 (recommendation version)
},
二、用更加快捷的mode模式來優化配置文件
webpack4中提供的mode有兩個值:development和production,默認值是 production。mode是我們爲減小生產環境構建體積以及節約開發環境的構建時間提供的一種優化方案,提供對應的構建參數項的默認開啓或關閉,降低配置成本。
開啓方式 1:直接在啓動命令後加入參數
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
開啓方式 2:可以在配置文件中加入一個mode屬性:
module.exports = {
mode: 'production' // development
};
development模式下,將側重於功能調試和優化開發體驗,包含如下內容:
- 瀏覽器調試工具
- 開發階段的詳細錯誤日誌和提示
- 快速和優化的增量構建機制
production模式下,將側重於模塊體積優化和線上部署,包含如下內容:
- 開啓所有的優化代碼
- 更小的bundle大小
- 去除掉只在開發階段運行的代碼
- Scope hoisting和Tree-shaking
- 自動啓用uglifyjs對代碼進行壓縮
webpack一直以來最飽受詬病的就是其配置門檻極高,配置內容複雜而繁瑣,容易讓人從入門到放棄,而它的後起之秀如rollup,parcel等均在配置流程上做了極大的優化,做到開箱即用,webpack在V4中應該也從中借鑑了不少經驗來提升自身的配置效率,詳見內容可以參考這篇文章《webpack 4: mode and optimization》
三、再見commonchunk,你好optimization
從webpack4開始官方移除了commonchunk插件,改用了optimization屬性進行更加靈活的配置,這也應該是從V3升級到V4的代碼修改過程中最爲複雜的一部分,下面的代碼即是optimize.splitChunks 中的一些配置參考,
module.exports = {
optimization: {
runtimeChunk: {
name: 'manifest'
},
minimizer: true, // [new UglifyJsPlugin({...})]
splitChunks:{
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: false,
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'initial',
priority: -10,
reuseExistingChunk: false,
test: /node_modules\/(.*)\.js/
},
styles: {
name: 'styles',
test: /\.(scss|css)$/,
chunks: 'all',
minChunks: 1,
reuseExistingChunk: true,
enforce: true
}
}
}
}
}
從中我們不難發現,其主要變化有如下幾個方面:
- commonchunk配置項被徹底去掉,之前需要通過配置兩次new webpack.optimize.CommonsChunkPlugin來分別獲取vendor和manifest的通用chunk方式已經做了整合, 直接在optimization中配置runtimeChunk和splitChunks即可 ,提取功能也更爲強大,具體配置見:splitChunks
- runtimeChunk可以配置成true,single或者對象,用自動計算當前構建的一些基礎chunk信息,類似之前版本中的manifest信息獲取方式。
- webpack.optimize.UglifyJsPlugin現在也不需要了,只需要使用optimization.minimize爲true就行,production mode下面自動爲true,當然如果想使用第三方的壓縮插件也可以在optimization.minimizer的數組列表中進行配置
四、ExtractTextWebpackPlugin調整,建議選用新的CSS文件提取插件mini-css-extract-plugin
由於webpack4以後對css模塊支持的逐步完善和commonchunk插件的移除,在處理css文件提取的計算方式上也做了些調整,之前我們首選使用的extract-text-webpack-plugin也完成了其歷史使命,將讓位於mini-css-extract-plugin
基本配置如下:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // replace ExtractTextPlugin.extract({..})
"css-loader"
]
}
]
}
}
生產環境下的配置優化:
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin({}) // use OptimizeCSSAssetsPlugin
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/app.[name].css',
chunkFilename: 'css/app.[contenthash:12].css' // use contenthash *
})
]
....
}
將多個css chunk合併成一個css文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.scss|css$/,
chunks: 'all', // merge all the css chunk to one file
enforce: true
}
}
}
}
}
五、其他調整項備忘
- NoEmitOnErrorsPlugin- > optimization.noEmitOnErrors(默認情況下處於生產模式)
- ModuleConcatenationPlugin- > optimization.concatenateModules(默認情況下處於生產模式)
- NamedModulesPlugin- > optimization.namedModules(在開發模式下默認開啓)
- webpack命令優化 -> 發佈了獨立的 webpack-cli 命令行工具包
- webpack-dev-server -> 建議升級到最新版本
- html-webpack-plugin -> 建議升級到的最新版本
- file-loader -> 建議升級到最新版本
- url-loader -> 建議升級到最新版本