首页
/ airi 与 UnoCSS:基于 @unocss/nuxt 的 Nuxt 集成接入与配置完全指南

airi 与 UnoCSS:基于 @unocss/nuxt 的 Nuxt 集成接入与配置完全指南

2026-09-08 11:38:09作者:房伟宁

本文以仓库内技能文档 integrations-nuxt.md 为核心骨架,讲解 UnoCSS 官方 Nuxt 模块 @unocss/nuxt 的安装、支持矩阵、uno.config.ts 配置、Nuxt Layers 配置合并、组件内使用方式与调试手段;同时以 airi 仓库中大量 Vite 应用的 UnoCSS 真实工程实践(根配置 uno.config.tsapps/stage-web/uno.config.ts)作为对照,帮助读者把"Vite 侧已经很成熟的 UnoCSS 玩法"平移、迁移到 Nuxt 项目。

导读

UnoCSS 是即时按需生成的原子化 CSS 引擎,其核心本身不预设任何工具类,所有工具类由 preset 提供;airi 仓库的前端应用(stage-webui-server-authstage-ui 等)全部基于 Vite 插件接入 UnoCSS。如果你的下一个前端工程选择了 Nuxt(或 Nuxt Bridge / Nuxt 2),UnoCSS 官方提供了 @unocss/nuxt 模块,让配置与使用体验与 Vite 侧几乎一致,还额外带来 uno.css 自动注入与 Nuxt Layers 配置合并两大能力。读完本文,你将掌握:在 Nuxt 工程中从零接入 UnoCSS 的完整步骤、uno.config.tsnuxt.config.ts 的职责划分、如何复用并合并多个 Layers 的 UnoCSS 配置,以及在 SFC 组件中使用工具类与 attributify 写法的正确姿势。

一、认识 @unocss/nuxt 与它在 UnoCSS 生态中的位置

UnoCSS 的集成方式按其承载工具分为若干官方入口。在 airi 仓库内,Vite 应用统一采用 unocss/vite 插件方式接入,例如 apps/stage-web/vite.config.tspackages/stage-ui/vite.config.tsapps/ui-server-auth/vite.config.ts 都以 import Unocss from 'unocss/vite' 引入插件,并在 main.ts 中显式导入 uno.css

// apps/stage-web/src/main.ts(节选)
import '@unocss/reset/tailwind.css'
import 'uno.css'

而针对 Nuxt,UnoCSS 提供的是 Nuxt module:@unocss/nuxt。它把上面两步"插件注册 + 入口 CSS 注入"全部封装进 Nuxt 的 modules 机制,无需手工在 main.tsvirtual:uno.css 导入。技能文档体系在 SKILL.md 的 Integrations 一节将其与 integrations-vite.md 并列,两者分别对应 Vite 与 Nuxt 两条主流接入路径,本文聚焦 Nuxt 一侧。

需要特别说明:Nuxt 模块底层仍然构建在 Vite/Webpack 的 UnoCSS 插件之上,因此你在 Vite 侧积累的所有知识——preset、shortcuts、transformers、content 抽取管线——在 Nuxt 工程中完全适用。

二、安装与最小接入

2.1 安装依赖

在 Nuxt 项目根目录执行:

pnpm add -D unocss @unocss/nuxt

airi 采用 pnpm workspace 的"catalog 化"依赖管理模式,各应用的 package.json 中依赖以 "catalog:" 引用(例如 apps/stage-web/package.json 中的 "@unocss/reset": "catalog:")。若你所在的 monorepo 同样维护了版本目录(catalog),也可以把 unocss@unocss/nuxt 收敛到同一份版本中,保证所有前端应用使用完全一致的 UnoCSS 版本。

2.2 注册模块

nuxt.config.ts 中把模块加入 modules 数组:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@unocss/nuxt',
  ],
})

注意这里不需要给模块传任何选项——UnoCSS 模块的设计哲学与仓库根 uno.config.ts 一致:一切规则、预设、主题都收敛到独立的 uno.config.ts 中,nuxt.config.ts 只负责"启用模块"。

2.3 创建 UnoCSS 配置文件

// uno.config.ts
import { defineConfig, presetWind3 } from 'unocss'

export default defineConfig({
  presets: [
    presetWind3(),
  ],
})

presetWind3() 是 Tailwind CSS v3 / Windi CSS 兼容预设,也是 airi 仓库所有应用的统一选择(见根 uno.config.ts 中的 sharedUnoConfig())。详细能力清单可参考技能文档 preset-wind3

