Webpack 3 升级至 Webpack 4 实战指南:常见报错与解决方案

作者:编译时光

时间:2026-10-22

浏览:403

本文记录了将 Webpack 3 项目升级至 Webpack 4 的实际过程与遇到的典型问题。主要涉及安装 webpack-cli 解决 CLI 缺失报错、处理 webpack-dev-server 版本兼容性、将 CommonsChunkPlugin 迁移至 SplitChunksPlugin 的配置细节,以及修复 happypack 和 html-webpack-plugin 因 API 变更导致的运行时错误。通过具体案例展示了构建速度提升及模块拆分效果,为同类项目升级提供参考。

文章目录

Webpack 3 升级至 Webpack 4 概述

Webpack 4 发布已有一段时间,此前曾尝试进行过升级但因故中止。今日重新尝试并完成升级,过程虽有些棘手但最终成功。

首先展示原有的 Webpack 3 配置文件内容。

注:本文作者自谦配置较为简单,以下直接开始具体操作步骤。

安装 webpack-cli 解决 CLI 缺失问题

第一步:将 Webpack 升级至 4.0 版本,并安装 webpack-cli。


yarn add webpack-cli global<br>yarn add webpack-cli -D

若未安装 webpack-cli,运行命令时会抛出如下错误:

The CLI moved into a separate package:webpack-cli. Please install 'webpack-cli' in addition to webpack itself to use the CLI. ->when using npm: npm install webpack-cli -D ->when using yarn: yarn add webpack-cli -D

第二步:检查并更新相关依赖包。

处理 webpack-dev-server 兼容性报错

继续执行 yarn run dev 命令时,再次出现报错。

Error: Cannot find module 'webpack/bin/config-yargs' at Function.Module._resolveFilename (module.js:538:15) at Function.Module._load (module.js:468:25) at Module.require (module.js:587:17) at require (internal/module.js:11:18) at Object.<anonymous> (C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\webpack-dev-server\bin\webpack-dev-server.js:54:1) at Module._compile (module.js:643:30) at Object.Module._extensions..js (module.js:654:10) at Module.load (module.js:556:32) at tryModuleLoad (module.js:499:12) at Function.Module._load (module.js:491:3) error Command failed with exit code 1.

解决方法:该错误表明当前版本的 webpack-dev-server 不兼容 Webpack 4,需进行升级。


yarn add webpack-dev-server@3.1.1 -D //我装的是3.1.1的包

查阅资料发现,只要 webpack-dev-server 版本在 3.0 以上通常即可兼容。实际测试中,使用 3.0.0-alpha6 版本成功通过。

迁移 CommonsChunkPlugin 至 SplitChunksPlugin

第三步:移除 CommonsChunkPlugin,改用 webpack.optimize.SplitChunksPlugin。

再次执行 yarn run dev 后,又出现新的错误。面对连续报错,只能逐一排查解决。

错误原因分析:

Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead

Webpack 4 废弃了诸多 API。此前配置公共代码拆分及第三方库打包较为繁琐,官方直接移除了旧插件并引入了 webpack.optimize.SplitChunksPlugin。

关于该插件的使用,经过长时间摸索并参考官方示例后有了清晰思路。若熟悉旧的 CommonsChunkPlugin,直接查阅官方示例即可理解。此处提供官方 example 链接,重点参考如何打包多文件入口及 common-chunk-add-vendor-chunk 示例,该示例直观展示了公共代码与第三方库的拆分方法。

关于打包 runtime 代码,Webpack 4 直接调用新方法即可,无需额外配置。


 new webpack.optimize.RuntimeChunkPlugin({
      name: "manifest"
    }),

此处附上 webpack.optimize.SplitChunksPlugin 的详细用法,感兴趣者可自行研究。


new webpack.optimize.SplitChunksPlugin({
          chunks: "initial", // 必须三选一: "initial" | "all"(默认就是all) | "async"
          minSize: 0, // 最小尺寸,默认0
          minChunks: 1, // 最小 chunk ,默认1
          maxAsyncRequests: 1, // 最大异步请求数, 默认1
          maxInitialRequests: 1, // 最大初始化请求书,默认1
          name: function () {
          }, // 名称,此选项可接收 function
          cacheGroups: { // 这里开始设置缓存的 chunks
            priority: 0, // 缓存组优先级
            vendor: { // key 为entry中定义的 入口名称
              chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是异步)
              name: "vendor", // 要缓存的 分隔出来的 chunk 名称
              minSize: 0,
              minChunks: 1,
              enforce: true,
              maxAsyncRequests: 1, // 最大异步请求数, 默认1
              maxInitialRequests: 1, // 最大初始化请求书,默认1
              reuseExistingChunk: true // 可设置是否重用该chunk(查看源码没有发现默认值)
            }
          }
        }),

