无效的配置对象:Webpack 已使用与 API 模式不匹配的配置对象进行了初始化

Invalid configuration object: Webpack has been initialized using a configuration object that does not match the API schema

我继承了一个旧存储库,我正在尝试更新 Node 以及一些依赖项。回购协议使用 webpack 3.6,我将其升级到 webpack 5.70.0。

当 运行 npm run build 时出现以下错误:

> node scripts/build.js

Creating an optimized production build...
Failed to compile.

Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration.module.rules[1] should be one of these:
   ["..." | object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use? }, ...]
   -> A rule.
   Details:
    * configuration.module.rules[1].oneOf[2].loader should be a non-empty string.
      -> A loader request.

这是我的webpack.config

const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require("copy-webpack-plugin");
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

const resolveApp = relativePath => path.resolve(__dirname, relativePath);

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

const paths = {
  appEntry: resolveApp('web/static'),
  appAssets: resolveApp('web/static/assets'),
  appOutput: resolveApp('priv/static')
}

module.exports = {
  bail: true,
  devtool: 'source-map',
  entry: {
    index: [paths.appEntry + '/js/index.js', paths.appEntry + '/css/globals.scss'],
    ads: paths.appEntry + '/js/ads.js'
  },
  output: {
    path: paths.appOutput,
    filename: 'js/[name].js',
    pathinfo: true,
    // Point sourcemap entries to original disk location (format as URL on Windows)
    devtoolModuleFilenameTemplate: info =>
      path.resolve(info.absoluteResourcePath).replace(/\/g, '/'),
  },
  resolve: {
    modules: [ "node_modules", __dirname + "/web/static/js" ],
    extensions: ['.web.js', '.js', '.json', '.web.jsx', '.jsx', '.scss'],
  },
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        // compress: {
        //   warnings: false,
        //   // Disabled because of an issue with Uglify breaking seemingly valid code:
        //   // https://github.com/facebookincubator/create-react-app/issues/2376
        //   // Pending further investigation:
        //   // https://github.com/mishoo/UglifyJS2/issues/2011
        //   comparisons: false,
        // },
        // output: {
        //   comments: false,
        //   // Turned on because emoji and regex is not minified properly using default
        //   // https://github.com/facebookincubator/create-react-app/issues/2488
        //   ascii_only: true,
        // },
        sourceMap: true,
      }),
    ]
  },
  module: {
    strictExportPresence: true,
    rules: [
      // First, run the linter.
      // It's important to do this before Babel processes the JS.
      {
        test: /\.(js|jsx)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              eslintPath: require.resolve('eslint'),

            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        include: paths.appEntry,
      },
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works like "file" loader except that it embeds assets
          // smaller than specified limit in bytes as data URLs to avoid requests.
          // A missing `test` is equivalent to a match.
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: '/images/[name].[hash:8].[ext]',
            },
          },
          // Process JS with Babel.
          {
            test: /\.(js|jsx)$/,
            include: paths.appEntry,
            loader: require.resolve('babel-loader'),
            options: {
              compact: true
            },
          },
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader turns CSS into JS modules that inject <style> tags.
          // In production, we use a plugin to extract that CSS to a file, but
          // in development "style" loader enables hot editing of CSS.
          {
            test: /\.s?css$/,
            loader: ExtractTextPlugin.extract(
              Object.assign(
                {
                  fallback: require.resolve('style-loader'),
                  use: [
                    {
                      loader: require.resolve('css-loader'),
                      options: {
                        modules: true,
                        importLoaders: 1,
                        minimize: true,
                        localIdentName: '[name]__[local]___[hash:base64:5]'
                      }
                    },
                    {
                      loader: require.resolve('postcss-loader'),
                      options: {
                        // Necessary for external CSS imports to work
                        // https://github.com/facebookincubator/create-react-app/issues/2677
                        ident: 'postcss',
                        plugins: () => [
                          require('postcss-flexbugs-fixes'),
                          autoprefixer({
                            browsers: [
                              '> 1%',
                              'last 8 versions',
                              'Firefox ESR',
                              'not ie < 9', // React doesn't support IE8 anyway
                            ],
                            flexbox: 'no-2009',
                          }),
                        ],
                      },
                    },
                    require.resolve('sass-loader')
                  ],
                },
                { publicPath: Array(cssFilename.split('/').length).join('../') }
              )
            ),
          },
          // "file" loader makes sure those assets get served by WebpackDevServer.
          // When you `import` an asset, you get its (virtual) filename.
          // In production, they would get copied to the `build` folder.
          // This loader doesn't use a "test" so it will catch all modules
          // that fall through the other loaders.
          {
            // Exclude `js` files to keep "css" loader working as it injects
            // it's runtime that would otherwise processed through "file" loader.
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
            exclude: [/\.js$/, /\.html$/, /\.json$/],
            loader: require.resolve('file-loader'),
            options: {
              name: '/images/[name].[hash:8].[ext]',
            },
          },
        ],
      },
      // ** STOP ** Are you adding a new loader?
      // Make sure to add the new loader(s) before the "file" loader.
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    }),
    // Minify the code.
    // new webpack.optimize.UglifyJsPlugin({
    //   compress: {
    //     warnings: false,
    //     // Disabled because of an issue with Uglify breaking seemingly valid code:
    //     // https://github.com/facebookincubator/create-react-app/issues/2376
    //     // Pending further investigation:
    //     // https://github.com/mishoo/UglifyJS2/issues/2011
    //     comparisons: false,
    //   },
    //   output: {
    //     comments: false,
    //     // Turned on because emoji and regex is not minified properly using default
    //     // https://github.com/facebookincubator/create-react-app/issues/2488
    //     ascii_only: true,
    //   },
    //   sourceMap: true,
    // }),
    // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
    new ExtractTextPlugin({
      filename: cssFilename,
    }),
    new CopyWebpackPlugin({patterns:[{ from: paths.appAssets }]}),
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/
    })
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  // node: {
  //   dgram: 'empty',
  //   fs: 'empty',
  //   net: 'empty',
  //   tls: 'empty',
  //   child_process: 'empty',
  // },
}

错误是指这条规则,但我不确定这里的问题是什么。

          {
            test: /\.s?css$/,
            loader: ExtractTextPlugin.extract(
              Object.assign(
                {
                  fallback: require.resolve('style-loader'),
                  use: [
                    {
                      loader: require.resolve('css-loader'),
                      options: {
                        modules: true,
                        importLoaders: 1,
                        minimize: true,
                        localIdentName: '[name]__[local]___[hash:base64:5]'
                      }
                    },
                    {
                      loader: require.resolve('postcss-loader'),
                      options: {
                        // Necessary for external CSS imports to work
                        // https://github.com/facebookincubator/create-react-app/issues/2677
                        ident: 'postcss',
                        plugins: () => [
                          require('postcss-flexbugs-fixes'),
                          autoprefixer({
                            browsers: [
                              '> 1%',
                              'last 8 versions',
                              'Firefox ESR',
                              'not ie < 9', // React doesn't support IE8 anyway
                            ],
                            flexbox: 'no-2009',
                          }),
                        ],
                      },
                    },
                    require.resolve('sass-loader')
                  ],
                },
                { publicPath: Array(cssFilename.split('/').length).join('../') }
              )
            ),
          }

非常感谢任何帮助!

错误表明“loader”的值应该是 non-empty 字符串。因此,如果您查看“loader”的值,您会看到:

loader: ExtractTextPlugin.extract(

我敢打赌,上面的内容 return 不是字符串。当查看 docs for the ExtractTextPlugin 时,它说要像这样使用它:

use: ExtractTextPlugin.extract(