关键差异:uno.css 由模块自动注入。 在 Vite 接入方式下,你必须手动在入口文件 import 'virtual:uno.css'(airi 各 Vite 应用正是如此,见 apps/ui-server-auth/src/main.ts);而 Nuxt 模块会在构建流程中自动注入 uno.css 入口,无需也无法再手动添加这条 import。这正是下面 「与 Vite 集成的关键差异」 中列出的第一条差异。

三、支持矩阵:看清你的 Nuxt 版本与构建工具组合

@unocss/nuxt 对不同 Nuxt 版本与底层构建工具的覆盖并不完全一致,官方支持状态如下:

构建工具 Nuxt 2 Nuxt Bridge Nuxt 3
Webpack Dev 🚧
Webpack Build
Vite Dev -
Vite Build -

从矩阵可以读出三条实用结论:

  1. Nuxt 3 的默认开发体验走 Vite Dev/Build 路线,这两条路径都是 ✅,因此在新项目(Nuxt 3)上无需担心;
  2. Nuxt 2 + Webpack 是唯一全量支持组合(Dev 与 Build 均为 ✅),老项目升级 UnoCSS 可行;
  3. Webpack Dev 在 Nuxt 3 下标记 🚧,即"尚未就绪/构建中",如果你的 Nuxt 3 项目被迫使用 Webpack(而非 Vite),开发态的热更新能力可能受限,生产 Build(✅)不受影响;
  4. Nuxt 2 与 Vite 的组合不存在(-),因为 Nuxt 2 的底层仅支持 Webpack 构建。

规划项目技术栈时,请优先把这一矩阵纳入选型依据。

四、配置方式详解

4.1 推荐:使用独立的 uno.config.ts

把配置放在独立文件中可以获得最佳 IDE 支持(语言服务能直接读取该文件提供补全与悬停提示),同时也让配置天然可被 Vitest、Storybook(histoire)、脚本等非 Nuxt 运行时复用。airi 仓库正是"单份共享配置 + 各应用 merge 覆盖"的范本:根 uno.config.ts 导出 sharedUnoConfig(),随后各应用在自身 uno.config.tsmergeConfigs 叠加差异。

一个覆盖主流需求的 uno.config.ts 示例:

// uno.config.ts
import { defineConfig, presetWind3, presetIcons } from 'unocss'

export default defineConfig({
  presets: [
    presetWind3(),
    presetIcons(),
  ],
  shortcuts: {
    'btn': 'py-2 px-4 font-semibold rounded-lg',
  },
})
  • presets:工具类来源。presetWind3() 提供类 Tailwind 的全部工具;presetIcons() 让纯 CSS 图标可用(结合 Iconify 图标集,详见 preset-icons)。
  • shortcuts:把一段工具类组合绑定为语义化类名。这里 btn 会被展开为 padding、font-weight、圆角四条规则。

airi 中 shortcut 的更贴近生产级的用法可见根 uno.config.ts 的自定义规则区(例如 mask-[...]bg-dotted-[...]drag-region),以及 apps/stage-web/uno.config.ts 中通过 mergeConfigs 追加 transition-colors-none 规则、叠加 presetWebFonts 的写法——这种"基座配置 + 应用级追加"的工程模式,与下文 Nuxt Layers 的合并机制同构。

4.2 Nuxt Layers 支持:自动合并来自 Layer 的 UnoCSS 配置

Nuxt Layers 允许把应用拆分为可复用的"层"。默认情况下 @unocss/nuxt 只读取当前项目根目录的配置;开启 nuxtLayers 后,模块会自动发现并合并各 Layer 暴露的 UnoCSS 配置。

首先在 nuxt.config.ts 中开启:

// nuxt.config.ts
export default defineNuxtConfig({
  unocss: {
    nuxtLayers: true,
  },
})

随后,根应用uno.config.ts 应从 Nuxt 生成的合并结果文件读取配置:

// uno.config.ts
import config from './.nuxt/uno.config.mjs'

export default config

这样,Nuxt 会把所有 Layer 的 UnoCSS 配置自动合并后写入 .nuxt/uno.config.mjs,根配置直接以它为最终结果。

如果你还想在合并结果之上追加自己的覆盖,用 @unocss/core 导出的 mergeConfigs 组合:

