☰
UnoCSS transformerAttributifyJsx 详解:在 JSX/TSX 中正确使用 valueless Attributify 语法
2026/10/10 5:49:58 网站建设 项目流程
  • AI 技能
  • 人工智能

【免费下载链接】skills

Anthony Fu's curated collection of agent skills.

项目地址:https://gitcode.com/gh_mirrors/skills11/skills
点击查看免费下载

UnoCSS 的 Attributify 模式允许把工具类拆散成独立的 HTML 属性,但在 React、Preact、Solid 等 JSX 框架中,无值属性(valueless attributify)会被 JSX 编译器改写成={true}形式,从而彻底破坏 UnoCSS 的类名提取。本文围绕transformerAttributifyJsx这一专用 transformer,讲清它解决的问题、工作原理、配置选项(blocklist)、各 JSX 框架下的 Vite 插件接入方式,以及配套的 TypeScript 类型声明,帮助你在 JSX 项目中稳定启用无值 Attributify 写法。

问题背景:JSX 会把无值属性变成={true}

UnoCSS 的 Attributify 预设支持“无值属性”写法(valueless attributify),即把工具类直接作为不取值的属性写在标签上(参见 preset-attributify 参考):

// 你写的是 <div m-2 rounded text-teal-400 />

但 JSX 编译器会把没有取值的布尔属性统一改写为显式的true:

// JSX 编译后变成 <div m-2={true} rounded={true} text-teal-400={true} />

正是这个={true}导致 UnoCSS 的 Attributify 检测失效——提取器期望的是m-2=""这类空字符串值,而={true}既不是空值、也不符合 Attributify 的取值约定,属性名因此无法被正确识别为工具类。

需要注意的作用边界:UnoCSS 的提取发生在构建时,且默认从 Vite/Webpack 管线中提取.jsx、.tsx、.vue、.md、.html、.svelte、.astro、.marko文件(.js、.ts默认不在提取范围内,详见 core-extracting 参考)。也就是说,JSX/TSX 源文件本来就在扫描对象中,问题只出在“无值属性”这一种写法上。

工作原理:把布尔属性还原回空字符串

transformerAttributifyJsx的作用是把 JSX 编译产生的布尔属性重新转换回空字符串形式,让 UnoCSS 的 Attributify 检测恢复正常:

// 输入(JSX 编译后的形态) <div m-2={true} rounded={true} /> // 输出(transformer 转换后) <div m-2="" rounded="" />

转换之后,UnoCSS 就能正常地从这些属性中提取出 Attributify 工具类并生成对应 CSS。从配置角度看,它与transformerDirectives、transformerVariantGroup、transformerCompileClass一样,统一挂在UnoCSS配置的transformers数组中(transformers选项的完整说明见 core-config 参考)。

安装与基本配置

在 UnoCSS 配置中同时启用presetAttributify和transformerAttributifyJsx:

import { defineConfig, presetAttributify, transformerAttributifyJsx } from 'unocss' export default defineConfig({ presets: [ presetAttributify(), ], transformers: [ transformerAttributifyJsx(), ], })

UnoCSS 会自动在项目根目录查找uno.config.{js,ts,mjs,mts}或unocss.config.{js,ts,mjs,mts},无需额外指定配置文件路径。

配置选项:blocklist

transformerAttributifyJsx支持通过blocklist排除不希望被转换的属性名:

transformerAttributifyJsx({ // 排除特定属性,不对其进行转换 // 默认:转换所有符合 attributify 模式的属性 blocklist: ['text', 'font'], })

默认的转换范围是所有符合 attributify 模式的属性;当某些属性名与 JSX 框架自身的语义冲突、或者你希望保持原样时,把它们加入blocklist即可让 transformer 跳过这些属性。

什么时候必须使用

当你在下列环境中使用无值 attributify 语法时,必须启用该 transformer:

  • React
  • Preact
  • Solid
  • 任何基于 JSX 的框架

两种写法的区别在于属性是否带值:

// 这种写法需要 transformer 才能生效 <div flex items-center gap-4 /> // 这种写法带值("~" 表示“前缀自身”,如 flex 即 flex),无需 transformer <div flex="~" items="center" gap="4" />

即:带值写法(flex="~"、items="center")本身不经过布尔属性改写,可以正常工作;只有<div flex />这类无值写法才依赖transformerAttributifyJsx做还原。如果项目中统一采用带值写法,也可以不启用该 transformer。

各 JSX 框架下的 Vite 接入

UnoCSS 与 Vite 的集成参考见 integrations-vite 文档,以下是针对 JSX 框架的关键点。

React

UnoCSS()插件必须放在 React 插件之前,这样 UnoCSS 才能在 JSX 转换之前处理源码:

// vite.config.ts import React from '@vitejs/plugin-react' import UnoCSS from 'unocss/vite' export default { plugins: [ UnoCSS(), // 必须位于 React 之前 React(), ], }

配套的uno.config.ts:

// uno.config.ts import { defineConfig, presetAttributify, presetWind3, transformerAttributifyJsx } from 'unocss' export default defineConfig({ presets: [ presetWind3(), presetAttributify(), ], transformers: [ transformerAttributifyJsx(), ], })

此外,Vite 集成文档中还有一条与 attributify 相关的构建提示:使用@unocss/preset-attributify时,应从 build script 中移除tsc步骤,以避免类型检查因自定义属性报错。

Preact

与 React 相同的插件顺序,使用@preact/preset-vite或@prefresh/vite即可:

// vite.config.ts import Preact from '@preact/preset-vite' import UnoCSS from 'unocss/vite' export default { plugins: [ UnoCSS(), Preact(), ], }

Solid

// vite.config.ts import UnoCSS from 'unocss/vite' import solidPlugin from 'vite-plugin-solid' export default { plugins: [ UnoCSS(), solidPlugin(), ], }

TypeScript 类型支持

在 JSX 中给 DOM 元素写任意自定义属性,TypeScript 默认会报错。UnoCSS 提供了类型声明方案:presetAttributify包导出了AttributifyAttributes类型,把它混入 React 的HTMLAttributes后,所有 Attributify 属性都能通过类型检查:

// shims.d.ts import type { AttributifyAttributes } from '@unocss/preset-attributify' declare module 'react' { interface HTMLAttributes<T> extends AttributifyAttributes {} }

Vue 3 项目的对应写法(混入@vue/runtime-dom/@vue/runtime-core)见 preset-attributify 参考的 TypeScript Support 章节。

配套要点:presetAttributify 的相关选项

启用 valueless 写法时,presetAttributify自身的两个选项与这个 transformer 直接相关(完整选项见 preset-attributify 参考):

presetAttributify({ strict: false, // 仅为 attributify 生成 CSS prefix: 'un-', // 属性前缀 prefixedOnly: false, // 要求所有属性都带前缀 nonValuedAttribute: true, // 支持无值属性(valueless 写法的关键) ignoreAttributes: [], // 忽略的属性 trueToNonValued: false, // 把 value="true" 也视为无值 })
  • nonValuedAttribute: true:声明预设支持<div m-2 rounded />这类无值属性,是 valueless 写法生效的前提。
  • trueToNonValued: false:默认不把value="true"当作无值处理。注意它面向的是字符串"true"取值,而 JSX 产生的={true}是布尔表达式、且发生在源码提取之前的编译阶段,因此不能靠这个选项替代transformerAttributifyJsx——这正是需要 transformer 的根本原因。

另外,当属性名与 HTML 原生属性冲突时,可按 preset 文档的约定使用un-前缀(如<a un-text="red">)规避。

在 skills 仓库中继续深入

本文基于 skills/unocss/references/transformer-attributify-jsx.md 展开,该文档由 UnoCSS 官方文档生成(生成信息见 skills/unocss/GENERATION.md,对应上游源码提交f05ee3a9ed0e1d4490aa7f04fc7aef4bd0babb15,Skill 基于 UnoCSS v66.10.5)。建议结合以下同目录参考一起阅读:

  • preset-attributify:Attributify 预设的完整用法、前缀自引用(~)、冲突属性处理与 TypeScript 声明;
  • integrations-vite:Vite 插件各模式、各框架插件顺序与 attributify 相关注意事项;
  • core-extracting:提取机制、默认文件类型与魔法注释(@unocss-include等);
  • core-config:transformers等完整配置项;
  • UnoCSS Skill 总览 skills/unocss/SKILL.md:所有 preset 与 transformer 的索引表。

小结

  • transformerAttributifyJsx专门解决 JSX 编译把无值属性改写为={true}、导致 Attributify 检测失效的问题,原理是把布尔属性还原为空字符串(m-2={true}→m-2="");
  • 只需在uno.config.ts中把transformerAttributifyJsx()加入transformers,并与presetAttributify()配合即可;
  • blocklist选项可排除特定属性(如['text', 'font'])不被转换;
  • 在 Vite 中UnoCSS()插件必须位于 React/Preact/Solid 插件之前;
  • 用@unocss/preset-attributify导出的AttributifyAttributes混入 React 的HTMLAttributes,可获得完整类型支持;
  • 若团队统一采用带值写法(flex="~"),则无需启用该 transformer。
  • AI 技能
  • 人工智能

【免费下载链接】skills

Anthony Fu's curated collection of agent skills.

项目地址:https://gitcode.com/gh_mirrors/skills11/skills
点击查看免费下载

相关推荐

上一篇:Elementor MCP `manage-elements` 能力详解:基于元素 ID 的原子化批量编辑、移动与克隆
下一篇:英雄联盟终极工具箱:5分钟掌握League Akari的完整使用指南

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

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

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

立即咨询