最后附上修改后的 webpack.optimize.SplitChunksPlugin 配置代码。


new webpack.optimize.SplitChunksPlugin({
      cacheGroups: {
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
        //打包重复出现的代码
        vendor: {
          chunks: 'initial',
          minChunks: 2,
          maxInitialRequests: 5, // The default limit is too small to showcase the effect
          minSize: 0, // This is example is too small to create commons chunks
          name: 'vendor'
        },
        //打包第三方类库
        commons: {
          name: "commons",
          chunks: "initial",
          minChunks: Infinity
        }
      }
    }),

    new webpack.optimize.RuntimeChunkPlugin({
      name: "manifest"
    }),

升级 happypack 以适配多线程打包

第四步:升级 happypack 插件。

使用红字强调:若项目中使用了 happypack 进行多线程打包加速,务必注意升级该插件。此前因未升级导致长时间卡住,查阅他人配置后才得知 happypack 也不兼容新版 Webpack。以下为当时的错误提示:

TypeError: Cannot read property 'length' of undefined at resolveLoader (C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\happypack\lib\WebpackUtils.js:138:17) at C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\happypack\lib\WebpackUtils.js:126:7 at C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\happypack\node_modules\async\lib\async.js:713:13

解决方法:直接升级 happypack 至兼容版本。

修复 html-webpack-plugin 及其他插件兼容性问题

第五步:其余问题多因当前包与 Webpack 4 不兼容导致,此处直接列出解决方案。

var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, { ^

TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function at C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\html-webpack-plugin\lib\compiler.js:81:51 at compile (C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\webpack\lib\Compiler.js:240:11) at hooks.afterCompile.callAsync.err (C:\Users\hboxs022\Desktop\webpack-demo\webpack-demo\node_modules\webpack\lib\Compiler.js:488:14)解决方法:升级 html-webpack-plugin


yarn add webpack-contrib/html-webpack-plugin -D

最后,extract-text-webpack-plugin 和 sass-loader 也需进行升级。具体的 Webpack 4 完整配置将在文末的 Demo 中提供,供读者参考安装。

构建测试与性能对比

第六步:配置完成后进行测试。

开发环境测试:

执行 yarn run start,效果正常。查看构建时间为 9891ms,对比图中 Webpack 3 的 17161ms,速度有明显提升。


:\Users\hboxs022\Desktop\webpack4>yarn run dev
yarn run v1.3.2
$ set NODE_ENV=dev && webpack-dev-server
Happy[js]: Version: 5.0.0-beta.3. Threads: 6 (shared pool)
(node:2060) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
i 「wds」: Project is running at http://localhost:8072/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from C:\Users\hboxs022\Desktop\webpack4\src
Happy[js]: All set; signaling webpack to proceed.
Happy[css]: Version: 5.0.0-beta.3. Threads: 6 (shared pool)
Happy[css]: All set; signaling webpack to proceed.
(node:2060) DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
i 「wdm」: wait until bundle finished: /page/index.html
i 「wdm」: Hash: 1911cfc871cd5dc27aca
Version: webpack 4.1.1
Time: 9891ms
Built at: 2018-3-28 18:49:25

Webpack 3 升级至 Webpack 4 概述

生产环境测试:


yarn run build

Webpack 3 升级至 Webpack 4 概述

执行结果正常。第三方库 jquery 已打包至 common 中,公共 JS 代码打包进 vendor,公共样式也打包进 vendor 并分离为 vendor.css。

Webpack 3 升级至 Webpack 4 概述

目录结构符合预期,模块 ID 也已固定。

接下来查看速度对比情况。

Webpack 3 构建结果:

Webpack 3 升级至 Webpack 4 概述

Webpack 4 构建结果:是否是我的错觉?

Webpack 3 升级至 Webpack 4 概述

最后附上 Webpack 4 的 GitHub 链接。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章