☰
UnoCSS 官方 ESLint 插件完全指南:安装配置与四大规则深度解析
2026/10/10 21:52:19 网站建设 项目流程
  • 前端
  • 构建工具

【免费下载链接】unocss

The instant on-demand atomic CSS engine.

项目地址:https://gitcode.com/GitHub_Trending/un/unocss
点击查看免费下载

UnoCSS 为工程化质量保障提供了官方 ESLint 集成:@unocss/eslint-plugin(推荐通过@unocss/eslint-config引入)。本文以仓库内 docs/integrations/eslint.md 与 packages-integrations/eslint-plugin/README.md 为核心骨架,结合packages-integrations/eslint-plugin的源码与测试,完整讲解插件的安装、Flat Config /.eslintrc两种接入方式、order、order-attributify、blocklist、enforce-class-compile四条规则的语义与全部可选参数,并深入其底层工作原理。读完你可以在任何 Vue / React / Svelte 项目中落地 UnoCSS 的类名排序与禁用规则检查,并理解规则如何直接复用 UnoCSS 引擎的真实生成器做判断。

一、为什么需要 UnoCSS 的 ESLint 插件

UnoCSS 按需生成原子化 CSS,一个元素的样式由class属性中的一串工具类名决定。随着类名增多,两个工程问题随之而来:

  • 顺序不一致:同一个类名集合,在不同文件里书写顺序不同,生成的 CSS 规则顺序也不同(影响层叠结果),代码评审时也容易反复争论。
  • 禁用类名无法拦截:项目里想淘汰bg-red-500、border等工具类,或在多套设计系统之间禁用某类命名,纯靠人肉 review 难以覆盖全局。

官方 ESLint 插件把这些问题交给静态检查与自动修复解决。它的核心亮点在于:规则不是靠硬编码的正则匹配,而是真正加载你的uno.config.ts,调用 UnoCSS 引擎对类名进行解析、排序与拦截判断,因此结果与运行时构建完全一致。这一点从 worker.ts 中可以看到:它通过loadConfig读取配置并用createGenerator构造真实的 UnoCSS 生成器,规则侧再通过synckit的createSyncFn同步调用 worker(见 _.ts)。

二、安装

插件本体为@unocss/eslint-plugin,推荐直接安装封装好的@unocss/eslint-config(它内部依赖并导出了插件,见 eslint-config/src/index.ts 与 eslint-config/src/flat.ts):

pnpm add -D @unocss/eslint-config
yarn add -D @unocss/eslint-config
npm install -D @unocss/eslint-config
bun add -D @unocss/eslint-config

前提条件:规则运行需要读取 UnoCSS 配置文件。如果项目根目录没有uno.config.ts,worker 会抛出错误提示先创建配置文件(见 worker.ts 中的报错逻辑)。

三、两种 ESLint 配置风格的接入

3.1 Flat Config 风格(ESLint 9+ 默认)

在eslint.config.js中引入 flat 配置:

import unocss from '@unocss/eslint-config/flat' export default [ unocss, // other configs ]

@unocss/eslint-config/flat子路径导出的是插件预置的 flat 配置对象。从源码 configs/flat.ts 可以看到,它注册了unocss插件命名空间,并默认开启两条 warn 级规则:

const flatConfig = { plugins: { unocss: plugin }, rules: { 'unocss/order': 'warn', 'unocss/order-attributify': 'warn', }, }

3.2 传统.eslintrc风格

{ "extends": [ "@unocss" ] }

对应 legacy 推荐配置见 configs/recommended.ts,注册@unocss插件并同样只默认开启order与order-attributify两条 warn 规则。

两个配置对象通过 index.ts 统一挂在configs.recommended与configs.flat上,这也是unocss.configs.flat这种写法的来源。

四、规则总览

规则名前缀取决于配置风格:

  • Flat config:unocss/<rule-name>
  • Legacy.eslintrc:@unocss/<rule-name>

可用的规则(注册于 plugin.ts):

规则名作用默认开启
order强制class属性中工具类按特定顺序排列是(warn)
order-attributify强制 attributify 属性按特定顺序排列是(warn)
blocklist禁用配置blocklist中指定的类名否
enforce-class-compile强制类名使用:uno:编译前缀否

特别说明:order-attributify只排序 attributify属性本身,不会对属性值内部的工具类排序,例如un-before="text-center font-sans color-gray"中的内容不会被重排——这种值内部的排序仍由order负责。

五、order:类选择器排序规则

5.1 基本行为

order检查class/className属性(源码 constants.ts 中的CLASS_FIELDS = ['class', 'classname']),对字符串中的工具类调用 UnoCSS 引擎重新排序,乱序时报UnoCSS utilities are not ordered并自动修复(fixable: 'code')。

它覆盖的语法形式非常广(见 order.ts 与 order.test.ts):

  • JSX/TSX:className="mx1 m1 mr-1"、className={"..."}、模板字符串className={...}、String.raw、带插值的模板字符串(只重排纯文本片段)。
  • Vue 模板:class字面量与:class绑定中的字符串字面量。
  • Svelte:class="..."及其{test ? 'a' : 'b'}三元表达式。
  • 函数调用:clsx(...)、classnames(...)以及你通过选项指定的任意工具函数(支持字符串、模板字符串、条件表达式、逻辑表达式、对象键值、数组嵌套、cva/tv变体对象等)。
  • 变量声明:变量名匹配的字符串字面量、对象字面量(含嵌套、as const satisfies类型断言,见order-unoVariables-satisfies测试组)。

一个 Vue 模板示例:

<!-- 修改前 --> <div class="mx1 m1 mr-1"></div> <!-- 修改后(自动修复) --> <div class="m1 mx1 mr-1"></div>

Svelte 中的示例(见 order.test.ts):

<!-- 修改前 --> <div class="mr-1 ml-1"></div> <!-- 修改后 --> <div class="ml-1 mr-1"></div>

5.2 排序原理:复用引擎而非硬编码

order之所以"懂"UnoCSS 的排序规则,是因为它调用了共享的排序实现 sort-rules.ts。该实现的关键步骤:

  1. 先用parseVariantGroup展开变体组,再用splitVariantGroupBody切分每个工具类;
  2. 逐个调用uno.parseToken(i)让引擎真正解析工具类,解析不出的视为未知类名,保持原位不动(只排序已知类名);
  3. 用解析结果中的规则序号token[0][0]加上变体层数权重variantHandlers.length * 100_000计算排序键,同序号时按字典序比较;
  4. 排序后重新用collapseVariantGroup收起变体组,最后把未知类名拼回头部。

这也解释了为什么order要求项目存在uno.config.ts:排序顺序完全由你的 preset(如presetWind3)与自定义规则决定。

5.3order规则选项

order接收一个可选的 options 对象(schema 见 order.ts):

  • unoFunctions(string[]):标记哪些函数调用需要检查。这些是普通函数名而非模式,匹配时忽略大小写。默认['clsx', 'classnames']。
  • unoVariables(string[]):标记哪些变量声明需要检查。这些是带i标志的正则模式。默认['^cls', 'classNames?$'],例如会匹配变量名clsButton与buttonClassNames。

自定义示例:

export default [ unocss, { rules: { 'unocss/order': ['warn', { unoFunctions: ['clsx', 'classnames', 'cva', 'tv'], // 检查这些工具函数的入参 unoVariables: ['^cls', 'classNames?$', '^theme'], // 匹配 themeDashboard 等变量 }], }, }, ]

对应测试见 order.test.ts 中的order-unoFunctions(含cva({ variants: { size: { small: 'px-2 text-sm py-1' } } })这类变体对象的重排)与order-unoVariables两组用例。

六、order-attributify:attributify 属性排序规则

如果你启用了 preset-attributify,HTML 元素会写成这样:

<div text-center font-sans color-gray un-before="text-center font-sans color-gray" />

order-attributify专门对这些无值的 attributify 属性(如text-center、font-sans)按 UnoCSS 排序规则重排。从 order-attributify.ts 的源码可以看到:

  • 它只处理 Vue 模板的VStartTag,过滤出所有无值属性(排除style、class、classname、value等原生属性,见IGNORE_ATTRIBUTES);
  • 把这些属性名拼成字符串交给syncAction(..., 'sort', ...)排序;
  • 修复时用magic-string删除乱序属性并在第一个属性位置重写(源码 order-attributify.ts)。

再次强调:它不处理属性值内部,un-before="text-center font-sans color-gray"的值内部乱序要交给order检查。

七、blocklist:禁用指定工具类(可选规则)

7.1 规则语义

blocklist不是默认开启的规则。启用后,当代码中出现 UnoCSS 配置blocklist中列出的工具类时,会抛出警告或错误。它既检查class字面量(Vueclass/:class、JSXclassName、Svelteclass),也检查attributify 无值属性名(见 blocklist.ts 的VStartTag分支)。

报错消息格式为"{{name}}" is in blocklist{{reason}},即默认展示被禁的类名;配置了自定义消息时追加: 你的消息。

7.2 启用方式

import unocss from '@unocss/eslint-config/flat' export default [ unocss, { rules: { 'unocss/blocklist': 'error', // 或 'warn' }, }, ]
{ "extends": ["@unocss"], "rules": { "@unocss/blocklist": "error" } }

仓库自带的 fixtures 就是这么用的(fixtures/eslint.config.ts)。

7.3 自定义拦截消息

你可以为被禁规则定制消息,让提示更有指导性。消息可以是静态字符串或接收类名返回字符串的函数(函数形式可结合原始类名动态生成建议):

export default defineConfig({ blocklist: [ ['bg-red-500', { message: 'Use bg-red-600 instead' }], [/-auto$/, { message: s => `Use ${s.replace(/-auto$/, '-a')} instead` }], // 例如 "my-auto" 被禁用时提示:Use "my-a" instead ], })

注意这里同时用到了两种 blocklist 条目写法:'bg-red-500'字符串字面量,以及[匹配器, { message }]元组形式——元组中匹配器可以是正则、字符串或接收类名返回布尔值的函数,message的取值函数在 worker.ts 中按raw类名求值。测试 blocklist.test.ts 与规则目录下的 uno.config.ts 覆盖了静态消息、动态匹配、动态消息三类场景(例如h-auto被提示改为h-a)。

7.4 底层判定流程

blocklist的判定同样发生在 worker 中(worker.ts):先对类名字符串执行uno.applyExtractors提取工具类,再对每个提取结果依次做uno.getBlocked(raw)直接命中、config.preprocess预处理、matchVariants匹配变体后的间接命中三层检查,从而保证被禁类名即使带变体前缀(如hover:)也能被识别。

八、enforce-class-compile:强制类编译前缀(可选规则)

8.1 规则语义与修复能力

enforce-class-compile专为配合 compile class transformer 设计:当class属性或:class指令的内容不以:uno:开头时,报告prefix::uno:is missing,并且(默认)自动为所有 class 属性与指令补上:uno:前缀,把长串工具类编译为带哈希的短类名。

<!-- 修改前 --> <div class="mr-1"></div> <!-- 自动修复后 --> <div class=":uno: mr-1"></div>

它覆盖 Vue 中的多种绑定形态(见 enforce-class-compile.test.ts 与 enforce-class-compile.ts):

  • class="mr-1"静态属性;
  • :class="'mr-1'"字符串字面量;
  • :class="condition ? ':uno: mr-1' : ':uno: ml-1'"三元表达式(修复两侧);
  • :class="{'mr-1': condition}"对象字面量键名,以及{flex}简写属性(会展开为{':uno: flex': flex});
  • :class="mr-1"模板字符串。

8.2 规则选项

  • prefix(string):编译前缀,必须与transformerCompileClass的触发词一致,用于配合自定义前缀。默认:uno:。
  • enableFix(boolean):设为false时只报告不自动修复,适合渐进式迁移(先把存量代码标红,再逐步手动接入)。默认true。
import unocss from '@unocss/eslint-config/flat' export default [ unocss, { rules: { 'unocss/enforce-class-compile': ['warn', { prefix: ':uno:', enableFix: true, // 迁移期可设为 false,仅报告 }], }, }, ]

8.3 与 compile-class transformer 的配合前提

enforce-class-compile的prefix选项本质上对应transformerCompileClass的trigger参数——后者默认匹配:uno:(正则见 transformer-compile-class/src/index.ts),两者必须保持一致,否则 ESLint 补上的前缀在构建时不会被 transformer 识别。如果你自定义了 trigger(例如通过trigger正则或:uno-名称:命名编译类),请同步修改本规则的prefix。

兼容性注意:该规则目前只支持 Vue(源码中scriptVisitor对 JSX 与 Svelte 分支留了todo: add support | NEED HELP占位,见 enforce-class-compile.ts)。Svelte 场景建议改用svelte-scoped模式;若需要在 JSX 中使用,可向项目提交 PR 补全。

九、可选规则统一启用模板

以下两段模板供整体参考(来自官方文档),可按需把'warn'换成'error'或追加 options 数组:

import unocss from '@unocss/eslint-config/flat' export default [ unocss, { rules: { 'unocss/blocklist': 'warn', // 或 "error" 'unocss/enforce-class-compile': ['warn', { /* options */ }], }, }, ]
{ "extends": ["@unocss"], "rules": { "@unocss/blocklist": "warn", "@unocss/enforce-class-compile": ["warn", { "prefix": ":uno:" }] } }

十、底层工作原理:worker 线程 + 真实引擎

规则与 UnoCSS 引擎之间隔着一层精心设计的桥接,理解它有助于排查"规则和构建结果不一致"之类的问题:

  1. 规则侧(同步):_.ts 用synckit的createSyncFn(join(distDir, 'worker.mjs'))把sort/blocklist动作同步派发到 worker(dist/worker.mjs由 worker.ts 通过runAsWorker注册)。
  2. Worker 侧(异步):worker.ts 用loadConfig加载 UnoCSS 配置,createGenerator({ ...config, warn: false })构造生成器,并按缓存键(显式configPath、文件所在目录、process.cwd())缓存生成器实例。
  3. 多仓库(monorepo)支持:未显式指定configPath时,worker 从被检查文件所在目录向上查找配置文件(getSearchCwd,见 worker.ts),因此每个子包可以使用自己的uno.config.ts。
  4. 处理器虚拟路径:markdown / MDX 等经 ESLint processor 生成的虚拟文件路径(形如/path/to/source.ext/virtual_file.ext)会被剥离出真实目录再定位配置。

如果你需要强制规则使用某个特定配置文件(比如项目根与 lint 入口不一致时),可以在 ESLint 配置的settings中指定:

export default [ unocss, { settings: { unocss: { configPath: './uno.config.ts', // 显式指定配置文件 }, }, }, ]

这个settings.unocss.configPath的类型声明定义在 types.ts,测试文件中也普遍使用它指向各自的uno.config.ts(如 order.test.ts)。

十一、运行与验证

在 fixtures 目录验证插件效果:

cd packages-integrations/eslint-plugin/fixtures && eslint ./src

fixtures 仓库提供了现成的验证素材:fixtures/src/App.vue、fixtures/src/app.tsx、fixtures/src/+page.svelte,配合 fixtures/eslint.config.ts(开启了unocss/blocklist: 'error')与 fixtures/uno.config.ts(配置了presetWind3、variant-group transformer 与 blocklist 匹配器)即可跑通完整链路。

也可以直接运行规则测试确认行为符合预期(测试均基于eslint-vitest-rule-tester,与真实 ESLint 运行时行为一致):

  • order.test.ts:覆盖 Vue / JSX / Svelte 三端与unoFunctions/unoVariables两个选项;
  • blocklist.test.ts:覆盖静态 / 动态 blocklist 与自定义消息;
  • enforce-class-compile.test.ts:覆盖前缀补全、自定义 prefix、enableFix: false只报不改等场景。

十二、最佳实践小结

  • 最小起步:安装@unocss/eslint-config,Flat 或.eslintrc二选一接入,即可获得order与order-attributify的 warn 级排序检查;确保项目根有uno.config.ts。
  • 渐进开启可选规则:先以warn启用blocklist与enforce-class-compile,配合enableFix: false完成存量迁移后再升级为error并开启自动修复。
  • 统一工具函数名单:如果项目使用cva、tv、superclass等组合类名工具,记得把它们加入order的unoFunctions,否则这些函数体内的类名不会被检查。
  • prefix 保持一致:使用 compile-class 工作流时,enforce-class-compile的prefix必须与transformerCompileClass的 trigger 完全一致。

结语

@unocss/eslint-plugin的价值在于把"类名排序、禁用拦截、编译前缀强制"这些与 UnoCSS 引擎强耦合的检查,做成了标准化的 ESLint 规则,并且直接复用真实的 UnoCSS 生成器,杜绝了 lint 结果与构建结果"两张皮"的问题。结合order/order-attributify的自动修复能力,它能让团队在原子化 CSS 的写法上保持高度一致,是 UnoCSS 生产级工程化中值得优先接入的一环。

  • 前端
  • 构建工具

【免费下载链接】unocss

The instant on-demand atomic CSS engine.

项目地址:https://gitcode.com/GitHub_Trending/un/unocss
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询