You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack 4.29.6升级至5.93.0遇'tapPromise'未定义错误求助

Webpack 5升级后出现Cannot read properties of undefined (reading 'tapPromise')错误解决

将Electron应用的Webpack从4.29.6升级到5.93.0后,编译时触发以下错误:

[webpack-cli] TypeError: Cannot read properties of undefined (reading 'tapPromise')
    at ESLintWebpackPlugin.apply (..sources\webapp\node_modules\eslint-webpack-plugin\dist\index.js:63:26)
    at exports.createResolver (..sources\webapp\node_modules\enhanced-resolve\lib\ResolverFactory.js:695:11)
    at ResolverFactory._create (..\sources\webapp\node_modules\webpack\lib\ResolverFactory.js:135:12)
    at ResolverFactory.get (..\sources\webapp\node_modules\webpack\lib\ResolverFactory.js:116:28)
    at NormalModuleFactory.getResolver (..\sources\webapp\node_modules\webpack\lib\NormalModuleFactory.js:1302:31)
    at defaultResolve (..\sources\webapp\node_modules\webpack\lib\NormalModuleFactory.js:759:35)
    at ..\sources\webapp\node_modules\webpack\lib\NormalModuleFactory.js:828:10
    at Hook.eval [as callAsync] (eval at create (..\sources\webapp\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:7:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (..\sources\webapp\node_modules\tapable\lib\Hook.js:18:14)
    at ..\sources\webapp\node_modules\webpack\lib\NormalModuleFactory.js:340:24

当前使用的webpack-app.config.js配置:

'use strict';

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const ESLintWebpackPlugin = require('eslint-webpack-plugin');
const paths = require('./config/paths');
const getClientEnvironment = require('./config/env');

// Webpack uses `publicPath` to determine where the app is being served from.
const publicPath = paths.servedPath;
const shouldUseRelativeAssetPaths = publicPath === './';
const publicUrl = publicPath.slice(0, -1);
const env = getClientEnvironment(publicUrl);

// Note: defined here because it will be used more than once.
const cssFilename = 'static/css/[name].css';

module.exports = {
  mode: 'development',
  bail: true,
  devtool: 'cheap-module-source-map',
  entry: [require.resolve('./src/polyfills'), 'babel-polyfill', paths.appIndexJs],
  output: {
    path: paths.appBuild,
    filename: 'static/js/[name].js',
    chunkFilename: 'static/js/[name].chunk.js',
    publicPath: publicPath,
    devtoolModuleFilenameTemplate: info => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/')
  },
  resolve: {
    modules: ['node_modules', paths.appNodeModules].concat(
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
    ),
    extensions: ['.web.js', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {
      'react-native': 'react-native-web'
    },
    plugins: [
      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
      new ESLintWebpackPlugin({ extensions: ['js', 'jsx'] }),
    ]
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.(js|jsx)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: require.resolve('react-dev-utils/eslintFormatter'),
              eslintPath: require.resolve('eslint')
            },
            loader: 'eslint-webpack-plugin',
          }
        ],
        include: paths.appSrc
      },
      {
        oneOf: [
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            type: 'asset',
            parser: {
              dataUrlCondition: {
                maxSize: 10000, // 10kb
              },
            },
            generator: {
              filename: 'static/media/[name].[hash][ext]'
            }
          },
          {
            test: /\.svg$/,
            use: [
              {
                loader: '@svgr/webpack',
                options: {
                  svgoConfig: {
                    plugins: [
                      { removeViewBox: false },
                      { cleanupIDs: false },
                      { prefixIds: false }
                    ]
                  }
                }
              },
              {
                loader: 'url-loader',
                options: {
                  limit: 10000,
                  name: 'static/media/[name].[hash].[ext]'
                }
              }
            ]
          },
          {
            test: /\.(js|jsx)$/,
            include: paths.appSrc,
            use: {
              loader: require.resolve('babel-loader'),
              options: {
                sourceMap: true
              }
            }
          },
          {
            test: /\.css$/,
            use: [
              "style-loader",
              "css-loader",
              {
                loader: "postcss-loader",
                options: {
                  postcssOptions: {
                    plugins: [
                      [
                        "postcss-preset-env",
                        {
                          // Options
                        },
                      ],
                    ],
                  },
                },
              },
            ],
          },
          {
            test: /\.(eot|otf|ttf|woff|woff2)$/,
            type: 'asset/resource',
            generator: {
              filename: 'static/media/[name].[hash][ext]'
            }
          },
          {
            type: 'asset/resource',
            exclude: [/\.js$/, /\.html$/, /\.json$/],
            generator: {
              filename: 'static/media/[name].[hash][ext]'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: './index.html',
      inject: true,
      template: paths.appHtml,
      minify: {
        removeComments: false,
        collapseWhitespace: false,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      },
      templateParameters: {
        PUBLIC_URL: publicUrl
      }
    }),
    new webpack.DefinePlugin(env.stringified),
    new MiniCssExtractPlugin({
      filename: cssFilename
    }),
    new ESLintPlugin({
      extensions: ['js', 'jsx'],
      eslintPath: require.resolve('eslint'),
      formatter: require.resolve('react-dev-utils/eslintFormatter'),
    }),
    new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/ })
  ],
  externals: {
    'electron-edge-js': 'commonjs2 electron-edge-js',
  },
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000
  }
};

相关依赖版本:

  • webpack-cli: ^5.1.4
  • webpack: ^5.93.0
  • eslint-webpack-plugin: ^4.2.0

已尝试删除node_modules和package.lock后重新安装依赖,问题仍存在。


解决方案

错误根源是配置中对eslint-webpack-plugin的错误使用:

  1. 移除resolve.plugins中的ESLint插件
    resolve.plugins是用于配置模块解析规则的插件集合,不应该放置ESLint这类编译流程插件,直接删掉new ESLintWebpackPlugin({ extensions: ['js', 'jsx'] })这一行。

  2. 删除错误的ESLint Loader配置
    在module.rules里你把eslint-webpack-plugin当成loader来使用了,这完全错误。Webpack 5配合eslint-webpack-plugin不需要单独的loader,直接删除整个enforce: 'pre'的rule块。

  3. 统一ESLint插件的实例化
    你同时引入了ESLintPlugin和ESLintWebpackPlugin,两者是同一个包的不同导出名,保留其中一个即可。建议统一使用ESLintWebpackPlugin,并确保只在plugins数组中实例化一次,删除重复的插件实例。


修正后的关键配置片段

// 顶部引入统一为:
const ESLintWebpackPlugin = require('eslint-webpack-plugin');

// resolve.plugins修正后:
resolve: {
  // ...其他配置
  plugins: [
    new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
    // 删掉ESLintWebpackPlugin
  ]
},

// module.rules修正后:
module: {
  strictExportPresence: true,
  rules: [
    // 删掉那个enforce: 'pre'的ESLint loader rule
    {
      oneOf: [
        // ...原有其他rules
      ]
    }
  ]
},

// plugins修正后:
plugins: [
  // ...其他插件
  new ESLintWebpackPlugin({
    extensions: ['js', 'jsx'],
    eslintPath: require.resolve('eslint'),
    formatter: require.resolve('react-dev-utils/eslintFormatter'),
  }),
  // ...其他插件
]

完成以上修改后重新执行编译,问题即可解决。

内容的提问来源于stack exchange,提问作者scorona85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:00:54