Skip to main content

UnoCSS 集成与使用(替代 SCSS)

本节说明如何将 UnoCSS 集成进基于本框架的 Angular 项目,并作为 SCSS 的补充或替代 使用,以原子化工具类提升样式开发效率。

1. 为何用 UnoCSS 替代/补充 SCSS​

  • 原子化 CSS:按需生成工具类(如 flex、p-4、text-blue-500),减少手写 CSS/SCSS 体积与重复。
  • 与组件共存:可在模板中直接写类名,也可在 styles 或全局样式中使用;与现有 SCSS 文件可逐步迁移、并存。
  • 构建集成:通过 Webpack 或 Vite 插件在构建时扫描源码生成样式,无需预写一大份 CSS。

本框架默认不强制样式方案,以下集成方式适用于使用 Angular CLI(Webpack) 或 Vite 构建 的 Angular 项目。

2. 集成方式概览​

构建方式推荐集成说明
Angular CLI(默认 Webpack)@angular-builders/custom-webpack + @unocss/webpack通过 custom-webpack 注入 UnoCSS 插件
Vite(如 @angular/build + Vite)Vite 官方插件 unocss/vite与 Vite 生态一致,配置简单

下面分别给出两种方式的安装与配置步骤。

3. 方式一:Angular CLI + Webpack​

3.1 安装依赖​

pnpm add -D unocss @unocss/webpack
pnpm add -D @angular-builders/custom-webpack

若项目仍使用 Webpack 4,需保证具备 style-loader 与 css-loader(Angular 默认已有)。

3.2 创建 UnoCSS 配置​

在项目根目录创建 uno.config.ts:

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

export default defineConfig({
presets: [presetUno()],
shortcuts: {
'btn': 'px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600',
'card': 'p-4 border border-gray-200 rounded-md shadow-sm',
},
});

可按需增加 presetAttributify、presetIcons 或自定义 rules。

3.3 自定义 Webpack 配置​

创建 webpack.config.js(或 .ts,需能被子 builder 加载):

// webpack.config.js(UnoCSS v0.59+ 为 ESM,使用动态 import)
module.exports = function () {
return import('@unocss/webpack').then(({ default: UnoCSS }) => ({
plugins: [UnoCSS()],
optimization: {
realContentHash: true,
},
}));
};

若使用较旧版 UnoCSS,可用 CommonJS:

const UnoCSS = require('@unocss/webpack').default;
module.exports = {
plugins: [UnoCSS()],
optimization: { realContentHash: true },
};

3.4 在 angular.json 中启用 custom-webpack​

在对应项目的 architect.build 中替换 builder 并指定 custom-webpack 配置:

{
"projects": {
"your-app": {
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.config.js"
}
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"buildTarget": "your-app:build"
}
}
}
}
}
}

将 your-app 替换为实际项目名;若使用 applicationBuilder(应用型构建),需查看 @angular-builders/custom-webpack 是否支持并选用对应 target。

3.5 引入 UnoCSS 入口样式​

在全局样式入口(如 src/styles.scss 或 src/main.ts)中增加:

// main.ts 顶部
import 'uno.css';

或:

// styles.scss
@import 'uno.css';

保证 UnoCSS 生成的样式参与打包。完成后执行 ng build / ng serve,模板中使用的 Uno 类即可生效。

4. 方式二:Vite 构建的 Angular 项目​

若项目已迁移到 Vite(例如通过 @angular/build 的 experimental 或社区方案),可直接使用 Vite 插件。

4.1 安装​

pnpm add -D unocss

4.2 配置文件​

同样在根目录使用 uno.config.ts(同上)。

4.3 Vite 配置​

在 vite.config.ts 中:

import UnoCSS from 'unocss/vite';

export default defineConfig({
plugins: [
angular(),
UnoCSS(),
],
});

4.4 入口引入​

在 main.ts 或全局样式入口中:

import 'uno.css';

5. 在项目中的使用方式(替代 SCSS 的写法)​

5.1 模板中直接使用工具类​

原先用 SCSS 写的布局、间距、颜色等,可改为原子类:

