记webpack3到webpack4的升级之路

记webpack3.0到webpack4.0的升级过程

前言:

由于管理后台webpack3.0每次打包需要切换到8.x.x版本的Node;这样切换来切换过去,实在忍受不了,趁着某个功能迭代的时机把webpack版本升级到4.0,同时记录升级过程中遇到的问题。

主要升级的俩个部分是:babel和webpack

babel(升级到babel7)

升级babel7的过程中,需要将babel的基本的包更新,原来babel6的依赖的包基本上都要舍弃掉

在升级babel7的过程中,有一些相关包名的变化;比如:

  • babel-core => @babel/core; babel-preset-react => @babel/preset-react
  • preset-es20xx弃用,改为 @babel/preset-env
  • babel-preset-stage-0 => @babel/preset-stage-0

babel配置迁移:

  • 将babel的配置从package.json移入到babel.config.js文件中;

  • 同时对可选链和空值的支持

    1
    2
    3
    4
    plugins: [
    '@babel/plugin-proposal-optional-chaining',
    '@babel/plugin-proposal-nullish-coalescing-operator',
    ]

webpack(升级到webpack4)

webpack升级主要是先将webpack版本升级,将对应的依赖的插件升级到webpack4的需要的版本和一些方法和属性的变化和新增。

webpack相关依赖版本升级

  • webpack v3.11.0 => webpack v4.46.0 ;引入依赖webpack-cli v3.3.12
  • webpack-dev-server: v2.5.0 => v3.11.0
  • html-webpack-plugin: v2.29.0 => v4.3.0
  • 移除 CommonsChunkPlugin,默认使用 SplitChunksPlugin 分割代码
  • 配置 mode属性
  • 移除 extract-text-webpack-plugin,引入 mini-css-extract-plugin 并配置 css-loader
  • 移除happypack,引入 thread-loader
  • 移除uglifyjs-webpack-plugin,引入terser-webpack-plugin 压缩js
  • react-dev-utils : v3.0.2 => v10.2.1 , createCompiler方法传参发生改变(传参变更为object)
  • webpackDevServer的setup方法被替换为beforeafter
  • 主题色配置采用less-loader modifyVars变量配置
  • 支持svg图标的使用, 引入@svgr/webpack
  • 配置optimization字段
    • 引入terser-webpack-plugin 压缩js
    • 引入optimize-css-assets-webpack-plugin 压缩css
    • splitChunks 配置 将chunk的方式由all更改为 async,同时将多个css chunk合并成一个css文件,减少请求

webpack4升级中的问题

问题1: 当升级依赖html-webpack-plugin版本的时候,遇到的问题:this.htmlWebpackPlugin.getHooks is not a function

解决方案:

1
2
webpack3 => new InterpolateHtmlPlugin(env.raw),
webpack4 => new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),

问题2:Cannot read property ‘tapPromise’ of undefined

解决方案:

升级add-asset-html-webpack-plugin版本: v2.1.2 => v3.1.3


问题3: Plugin could not be registered at ‘html-webpack-plugin-before-html-processing’. Hook was not found.

解决方案:

  • 升级webpack

    1
    2
    3
    4
    webpack `v3.11.0` => webpack `v4.46.0` 
    引入依赖webpack-cli `v3.3.11`
    webpack-dev-server: `v2.5.0 ` => `v3.7.2`
    html-webpack-plugin: `v2.29.0` => `v4.3.0`
  • InterpolateHtmlPlugin放在HtmlWebpackPlugin之后

    1
    2
    3
    4
    5
    6
    7
    8
    9
    module.exports ={
    //...
    plugins:[
    new HtmlWebpackPlugin({
    //...
    }),
    new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw)
    ]
    }

问题4: TypeError [ERR_INVALID_ARG_TYPE]: The “path” argument must be of type string. Received undefined

解决方案: 升级webpack-manifest-plugin版本


问题5: asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).【配置静态文件大小限制】

解决方案:

1
2
3
4
5
performance: {
hints: "warning",
maxEntrypointSize: 5000 * 1024,
maxAssetSize: 5000 * 1024,
},

问题6: error:despite it was not able to fulfill desired ordering with these modules:

解决方案:

1
2
3
new MiniCssExtractPlugin({
ignoreOrder: true,
}),

问题7: dev启动开发环境,识别不了css样式中的@符号

添加参数libraryDirectory:'es'

1
2
3
4
5
6
7
8
9
{
loader: 'babel-loader',
options: {
plugins: [
['import', { libraryName: 'antd', style: true ,libraryDirectory: 'es'}]
],
cacheDirectory: true,
}
},

webpack4升级优化的点

引入thread-loader加快打包速度

1
2
3
4
5
例如:
{
test: /\.css$/,
use: ['thread-loader', 'style-loader', 'css-loader'],
},

将chunk的方式由all更改为 async, 同时将多个css chunk合并成一个css文件,减少请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
automaticNameMaxLength: 30,
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: -10
},
styles: {
test: /\.less|css$/,
name: 'styles',
priority: -10
}
}
},

支持svg引入@svgr/webpack

1
2
3
4
{
test: /\.svg$/,
use: ['@svgr/webpack'],
},

优化体验

webpack3.0 打包构建时间

image-20210330095657679

webpack4.0 打包构建时间 构建时间上加快了一分多钟

image-20210330152441292

image-20210402105429211

webpack3与webpack4开发依赖对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
webpack "^3.11.0"
webpack-dev-server "^2.5.0"
html-webpack-plugin "^2.29.0"
extract-text-webpack-plugin "^3.0.2"
webpack-manifest-plugin "1.1.1"
add-asset-html-webpack-plugin "^2.1.2"
uglifyjs-webpack-plugin "^1.2.4"
react-dev-utils "^3.0.2"
babel-core "6.25.0"
happypack "^4.0.0"
file-loader "0.11.2"
babel-plugin-import "^1.2.1"
css-loader "0.28.4"
less-loader "^4.0.5"


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
webpack "^4.46.0"
webpack-cli "^3.3.12"
webpack-dev-server "^3.11.0"
html-webpack-plugin "^4.3.0"
mini-css-extract-plugin "^1.3.9"
webpack-manifest-plugin "^2.2.0"
add-asset-html-webpack-plugin "^3.1.3"
terser-webpack-plugin "^3.0.6"
babel-plugin-import "1.13.0"
react-dev-utils "^10.2.1"
@babel/core "^7.13.10"
thread-loader "^2.1.3"
file-loader "6.1.1"
optimize-css-assets-webpack-plugin "^5.0.4"
postcss-safe-parser "^5.0.2"
css-loader "^3.6.0"
less-loader "^7.0.0"

总结

webpack3到webpack4的升级,主要做了以下这些事情

  • 升级依赖:升级webpack版本 ,升级html-webpack-plugin版本等
  • 代码分割:移除了CommonsChunkPlugin;引入SplitChunksPlugin,设置mode属性为production,optimization配置splitChunk拆分资源
  • 压缩css:移除extract-text-webpack-plugin;引入mini-css-extract-plugin,使用mini-css-extract-plugin的loader重新配置less-loader和css-loader,配置svg
  • 构建加速: 替换happypack为thread-loader,多线程式本地构建和生产构建
  • 代码热更新:升级webpack-cli和webpack-dev-server,并且设置mode为development

参考

https://mp.weixin.qq.com/s/yzmHYJ3KjSJ_EUTJ0hbkfA

https://segmentfault.com/a/1190000022205477


本文由 Abert 创作,采用 知识共享署名 4.0 国际许可协议。

本站文章除注明转载/出处外,均为本站原创或翻译,转载请务必署名。