// uno.config.ts
import { mergeConfigs } from '@unocss/core'
import config from './.nuxt/uno.config.mjs'

export default mergeConfigs([config, {
  // Your overrides
  shortcuts: {
    'custom': 'text-red-500',
  },
}])

mergeConfigs 是 UnoCSS 官方提供的配置合并函数,会深度合并 presets / shortcuts / rules / theme 等字段。airi 仓库对它的使用与此完全同构:根 uno.config.tsmergeConfigs([sharedUnoConfig(), histoireUnoConfig()]) 合并共享配置与 Histoire 专用配置,apps/stage-web/uno.config.ts 又基于根共享配置 mergeConfigs 出自己的 Web 端专属配置。可见这套"基座 + 覆盖"的合并哲学在 Vite 应用与 Nuxt Layers 场景中是同一套心智模型。

4.3 完整常用配置范例

技能文档给出了一个覆盖绝大多数实际项目需求的"全家桶"配置,值得直接作为模板:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@unocss/nuxt',
  ],
})
// uno.config.ts
import {
  defineConfig,
  presetAttributify,
  presetIcons,
  presetTypography,
  presetWebFonts,
  presetWind3,
  transformerDirectives,
  transformerVariantGroup,
} from 'unocss'

export default defineConfig({
  presets: [
    presetWind3(),
    presetAttributify(),
    presetIcons({
      scale: 1.2,
    }),
    presetTypography(),
    presetWebFonts({
      fonts: {
        sans: 'DM Sans',
        mono: 'DM Mono',
      },
    }),
  ],
  transformers: [
    transformerDirectives(),
    transformerVariantGroup(),
  ],
  shortcuts: [
    ['btn', 'px-4 py-1 rounded inline-block bg-teal-600 text-white cursor-pointer hover:bg-teal-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
  ],
})

各成员的角色与参考文档如下:

成员 作用 深入参考
presetWind3() Tailwind v3 / Windi 兼容核心工具集 preset-wind3
presetAttributify() 允许把工具类写到 HTML 属性上(见第五节) preset-attributify
presetIcons({ scale: 1.2 }) 纯 CSS 图标,scale 控制图标尺寸缩放比 preset-icons
presetTypography() 提供 prose 等排版类 preset-typography
presetWebFonts({ fonts }) 按需加载 Web 字体(Google Fonts / Fontsource 等提供商) preset-web-fonts
transformerDirectives() 让 CSS 中可用 @applytheme() 等指令 transformer-directives
transformerVariantGroup() 支持 hover:(...) 这类变体分组简写 transformer-variant-group
shortcuts 语义化复合类(数组写法支持更复杂展开) core-shortcuts

提示:上面的 sans: 'DM Sans'mono: 'DM Mono' 恰好也是 airi 的默认字体栈成员。airi 根 uno.config.tspresetWebFontsFonts('fontsource') 工具函数把 sans/serif/mono/日文可爱字体 Kiwi Maru 等多语言字体族统一交给 Fontsource 提供商按需加载,apps/stage-web/uno.config.ts 还在实际部署中为字体请求设置了 timeouts: { warning: 5000, failure: 10000 }——如果你在 CI/无外网环境(如 Netlify)构建,这套"字体提供商超时"的坑位与解法(根配置中 setDefaultAutoSelectFamilyAttemptTimeout(1000) 的注释说明)值得提前借鉴。

五、在组件中使用

5.1 常规 class 写法

<template>
  <div class="p-4 text-center">
    <h1 class="text-3xl font-bold text-blue-600">
      Hello UnoCSS!
    </h1>
    <button class="btn mt-4">
      Click me
    </button>
  </div>
</template>

text-3xl font-bold text-blue-600presetWind3 生成;btn 则由 shortcut 展开为上一节配置中完整的按钮样式串(含 hover:disabled: 变体)。

工程建议(同样写在本仓库 SKILL.md 中):优先使用基础的 class 写法;只有当团队对 attributify 模式与 preset 集合足够熟悉、且 IDE 插件配置完整时,再启用 attributify 等进阶能力。

5.2 Attributify 模式

如果开启了 presetAttributify(),工具类可以"属性化"书写,把同类工具合并到同一个属性里、以空格分词:

<template>
  <div p="4" text="center">
    <h1 text="3xl blue-600" font="bold">
      Hello UnoCSS!
    </h1>
  </div>
</template>

这里 p="4" 等价于 p-4text="3xl blue-600" 等价于 text-3xl text-blue-600font="bold" 等价于 font-bold。它显著提升了模板的可读性,但要求编辑器能正确识别这类"虚拟属性",否则会收到属性类型报错——这是选用 attributify 前需要确认的前置条件。写法细节参见 preset-attributify

六、Inspector:开发态的可视化调试面板

在开发模式下,访问:

/_nuxt/__unocss

即可打开 UnoCSS inspector。它能做三件事:检查生成的 CSS 规则(某条工具类最终产出了什么样式)、查看每个文件实际命中了哪些工具类、以及在 REPL 中即时验证尚未写进组件的工具类是否按预期生效。

注意这里的路径前缀是 /_nuxt/__unocss,与 Vite 接入时访问的 http://localhost:5173/__unocss(见 integrations-vite.md)不同——这是 Nuxt 约定路由前缀导致的两者差异之一。排查"某个类为什么没生效"时,inspector 是最快的定位工具:若类未出现在列表中,多半是内容抽取(extracting)没有覆盖到该文件,而非规则本身写错。

七、与 Vite 集成的关键差异对照表

integrations-vite.md 与本文内容对读,Nuxt 模块相对 Vite 插件的差异可归纳为四点:

  1. 无需 virtual:uno.css 手动导入:Nuxt 模块自动注入 uno.css;Vite 集成要求在入口写 import 'virtual:uno.css'
  2. 配置文件发现机制一致:两者都自动读取项目根目录的 uno.config.* / unocss.config.* 文件,规则相同,迁移成本低。
  3. Vite 插件的全部功能在 Nuxt 下均可用:preset、shortcuts、transformers、content 抽取管线等行为保持一致。
  4. 额外获得 Nuxt Layers 配置合并nuxtLayers: true 可跨 Layer 自动合并 UnoCSS 配置,这是纯 Vite 接入没有的能力。

从 airi 仓库的实际代码可以直观看到第 1 条的差异落地:四个 Vite 应用都要在入口手动 import 'uno.css'(如 apps/stage-web/src/main.tsapps/ui-server-auth/src/main.tsapps/component-calling/src/main.ts),而这些样板在 Nuxt 工程中会被模块自动处理掉。

八、进阶注意:内容抽取与生产可用性

UnoCSS 的"按需生成"依赖 content 抽取管线:它默认扫描哪些文件、类名如何从源码中被提取,直接决定了样式是否完整。Nuxt 场景需要注意:

  • .vue 文件默认在抽取范围内,组件的 class / attributify 属性都能被识别;而 .js / .ts 文件默认不被抽取。
  • 若你在脚本里动态拼接工具类字符串(例如把 bg-primary text-white 作为常量写在 .ts 里),需要扩大 content.pipeline.include。airi 根 uno.config.ts 提供了一个成熟的管线配置样本:include 中追加 '(components|src)/**/*.{js,ts,vue}' 与组件库目录,同时 exclude 掉 node_modules,以避免误扫进依赖体积;此外还可借助 // @unocss-include 魔法注释实现文件级精确收录(细节见 integrations-vite.mdcore-extracting)。
  • 动态类名不会全部被抽取:运行时才能确定完整类名的场景,应使用 safelist 显式罗列(见 core-safelist),airi 根配置的 safelistAllPrimaryBackgrounds() 即为按主色阶与透明度批量生成 safelist 的实践。

结语

@unocss/nuxt 让 Nuxt 工程获得与 Vite 场景几乎一致的 UnoCSS 开发体验,并以"自动注入入口 CSS"和"Nuxt Layers 配置合并"进一步降低样板代码。接入路径遵循三段式:pnpm add -D unocss @unocss/nuxtnuxt.config.ts 注册模块 → 根目录创建 uno.config.ts 声明 presets/shortcuts/transformers。选型时对照支持矩阵确认 Nuxt 版本与构建工具组合;复杂 monorepo 中则善用 mergeConfigs + nuxtLayers 实现"共享基座 + 分层覆盖"。文中所引 airi 仓库 根 uno.config.tsapps/stage-web/uno.config.ts 里的 preset 组合、自定义规则、safelist 与管线配置,均可作为 Nuxt 工程落地同一套样式体系时的直接蓝本。

进一步阅读:本仓库技能文档可继续深入 Vite 集成配置总览 core-configshortcutsattributify 预设 等章节,以补齐从"能跑"到"用好"的每一环。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525