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.4webpack: ^5.93.0eslint-webpack-plugin: ^4.2.0
已尝试删除node_modules和package.lock后重新安装依赖,问题仍存在。
解决方案
错误根源是配置中对eslint-webpack-plugin的错误使用:
移除
resolve.plugins中的ESLint插件resolve.plugins是用于配置模块解析规则的插件集合,不应该放置ESLint这类编译流程插件,直接删掉new ESLintWebpackPlugin({ extensions: ['js', 'jsx'] })这一行。删除错误的ESLint Loader配置
在module.rules里你把eslint-webpack-plugin当成loader来使用了,这完全错误。Webpack 5配合eslint-webpack-plugin不需要单独的loader,直接删除整个enforce: 'pre'的rule块。统一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
相关产品推荐
相关产品推荐

