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

Vite配置:根据目录名设置assetFileNames命名规则

解决Vite打包时页面目录下index.css重命名为目录名的问题

项目结构如下,每个页面目录下的style.css被index.jsx引入后,Vite打包会将所有这类CSS输出为index.<hash>.css,调试时难以区分:

src/
--pages/
----Home/
------index.jsx
------style.css
----NotFound/
------index.jsx
------style.css

assetFileNames的assetInfo参数仅包含name、source和type,无法直接获取原始文件路径,不像chunkFileNames可以通过facadeModuleId拿到源目录来重命名chunk。

方法:通过Rollup的generateBundle钩子关联Chunk与Asset

利用Rollup的generateBundle钩子,遍历打包产物中的Chunk和Asset,通过Chunk的facadeModuleId找到对应页面的目录名,再匹配关联的CSS Asset进行重命名。

完整配置代码

import { defineConfig } from 'vite';
import path from 'path';

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        assetFileNames: 'assets/[name]-[hash][extname]',
        chunkFileNames: (chunkInfo) => {
          const name = chunkInfo.name === 'index'
            ? path.basename(path.dirname(chunkInfo.facadeModuleId))
            : chunkInfo.name;
          return `${name}-[hash].js`;
        },
      },
      plugins: [
        {
          name: 'rename-index-css',
          generateBundle(_options, bundle) {
            // 遍历所有Chunk,每个Chunk对应一个页面的入口文件
            Object.values(bundle).forEach(chunk => {
              if (chunk.type === 'chunk' && chunk.facadeModuleId) {
                const pageDir = path.basename(path.dirname(chunk.facadeModuleId));
                // 遍历所有Asset,寻找当前Chunk关联的index.css
                Object.values(bundle).forEach(asset => {
                  if (asset.type === 'asset' && asset.name === 'index.css') {
                    // 验证该CSS文件是否属于当前页面目录
                    if (chunk.modules) {
                      const matchedCss = Object.keys(chunk.modules).find(modulePath => 
                        modulePath.endsWith('style.css') && path.dirname(modulePath) === path.dirname(chunk.facadeModuleId)
                      );
                      if (matchedCss) {
                        // 将文件名中的index替换为页面目录名
                        asset.fileName = asset.fileName.replace('index-', `${pageDir}-`);
                      }
                    }
                  }
                });
              }
            });
          }
        }
      ]
    }
  }
});

工作原理

  1. Chunk遍历:每个页面的index.jsx会被打包成一个Chunk,通过chunk.facadeModuleId可以获取该入口文件的绝对路径,进而提取出页面目录名(如Home、NotFound)。
  2. Asset匹配:遍历所有打包生成的Asset,找到名为index.css的文件,通过Chunk的modules属性验证该CSS是否属于当前页面目录。
  3. 重命名Asset:确认匹配后,将CSS文件名中的index-替换为页面目录名,最终输出如Home-<hash>.css、NotFound-<hash>.css的文件。

替代方案(手动指定名称,不推荐)

如果不想用钩子,也可以在引入CSS时通过查询参数指定名称:

// Home/index.jsx
import './style.css?name=Home';

// NotFound/index.jsx
import './style.css?name=NotFound';

然后在assetFileNames中解析查询参数:

assetFileNames: (assetInfo) => {
  let name = assetInfo.name;
  // 解析查询参数中的name
  if (assetInfo.source?.includes('?name=')) {
    name = assetInfo.source.split('?name=')[1].split('&')[0];
  }
  return `assets/${name}-[hash][extname]`;
}

这种方法需要手动修改每个页面的引入代码,灵活性较差,适合小型项目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:47:20