Umi 项目样式方案完全指南:从原生 CSS、CSS Modules 到 Tailwind CSS 与 UnoCSS 的实战配置
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
Umi 作为 React 社区的应用级框架,在构建层为样式处理提供了开箱即用的完整能力。本文以 Umi 官方样式指南为核心,系统讲解在 Umi 项目中使用原生 CSS、CSS Modules、LESS/SASS/SCSS/Stylus 预处理器,以及通过内置插件接入 Tailwind CSS 与 UnoCSS 的完整路径,并结合仓库源码(packages/plugins/src/tailwindcss.ts、packages/plugins/src/unocss.ts)剖析其底层运行原理,帮助你按项目诉求选择并落地最合适的样式方案。
使用原生 CSS 样式
在 Umi 项目中,你可以直接使用.css文件声明各种样式,然后在.js(或.tsx)文件中通过import引入即可生效。
例如,在src/pages/index.css中声明.title类的样式为红色:
.title { color: red; }然后在src/pages/index.tsx中引入该样式文件:
// src/pages/index.tsx import './index.css'; export default function () { return <div className="title">Hello World</div>; }需要特别注意的是:按照此种方式引入的样式会在整个 Umi 项目中生效。也就是说,无论你从哪个.js文件引入,它声明的样式都可以在任何页面和组件中使用——这是典型的全局样式行为。如果你希望避免样式被全局污染、限制样式作用域,请使用下一节介绍的 CSS Modules 功能。
使用 CSS Modules 隔离样式作用域
在js文件中引入样式时,如果为引入的样式赋予一个变量名,Umi 就会自动以 CSS Module 的形式处理该样式:
// src/pages/index.tsx import styles from './index.css'; export default function () { return <div className={styles.title}> Hello World </div>; }在上面的示例中,index.css中声明的样式不会对全局样式造成任何影响,只会对通过styles变量引用的类名生效。Umi 在编译期会将类名转换为带有哈希后缀的局部作用域名,从机制上避免类名冲突,非常适合组件库、多人协作或大型业务项目。
使用 CSS 预处理器
Umi 默认内置支持 LESS(官方推荐)、SASS 和 SCSS 样式的导入,你可以直接按照引入 CSS 文件的方式引入并使用这些由预处理器处理的样式。
// src/pages/index.tsx import './index.less'; import './index.sass'; import './index.scss'; export default function () { return <div className="title">Hello World</div>; }:::info{title=💡} 在 Umi 中使用 SASS(SCSS)需要额外安装预处理依赖,例如执行:
npm add -D sass:::
CSS 预处理器同样支持 CSS Modules 用法,只需为引入的样式赋予变量名即可:
// src/pages/index.tsx import lessStyles from './index.less'; import sassStyles from './index.sass'; import scssStyles from './index.scss'; export default function () { return <div className={lessStyles.title}> Hello World <p className={sassStyles.blue}>I am blue</p> <p className={scssStyles.red}>I am red</p> </div>; }此外,Umi 还内置支持.styl和.stylus文件。使用前必须先安装stylus预处理器依赖,其余用法与上述示例完全一致:
# .styl and .stylus npm add -D stylus从 Umi 仓库的示例集合(如 examples/with-sass、examples/with-stylus)可以看到,官方为这些预处理器均提供了可直接运行的参考项目,其中包含
.scss/.styl源文件与配套的package.json,可作为实际项目的起点模板。
进阶设置:通过 chainWebpack 接入自定义 Loader
如果你需要使用除常见 LESS、SASS、SCSS 之外的其他样式预处理器(例如 Stylus 之外的方言、PostCSS 插件等),可以通过 Umi 插件体系提供的chainWebpack接口加入自己需要的 Loader。
在 Umi 配置中,chainWebpack的类型为(memo, args) => void,默认值为null,其作用是以链式编程的方式修改 Umi 内置的 webpack 配置,底层基于 webpack-chain:
export default { chainWebpack(memo, { env, webpack }) { // 在这里通过 memo 链式调用修改 webpack 配置 return memo; }, };其中memo是当前 webpack 配置对象,args则携带env(当前环境,值为development或production)与webpack(webpack 对象,可获取内置插件等)两个辅助信息。完整接口说明可参考 chainWebpack 配置文档。Umi 插件自身的样式能力也依赖这套机制:例如 tailwindcss 插件源码 就通过api.chainWebpack为tailwind.css文件注册了前置 loader,这为理解自定义 Loader 的接入方式提供了现成范例。
使用 Tailwind CSS
Umi 提供了内置的 Tailwind CSS 插件,并且可以直接方便地使用「微生成器」(Micro-generator)来启用,无需手工编写配置。
通过微生成器一键启用
执行以下命令即可为项目开启 Tailwind CSS 配置:
$umi g tailwindcss命令执行后,Umi 会自动完成以下工作:
- 写入
package.json并安装 Tailwind CSS 相关依赖; - 在
.umirc.ts中写入config:tailwindcss配置项; - 更新
.umirc.ts中的plugins配置; - 生成
tailwind.config.js与tailwind.css两个文件。
(上述输出信息摘自 微生成器文档,仓库中的 examples/with-tailwindcss 和 examples/with-tailwindcss-v4 则提供了 Tailwind CSS v3 与 v4 两套可直接运行的示例工程。)
底层运行机制
从 packages/plugins/src/tailwindcss.ts 的源码可以清楚看到该插件的完整工作流:
- 配置开关:插件通过
api.describe注册tailwindcss配置项,并以enableBy: api.EnableBy.config的方式在「配置了该字段时」才启用; - 样式生成(v3):在
onBeforeCompiler阶段,插件通过crossSpawn启动tailwindcss二进制子进程,将项目根目录的tailwind.css与tailwind.config.js作为输入,把生成的样式输出到临时目录plugin-tailwindcss/tailwind.css(见 tailwindcss.ts)。开发环境下以--watch=always常驻监听,并每 300ms 轮询检查产物是否生成;生产环境下则在进程退出后结束构建; - 自动注入:构建完成后,插件通过
api.addEntryImports把生成的 CSS 文件自动追加到入口模块的 import 中,开发者无需手动引入(见 tailwindcss.ts); - Tailwind CSS v4 适配:插件会检测安装的
tailwindcss是否为 v4 版本(isTailwindV4)。若是 v4,则跳过子进程方案,改由@tailwindcss/webpackloader 处理(webpack/utoopack 场景下注册tailwindcss规则),并直接引入项目根目录的tailwind.css,保证新版本下的正确编译。
使用 UnoCSS
与 Tailwind CSS 相同,Umi 也提供了内置的 UnoCSS 插件,可以按照同样的思路开启。相比 Tailwind 的一键生成器,UnoCSS 的接入更强调手动配置,具体分为以下 5 步:
第 1 步:安装plugin-unocss
Umi 的 UnoCSS 插件位于@umijs/plugins包中,源码为 packages/plugins/src/unocss.ts,随 Umi 一并提供,无需单独安装。
第 2 步:安装unocss及@unocss/cli
pnpm i unocss @unocss/cli第 3 步:在 Umi 配置中启用插件并声明监听目录
// .umirc.ts export default { plugins: [ require.resolve('@umijs/plugins/dist/unocss') ], unocss: { // 检测 className 的文件范围,若项目不包含 src 目录,可使用 `pages/**/*.tsx` watch: ['src/**/*.tsx'] }, };这里的watch字段是插件的核心配置:从源码看,它的 schema 约束为zod.array(zod.any())的字符串数组,插件会将unocss.watch中的目录作为@unocss/cli的扫描输入(见 unocss.ts),用于告诉 UnoCSS 在哪些文件中检测工具类名。若项目没有src目录(例如直接在根目录放置pages),请相应调整为pages/**/*.tsx。
第 4 步:添加unocss.config.ts配置文件
在项目目录下创建unocss.config.ts,并加入项目需要的 UnoCSS Presets:
// unocss.config.ts import {defineConfig, presetAttributify, presetUno} from 'unocss'; export function createConfig({strict = true, dev = true} = {}) { return defineConfig({ envMode: dev ? 'dev' : 'build', presets: [presetAttributify({strict}), presetUno()], }); } export default createConfig();此配置文件不可或缺:源码中插件在构建前会检查unocss.config.ts是否存在,若缺失则输出警告「请在项目目录中添加 unocss.config.ts 文件,并配置需要的 unocss presets,否则插件将没有效果!」(见 unocss.ts)。仓库中的 examples/with-unocss 项目提供了unocss.config.ts、tailwind.css及配套页面的完整示例,可作为参照。
第 5 步:启动项目,动态生成并自动套用样式
npm run dev启动项目后,插件会监听配置文件中unocss.watch字段指定的文件范围:源码中通过execa以子进程方式启动node_modules/.bin/unocss,传入watch目录与--out-file输出参数,将生成的样式写入临时目录下的uno.css;开发环境追加--watch参数进入监听模式(见 unocss.ts)。随后同样通过api.addEntryImports将生成的uno.css自动注入入口模块(见 unocss.ts),开发者只需在 JSX 中直接书写class名,样式即可自动生效。
总结与选型建议
围绕 Umi 的样式体系,可以形成如下选型路径:
| 场景 | 推荐方案 | 特点 |
|---|---|---|
| 全局主题、Reset、公共样式 | 原生.css直接引入 | 引入即全局生效,简单直接 |
| 组件级样式、避免命名冲突 | CSS Modules(引入时赋予变量名) | 编译期生成局部作用域,隔离彻底 |
| 需要变量、嵌套、Mixin 等能力 | LESS(推荐)/ SASS / SCSS | Umi 内置支持,SASS 需自行安装sass依赖 |
| 原子化 CSS、按需生成工具类 | Tailwind CSS(微生成器一键开启) | 内置插件 +umi g tailwindcss,自动注入产物 |
| 高度可定制、极速的原子化方案 | UnoCSS(手动配置) | 内置插件,需配置watch目录与unocss.config.ts |
无论是传统的手写样式、预处理器工程化,还是新一代的原子化 CSS 体系,Umi 都在构建层提供了开箱即用的支持与源码级可控的扩展能力,开发者可以完全依据项目规模和团队偏好进行组合使用。
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考