Vite构建:不同目录下同名SCSS文件打包后被覆盖问题咨询
问题描述
我有两组文件名相同但存放目录不同的SCSS文件,目录结构如下:
// inside resources scss --> 存放LTR文件 | |- a.scss |- b.scss |- c.scss scss-rtl --> 存放RTL文件 | |- a.scss |- b.scss |- c.scss
执行 npm run build 构建后,生成的文件会互相覆盖,输出目录如下:
// inside public/build assets --> RTL文件覆盖了LTR文件 | |- a.[hash].css |- b.[hash].css |- c.[hash].css
同时收到提示:
The emitted file "assets/a.c4aecca9.css" overwrites a previously emitted file of the same name.
我原本以为即便文件名相同,只要文件路径不同,Vite会默认生成不同的哈希值,但实际并非如此。
解决方案
方案1:修改哈希计算规则,纳入文件路径
Vite默认哈希生成逻辑可能未包含文件的完整路径,导致同名文件哈希重复。可以通过配置Rollup的输出规则,让哈希计算包含文件的相对路径:
在 vite.config.js 中添加如下配置:
export default defineConfig({ build: { rollupOptions: { output: { assetFileNames: (assetInfo) => { // 将文件路径中的斜杠替换为下划线,避免路径分隔符干扰 const pathIdentifier = assetInfo.name.replace(/\//g, '_'); return `assets/${pathIdentifier}.[hash][extname]`; } } } } });
构建后输出文件会变为 assets_scss_a.[hash].css 和 assets_scss-rtl_a.[hash].css,彻底避免覆盖。
方案2:拆分LTR/RTL文件到不同输出目录
直接将两组样式文件输出到 assets 下的不同子目录,比如 ltr 和 rtl:
修改 vite.config.js:
export default defineConfig({ build: { rollupOptions: { output: { assetFileNames: (assetInfo) => { const filePath = assetInfo.name; if (filePath.includes('scss/')) { return `assets/ltr/[name].[hash][extname]`; } else if (filePath.includes('scss-rtl/')) { return `assets/rtl/[name].[hash][extname]`; } // 其他资源保持默认命名规则 return `assets/[name].[hash][extname]`; } } } } });
方案3:通过查询参数区分同名文件
在入口文件引入样式时添加查询参数,让Vite将参数作为文件名的一部分生成哈希:
// 引入LTR样式 import './resources/scss/a.scss?ltr'; // 引入RTL样式 import './resources/scss-rtl/a.scss?rtl';
这样Vite会为两组文件生成不同的哈希值,不会出现覆盖问题。
内容的提问来源于stack exchange,提问作者Owaiz Yusufi
相关产品推荐
相关产品推荐

