webpack-summary
webpack-summary copied to clipboard
webpack3 升级到 webpack4
webpac 4 是一个大版本,其中 plugin 机制都变化挺大的,几乎所有的 plugin 都需要升级来做兼容,这里简单记录一下遇到的一些问题。
1. webpack-cli
webpack 4
把核心代码和客户端分离开了,现在需要安装一个 webpack-cli
才可以启动 webpack
命令。
全局安装:
npm i webpack-cli -g
项目依赖:
npm i webpack --save-dev
npm i webpack-cli --save-dev
或者 package.json 配置:
{
"webpack": "^4.1.1",
"webpack-cli": "^2.0.12"
}
2. html-webpack-plugin
html-webpack-plugin
要升级到 3.0.6
以上即可。
3. module.loaders
替换为 modules.rules
module: {
loaders: [
...
]
}
替换为:
module: {
rules: [
...
]
}
4. 单独打包 CSS 的 extract-text-webpack-plugin
extract-text-webpack-plugin
暂不支持 webpack 4,我们可以使用另外一个插件 mini-css-extract-plugin 来替换之。
举个栗子(顺便支持一下 less):
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
...
optimization: {
minimizer: [
new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({ filename: 'css/index.css' }),
],
...
module: {
rules: [
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
]
}
5. mode
webpack 4
增加了一个 mode
配置,值可选有两个 development
和 production
,对不同的环境他会提供不同的一些默认配置,比如开发环境下默认开启 optimization.namedModules
(原NamedModulesPlugin,现已弃用),而生产环境默认使用 `optimization.noEmitOnErrors(原NoEmitOnErrorsPlugin,现已弃用)。
不同模式下的默认配置:
- 生产环境默认开启了很多代码优化(minify,splite 等)
- 开发时开启注视和验证,并且自动加上了 eval devtool
- 生产环境不支持 watching,开发环境优化了重新打包的速度
- 生产环境开启模块串联(原
ModuleConcatenationPlugin
),没用过不多说 - 自动设置
process.env.NODE_ENV
到不同环境,也就是不需要DefinePlugin
来做这个了 - 如果你给
mode
设置为none
,所有默认配置都去掉了
6. CommonsChunkPlugin
CommonsChunkPlugin删除之后,改成使用optimization.splitChunks进行模块划分,详细文档看 这里。
官方的说法是默认设置已经对大部分用户来说非常棒了,但是需要注意一个问题,默认配置只会对异步请求的模块进行提取拆分,如果要对 entry
进行拆分,需要设置 optimization.splitChunks.chunks = 'all'
。
对应之前我们拆分runtime的情况,现在也有一个配置optimization.runtimeChunk,设置为true就会自动拆分runtime文件。
真实例子 webpack.conf.js
'use strict';
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // Html文件处理
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(__dirname, './build'), // This is where images AND js will go
publicPath: '', // This is used to generate URLs to e.g. images
filename: 'js/[name].js',
chunkFilename: 'js/[id].chunk.js?[hash:8]'
},
mode: 'development', // 'production'
optimization: {
minimizer: [
new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
// 单独打包CSS
new MiniCssExtractPlugin({ filename: 'css/index.css' }),
new CopyWebpackPlugin([
{ from: 'src/images/*', to: 'images/', flatten: true},
{ from: 'src/parallax/*', to: 'js/', flatten: true}
], {}),
new HtmlWebpackPlugin({
filename: 'index.html',
chunks: ['index'],
template: './src/index.html',
hash: true
})
],
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader', // ES6
exclude: /(node_modules|parallax|fullpage)/
},
// { test: /\.css$/, loader: 'style-loader!css-loader' },
// { test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // use ! to chain loaders
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
query: {
name: '[path][name].[ext]?[hash:8]',
limit: 8192 // inline base64 URLs for <=8k images, direct URLs for the rest
}
}
]
}
};
附件
- webpack ChangeLog