升级 webpack5

 

升级 webpack5

webpack5 已经发布很长时间了, 不论打包体积还是构建效率, 都比 webpack4 提升了太多。 早就想在实际项目中操作一番, 正好目前我们项目中使用的是 webpack4, 且需要做一些优化, 于是就有了这个升级 webpack5 的过程,整体坑还是可控,遂将采坑记录一下, 方便其他人。

1. webpack5 所依赖的插件升级

查阅 webpack 升级文档, 相关的 plugin/loader 都需要升级, 如果手动一个一个升, 无疑是费时费力, 这里提供一个 npm 包, npm-check-updates, 它可以检测 package.json 中所有依赖的最新版本, 并将版本更新到最新, 最后只需要执行 npm i 即可将所有依赖升级到最新版本

安装 npm-check-updates

这里有两种方式 全局安装 npm install -g npm-check-updates 或者局部安装 npm install npm-check-updates --save-dev

在 package.json 根目录下执行 npm-check-updates 或者 npx npm-check-updates 他就会检测 package.json 中各依赖的版本, 如下图

npm-check-updates 检测版本

然后执行 ncu -u 即可更新 package.json 中的版本号, 最后执行 npm i 就可以安装最新的依赖

2. 优化报错信息

我们的 webpack 配置不是用的 webpack 配置文件做的, 而是使用 webpack 函数执行以后得到的 compiler 对象,然后执行 compiler.run 方法, 从回调里拿到构建信息, 代码如下

// 处理错误信息
function dealErr(err, stats) {
  if (err) {
      console.error(err.stack || err);
      if (err.details) console.error(err.details);
      return true;
  }

  var errorOrWarn = false;

  var info = stats.toJson();
  if (stats.hasErrors()) {
      errorOrWarn = true;
      exports.danger(info.errors && info.errors.join(''));
  }
  if (stats.hasWarnings()) {
      errorOrWarn = true;
      exports.danger(info.warnings && info.warnings.join(''));
  }

  return errorOrWarn;
}

const compiler = webpack(configJs); // configJs 即为 webpack 的配置项
compiler.run(function (err, stats) {
    var hasError = dealErr(err, stats);
    if (hasError) return;

    console.log('build success!');

    console.log(
        stats.toString({
            assets: true,
            assetsSort: '!size',
            children: false,
            chunks: false,
            chunkModules: false,
            colors: true,
            modules: false,
        })
    );
});

上述代码有个不好的地方, 就是报错信息不明确, dealErr 函数中的这几行

var info = stats.toJson();
if (stats.hasErrors()) {
    errorOrWarn = true;
    exports.danger(info.errors && info.errors.join(''));
}
if (stats.hasWarnings()) {
    errorOrWarn = true;
    exports.danger(info.warnings && info.warnings.join(''));
}

会将 stats 中的 errorswarnings 全部变成 [object, Object], 然后升级为 webpack5 以后, 构建控制台是这样的

npm-check-updates 检测版本

报错信息不明显, 所以需要更改一下, 在 webpack 配置选项中增加如下

const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')

module.exports = {
  plugins: [
    new FriendlyErrorsWebpackPlugin()
  ],
  stats: 'errors-only'
}

增加配置以后, 错误信息、警告信息就可以很好的识别了

3. 使用 webpack5 构建代码, 处理报错信息

上述配置完成以后, 就可以使用 webpack5 去构建代码, 查看控制台报错, 当把所有错误改完以后,webpack5 也就升级完成了, 因为写这篇文章是升级完成以后写的, 所以好多错误没有留下图片记录, 大部分以文字记录

对了, 构建之前可以先阅读一下升级文档,对升级有一个大致的了解, 将一些废弃的配置项以及废弃的插件和 loader 给去掉

下面具体说一下这次改动遇到的问题

  1. optimization.splitChunks.cacheGroups.vendors → optimization.splitChunks.cacheGroups.defaultVendors

  2. optimize-css-assets-webpack-plugin → css-minimizer-webpack-plugin

  3. hard-source-webpack-plugin 插件废弃, 使用这个插件会报错 TypeError: Cannot read property 'tap' of undefined。使用缓存, webpack5 有个配置项 cache, 具体文档在这里, 可以参考这个来配置缓存

  4. HashedModuleIdsPlugin → optimization.moduleIds: 'hashed', optimization.moduleIds: 'deterministic' 有易于长期缓存, 于是将该配置设置成 optimization.moduleIds: 'deterministic'

  5. terser-webpack-plugin 插件配置也有一些变化

  6. webpack4Rule.loaders 的配置已经被废弃掉,而在 webpack5 中使用 Rule.use 代替,相应的 loader 也要使用对象的形式来书写

  7. file-loader → 资源模块 asset/resource, 这里比较坑,配置文档比较隐蔽

以上,大概就这么多吧。 就这样吧!!!