Webpack 5.x 的十个踩坑记录

9,064 阅读2分钟

必须先吐槽一下 webpack5.x,踩坑都要踩哭了,小小总结,不成敬意~

1. webpack-dev-server 无法启动项目

解决:要注意 webpack-dev-server 版本

// package.json
{
  "scripts": {
    // webpack-dev-server 4.x
    "serve": "webpack-dev-server --config webpack.dev.js"

    // webpack-dev-server 5.x
    "serve": "webpack server --config webpack.dev.js"
  }
}

2. 启动项目之后报错

Error: getaddrinfo ENOTFOUND localhost at GetAddrInfoReqWrap.onlookup [as oncomplete]

解决:需开启本地 host 的 127.0.0.1

3. devtool

webpack/devtool

module.exports = {
  // webpack 4.x
  devtool: 'cheap-eval-module-source-map',

  // webpack 5.x
  devtool: 'eval-cheap-module-source-map'
}

4. 开启 hot: true 但是热更新无效

解决需要兼容 webpack5.x

webpack-dev-server/issues2758

module.exports = {
  target: 'web', // webpack5.x 加上之后热更新才有效果
}

还需要注意一个问题:如果使用了 mini-css-extract-plugin 插件(将样式以 link 的形式引入而不是 style 标签注入),则样式的热更新无效。

解决:需要判断开发模式使用 style 注入的形式,否则使用 link 引用的形式

// webpack.common.js

// 是否开发者模式
const devMode = process.env.NODE_ENV !== 'production'
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      },
      {
        test: /\.less$/,
        exclude: /node_modules/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader'
        ] // 解析 less
      },
    ]
  }
}

5. html-webpack-plugin报错

DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.

解决:需要兼容 webpack5.x

webpack/issues11997

yarn add html-webpack-plugin@next --dev

6. 使用 html-webpack-plugin 报错

ERROR in Conflict: Multiple assets emit different content to the same filename index.html

说明:使用 html-webpack-plugin 之后会生成 index.html 文件,此时会报错

解决:

① 去掉 public/index.html 文件

② 将 public/index.html 中的文件放入 src 下,重新指定模板路径为 src/index.html

③ 使用 templateContent 属性自己定义 html 模板

// webpack.common.js
const { templateContent } = require('./template')

module.exports = {
  plugins: [
    // webpack 5.x 报 有重复文件错误解决方法
    new HtmlWebpackPlugin({
      url: './',
      title: 'My Webpack',
      filename: 'index.html'
      // template: './public/index.html', // 方法1: 去掉此文件
      // template: './src/index.html', // 方法2:可将模板文件放入其他路径
      templateContent: ({ htmlWebpackPlugin }) => templateContent(htmlWebpackPlugin), // 方法3 使用 templateContent 属性自己写
    }),
  ],
}
// template/index.js
// html-webpack-plugin 属于templateContent 属性形式的模板文件
function templateContent (htmlWebpackPlugin) {
  return `
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="${htmlWebpackPlugin.options.url}favicon.ico">
        <title>${htmlWebpackPlugin.options.title}</title>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but ${htmlWebpackPlugin.options.title} doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
          <!-- built files will be auto injected -->
        </body>
      </html>`
}

module.exports = { templateContent }

7. 使用 webpack-merge 报错

TypeError: merge is not a function

webpack-merge提供了merge连接数组并合并对象以创建新对象的功能

解决:兼容 webpack5.x

// webpack 4.x
const merge = require('webpack-merge')

// webpack 5.x
const { merge } = require('webpack-merge')

// 接下来可以进行合并
const common = require('./webpack.common')

module.exports = merge(common, {
  ... // 配置们
}

8. 使用 copy-webpack-plugin 报错

ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.

解决:兼容 webpack5.x

 module.exports = {
  plugins: [
    // webpack 4.x 
    new CopyWebpackPlugin(['public'])

    // webpack 5.x
    new CopyWebpackPlugin({
      patterns: [
        { from: 'public', to: 'public' }
      ]
    })
  ]
}

9. 使用 optimize-css-assets-webpack-plugin时会有如下警告,但不影响打包

[DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS] DeprecationWarning: optimizeChunkAssets is deprecated (use Compilation.hook.processAssets instead and use one of Compilation.PROCESS_ASSETS_STAGE_* as stage option)(Use node --trace-deprecation ... to show where the warning was created)

解决:webpack 5.x 的问题,可以考虑换个插件(官方准备弃用了)

optimize-css-assets-webpack-plugin/issues134

yarn add css-assets-webpack-plugin --dev

10. 安装 imagemin-webpack-plugin 依赖失败,提示 autoreconf: command not found

解决:

macOS 没有安装 brew 的要先(到墙外)安装

brew 官方 可以看到安装命令【安装超级慢,需耐心等待...】

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

安装好后再用 brew 安装 autoreconf

brew install autoconf automake libtool

接下来就可以继续安装了


如果有写的不对不好的地方,还请各位大佬指正批评啦~