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

NextJS自定义Webpack配置时Asset Modules Plugin报错求助

问题

我在使用Next.js,在next.config.js中配置了自定义Webpack规则,配置代码如下:

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.

此前功能正常,添加上述CSS处理规则后出现问题。我尝试过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无法加载。我的文件夹结构为pages/和public/(包含fonts、gif、png、svg子目录),组件中通过import arrow from '../../public/svg/select-arrow.svg'方式引用资源。

解决方法

问题核心在于:

  1. Next.js默认已配置Asset Modules,新增的CSS规则与默认规则冲突,导致Webpack解析时出现filename属性不匹配的错误。
  2. 直接覆盖config.optimization会破坏Next.js默认优化配置,引发资源加载异常。

修改后的完整next.config.js

const { i18n } = require('./next-i18next.config')
const TerserPlugin = require("terser-webpack-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
          })
        );
      }

      // 修复默认Asset Generator的冲突问题,避免filename属性报错
      if (config.module.generator?.asset) {
        // 将默认的asset配置迁移到asset/resource,避免与inline类型冲突
        if (!config.module.generator['asset/resource']) {
          config.module.generator['asset/resource'] = { ...config.module.generator.asset };
        }
        // 删除全局的asset配置,只保留各类型单独配置
        delete config.module.generator.asset;
      }

      // 追加资源规则,不覆盖Next.js默认配置
      config.module.rules.push(
        { 
          test: /\.(woff|ttf|otf|eot|woff2)$/i, 
          type: "asset/resource", 
          generator: {
            outputPath: 'fonts/',
            publicPath: '/fonts/'
          } 
        },
        { 
          test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/i, 
          type: "asset/resource", 
          generator: {
            outputPath: 'images/',
            publicPath: '/images/'
          }
        }
      );

      // 扩展优化配置,而非完全覆盖
      config.optimization.minimizer.push(
        new TerserPlugin(),
        new CssMinimizerPlugin()
      );
      // 在现有splitChunks配置基础上调整参数
      Object.assign(config.optimization.splitChunks, {
        minSize: 20000,
        maxAsyncRequests: 30,
        maxInitialRequests: 30,
        enforceSizeThreshold: 50000
      });
    } 

    return config;
  },
  ...nextConfig
}

关键调整说明

  • 移除手动添加的MiniCssExtractPlugin,依赖Next.js生产环境默认的CSS提取逻辑,避免重复配置冲突。
  • 修复Asset Generator配置:将全局asset的filename属性迁移到asset/resource下,解决Schema不匹配报错。
  • 优化资源输出路径:将字体、图片分别归类到fonts/和images/目录,同时设置正确的publicPath确保资源可访问。
  • 扩展而非覆盖optimization.minimizer,保留Next.js默认优化插件,避免资源加载异常。
  • 使用Object.assign修改splitChunks参数,在默认配置基础上调整,不破坏原有逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:05:57