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
相关产品推荐
相关产品推荐

