文章 文章 posts

Vite + PurgeCSS 与 Vue 动态类名问题

在使用 vite-plugin-purgecss 时,Vue 项目中可能会出现以下 CSS 清理问题:

1. 问题表现

  1. 动态 class 不生效
vue
<div :class="isActive ? 'active' : 'inactive'"></div>

`

  • PurgeCSS 在静态分析时无法识别动态类名,会将 active 和 inactive 清理掉。
  1. 条件渲染组件的 class 不生效
vue
<MyComponent v-if="show" class="special"></MyComponent>
  • v-if 渲染的内容在静态分析阶段可能不可见,导致类名被清理。
  1. client-only 内部组件的 class 不生效
vue
<client-only>
  <MyComponent class="special"></MyComponent>
</client-only>
  • 在 SSR 项目中,client-only 内容仅在客户端渲染,PurgesCSS 在构建时看不到这些类名。

2. 原因

  • vite-plugin-purgecss 会扫描项目文件,删除未使用的 CSS 类。
  • 动态生成的类名、条件渲染组件以及客户端渲染内容在构建时不可见,因此被错误清理。

3. 解决方案

3.1 使用 Safelist(白名单)

在 vite.config.js 中配置 purgeCss.safelist,保留特定 class:

js
import purgeCss from 'vite-plugin-purgecss'

export default {
  plugins: [
    purgeCss({
      safelist: [
        'active',
        'inactive',
        /^special/, // 匹配所有以 special 开头的 class
      ],
    }),
  ],
}

3.2 避免动态拼接类名

将可能的 class 静态化:

vue
<div :class="computedClass"></div>
<script setup>
const computedClass = 'active' // 避免动态拼接
</script>

3.3 忽略特定文件

通过 exclude 配置忽略动态组件:

js
purgeCss({
  content: ['./index.html', './src/**/*.{vue,js,ts}'],
  exclude: ['**/MyDynamicComponent.vue']
})

3.4 client-only 结合 safelist

对于 client-only 内部组件,确保 class 在 safelist 中:

vue
<client-only>
  <MyComponent class="special"></MyComponent>
</client-only>
  • 白名单中加入 special 或正则 /^special-/。

4. 总结

  • PurgeCSS 静态分析能力有限,动态或条件生成的类容易被误删。
  • 核心解决方案:使用 safelist 保留动态类名、条件渲染组件以及客户端渲染内容的 CSS。
  • 避免大量动态拼接类名,并根据项目需求配置 exclude 或正则白名单。

相关文章:Nuxt + VitePurging CSS 配置示例