<div class="flex items-center justify-between p-4 bg-white rounded-lg shadow">
<h2 class="text-lg font-semibold text-gray-800">标题</h2>
<button class="btn">操作</button>
</div>

btn 在 uno.config.ts 的 shortcuts 中已定义,等同于一组工具类组合。

5.2 与组件 styles 并存​

组件内仍可使用 styles: ['...'] 或 styleUrls 写 SCSS;仅把适合原子化的部分移到 class,复杂或组件私有的样式保留在 SCSS 中:

@Component({
selector: 'app-card',
template: `<div class="card p-4">{{ title }}</div>`,
styles: [`
:host { display: block; }
.card { /* 仅保留无法用工具类表达的样式 */ }
`],
})

5.3 响应式与状态变体​

UnoCSS 默认支持类似 Tailwind 的断点与状态前缀:

<div class="w-full md:w-1/2 lg:w-1/3 p-2 md:p-4 hover:bg-gray-100">
响应式 + 悬停
</div>

5.4 渐进替代 SCSS 的建议​

  • 新页面/新组件:优先用 Uno 工具类 + 少量 SCSS(或仅 :host)。
  • 旧页面:保留原有 SCSS,仅在新加块或改版时逐步改用类名,避免一次性大改。
  • 全局变量:颜色、间距等若原在 SCSS 变量中,可在 uno.config.ts 的 theme 中统一,或继续用 SCSS 变量 + 少量混合使用。

6. 小结​

6. 与 AI 全自动开发的取舍(重要说明)​

如果你的目标是「主要由 AI Agent 负责自动生成/重构前端代码,人工以需求+审核为主」,不建议在业务层大量直接写原子类,而应将 UnoCSS 控制在「实现层」,把语义与布局抽象交给 SCSS / 设计令牌与组件类名。

6.1 为何大量原子类会削弱 AI 的效果?​

  • 原子类表达的是实现细节(bg-xx px-4 py-2),而不是「卡片」「主按钮」「警告 Banner」等语义。
  • 当同一种视觉风格在多个页面出现时,如果都用一串类堆出来:
    • AI(和人)在生成新代码时更容易「复制粘贴那一长串」,而不是提炼为复用样式;
    • 全局风格调整(如改主色/圆角/间距)需要在很多模板里统一替换,自动化重构成本更高。
  • 对 AI Agent 来说,语义清晰的类名 / 组件 / 设计令牌,比零散的 class 列表更容易理解和复用。

换句话说:
SCSS + 设计令牌 + 语义化类名 更像是「可被 AI 理解的领域语言」,而全原子类更像是「机器码」,自动化空间会小很多。

6.2 推荐的折中策略​

在本平台中,更推荐如下用法:

  • 仍以 SCSS + 设计令牌为主:
    • 在 tokens/_variables.scss 与主题文件中维护颜色、间距、布局等令牌;
    • 组件层使用语义化类名(如 .card-panel, .btn-primary),这些类再内部使用 Uno 的 shortcuts 或 token;
    • 让 AI 在生成代码时更多操作「卡片/按钮/布局组件」,而不是「一串原子类」。
  • UnoCSS 负责实现细节与快速实验:
    • 在 uno.config.ts 内定义少量语义化 shortcuts(如 btn-primary, card-surface);
    • 业务模板中优先用 shortcuts/组件类名,仅在极轻量 demo 或一次性页面中直接写原子类。

这样可以同时兼顾:

  • 开发体验:需要时仍可用 Uno 的原子类快速试验样式;
  • AI 自动化:大部分语义与布局抽象仍存在于 SCSS / 设计令牌 / 组件类名中,AI 更容易理解与批量生成/重构。

6.3 总结​

场景更推荐的选择
人工主导、小型页面快速试验可以更多使用 Uno 原子类,追求开发速度
中大型项目、希望 AI Agent 高度自动开发以 SCSS + 设计令牌 + 语义类名为主,Uno 作为实现层和 shortcuts,避免在业务模板中到处堆原子类

按上述方式集成 UnoCSS,可以在需要时享受原子化的灵活,同时保持「样式语义层」对 AI 友好,便于未来走向更高程度的自动化开发。