NextJS webpack:已使用与API架构不匹配的生成器对象初始化资产模块插件

xu3bshqb  于 2023-10-18  发布在  Webpack
关注(0)|答案(1)|浏览(130)

我使用的是NextJS,在next.config中,我使用的是一些自定义的webpack。
我的next.config.js文件如下:

const { i18n } = require('./next-i18next.config')
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

const nextConfig = {
  reactStrictMode: false,
  distDir: 'dist',
  i18n,
  images: {
    domains: ['aws-link', 'my-site'],
  },
}

module.exports = {
  webpack: function(config, {isServer}) {
    if (config.mode === 'production' && config.name === 'client') {
      if (!isServer && process.env.ANALYZE === 'true') {
        const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
        config.plugins.push(
          new BundleAnalyzerPlugin({
            analyzerMode: 'static',
            reportFilename: './analyze/client.html',
            generateStatsFile: true
          })
        );
      }

      // 'filename' is specific to 'asset/resource' type only, but incompatible with 'asset/inline',
      // see https://webpack.js.org/guides/asset-modules/#custom-output-filename.
      // Here we rename generator['asset'] into generator['asset/resource'] to avoid conflicts with inline assets.
      // if (config.module.generator?.asset?.filename) {
      //   if (!config.module.generator['asset/resource']) {
      //     config.module.generator['asset/resource'] = config.module.generator.asset
      //   }
      //   delete config.module.generator.asset
      // }

      config.plugins.push(
        new MiniCssExtractPlugin()
      )

      config.module.rules.push({
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
        parser: { dataUrlCondition: { maxSize: 50000 } },
      })

      config.module.rules.push({ test: /\.(woff|ttf|otf|eot|woff2)$/i, type: "asset/resource", generator: {
        outputPath: 'public/',
        publicPath: 'public/'
      } });

      config.module.rules.push({ test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/i, type: "asset/resource", generator: {
        outputPath: 'public/', // this is the new option set
        publicPath: 'public/'
      }});

  //     config.module.rules.push({
  //       test: /\.(png|jpg|webp|gif|svg|mp4|webm|ico|mp3)$/,
  //       type: 'asset',
  //       parser: { dataUrlCondition: { maxSize: 150000 } },
  // })

      config.optimization = {
        minimize: true,
        minimizer: [new TerserPlugin(), new CssMinimizerPlugin()],
        splitChunks: {
          chunks: 'async',
          minSize: 20000,
          minChunks: 1,
          maxAsyncRequests: 30,
          maxInitialRequests: 30,
          enforceSizeThreshold: 50000,
          cacheGroups: {
            defaultVendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              reuseExistingChunk: true
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true
            }
          }
        }
      };

    } 

    return config;
  },
  ...nextConfig
}

// module.exports = {
  
//   ...nextConfig,
// }

但是,我得到了一个错误:
编译失败。

./node_modules/antd/dist/antd.css
Module not found: Invalid generator object. Asset Modules Plugin has been initialized using a generator object that does not match the API schema.
 - generator has an unknown property 'filename'. These properties are valid:
   object { dataUrl? }
   -> Generator options for asset/inline modules.

我试着从一个Github的答案中找到这个解决方案:

if (config.module.generator?.asset?.filename) {
        if (!config.module.generator['asset/resource']) {
          config.module.generator['asset/resource'] = config.module.generator.asset
        }
        delete config.module.generator.asset
      }

但是,这只是搞乱了我所有的进口和没有css加载。我真的很感激这里的一些帮助,因为我已经浪费了一整天寻找解决方案。
这是我的文件夹结构:
页数/
公众/

--fonts/

 --gif/

 --png/

 --svg/

这就是我如何在我的组件中使用这些图像:
import arrow from '../../public/svg/select-arrow.svg'
所有这些都工作得很好,直到我决定在我的next.config.js中添加这个:

config.module.rules.push({
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
        parser: { dataUrlCondition: { maxSize: 50000 } },
      })

附:我几乎尝试了所有的解决方案在这里,但他们不解决我的问题,所以请不要标记为重复。

kx7yvsdv

kx7yvsdv1#

此错误消息表示webpack配置中的generator对象存在问题:它包含未知属性filename。根据webpack文档,资产模块的generator只能识别dataUrl属性。
若要解决此错误,请更新asset/resource类型的generator配置以删除filename属性。此外,确保parserrules之外。
以下是更正后的配置:

config.module.rules.push({
  test: /\.(woff|ttf|otf|eot|woff2)$/i, 
  type: "asset/resource", 
  generator: {
    outputPath: 'public/',
    publicPath: 'public/'
  } 
});

config.module.rules.push({ 
  test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/i, 
  type: "asset/resource", 
  generator: {
    outputPath: 'public/', // this is the new option set
    publicPath: 'public/'
  }
});

对于CSS规则,请确保解析器不在规则配置中:

config.module.rules.push({
  test: /\.css$/i,
  use: [MiniCssExtractPlugin.loader, "css-loader"]
});

如果你想为资产应用dataUrlCondition,你可以这样做:

config.module.rules.push({ 
  test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/i, 
  type: "asset/resource", 
  parser: { dataUrlCondition: { maxSize: 50000 } },
  generator: {
    outputPath: 'public/', // this is the new option set
    publicPath: 'public/'
  }
});

完成这些更改后,请再次尝试运行Next.js应用程序,以查看错误是否已解决。

相关问题