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

Webpack v5资源模块如何保持原目录结构?assetModuleFilename配置问题

问题描述

我在用WordPress做项目,目录结构和常规不同,没有index.js,是基于其他开发者的配置修改的。当前项目目录结构如下:

├── src
│   └── themes
│       └── someThemeName
│           ├── images
│           │   └── header
│           │       └── header.jpg
│           └── fonts
├── public_html
│   └── wp-content
│      └── themes
│          └── someThemeName
│             ├── images
│             │   └── header
│             │       └── header.jpg
│             └── fonts
│  
├── package-lock.json
├── package.json
└── webpack.config.js

我需要配置assetModuleFilename来保持资源的原有目录结构,但修改后出现错误:

Error: Conflict: Multiple chunks emit assets to the same filename undefined (chunks 375 and 375)

我的webpack.config.js配置如下:

const fs = require('fs');
const {
  resolve
} = require('path');
const svgToMiniDataURI = require('mini-svg-data-uri');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

let entries = {};
const theme = process.env.npm_config_theme;
const paths = {
  ['themes/' + theme + '/style']: './src/themes/' + theme + '/scss/style.scss',
  ['themes/' + theme + '/js/additions']: './src/themes/' + theme + '/js/additions.js'
};

for (var key in paths) {
  if (fs.existsSync(paths[key])) {
    entries[key] = paths[key]
  }
}

module.exports = {
  entry: entries,
  output: {
    path: resolve('./public_html/wp-content/'),
    assetModuleFilename: (pathData) => {
      const filepath = path.dirname(pathData.filename).split('/').slice(1).join('/');
      return filepath + '/[name][ext]';
    }
  },
  resolve: {
    extensions: ['.js', '.scss'],
    modules: [
      resolve('src'),
      'node_modules',
    ],
    alias: {
      'themes': resolve('./src/themes')
    }
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css'
    })
  ],
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource"
      },
      {
        test: /\.svg/,
        type: 'asset/inline',
        generator: {
          dataUrl: content => {
            content = content.toString();
            return svgToMiniDataURI(content);
          }
        }
      },
      {
        test: /\.js$/,
        exclude: [/public_html/, /node_modules/],
        use: ['babel-loader']
      },
      {
        test: /\.scss$/,
        exclude: /public_html/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
      }
    ]
  }
};
解决方案

1. 修复path模块未引入的问题

当前配置里使用了path.dirname但没有引入path模块,这会导致filepath计算错误,进而出现undefined相关的冲突。在文件顶部添加:

const path = require('path');

2. 调整assetModuleFilename的路径计算逻辑

原路径计算逻辑无法正确提取资源的相对结构,改为基于src目录的相对路径构建输出路径,确保和原目录结构完全匹配:

assetModuleFilename: (pathData) => {
  // 获取资源相对于src目录的完整路径
  const relativePath = path.relative(resolve('./src'), pathData.filename);
  // 直接使用该路径作为输出路径,保持和src内一致的目录结构
  return relativePath;
}

修改后,src/themes/someThemeName/images/header/header.jpg会被输出到public_html/wp-content/themes/someThemeName/images/header/header.jpg,完全符合目标结构要求。

3. 补充chunk文件名配置(可选)

若仍存在chunk文件名冲突风险,可在output中添加chunkFilename配置,确保文件名唯一:

output: {
  path: resolve('./public_html/wp-content/'),
  assetModuleFilename: (pathData) => {
    const relativePath = path.relative(resolve('./src'), pathData.filename);
    return relativePath;
  },
  chunkFilename: '[id].[contenthash].js'
}

4. 验证配置

修改后运行webpack构建命令,检查public_html/wp-content/themes/someThemeName下的资源目录结构是否与src内一致,同时确认冲突错误不再出现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:55:24