news 2026/9/13 23:15:34

UnoCSS CLI 完全指南:用 @unocss/cli 在传统后端与命令行工作流中生成原子化 CSS

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UnoCSS CLI 完全指南:用 @unocss/cli 在传统后端与命令行工作流中生成原子化 CSS

UnoCSS CLI 完全指南:用 @unocss/cli 在传统后端与命令行工作流中生成原子化 CSS

【免费下载链接】unocssThe instant on-demand atomic CSS engine.项目地址: https://gitcode.com/GitHub_Trending/un/unocss

@unocss/cli是 UnoCSS 的命令行入口,专为无法(或不便于)接入构建工具插件体系的"传统后端"场景设计:只需给定一组 glob 扫描模式,它就能从模板、脚本文件中提取类名、应用 transformers、并产出可直接部署的uno.css。本文以packages-engine/cli/README.md及其指向的官方文档 CLI 集成文档 为核心,结合 CLI 源码实现 与 测试用例,完整覆盖安装、全部命令行选项、配置文件中的cli.entry高级用法、--rewrite--split-css的底层行为,以及 watch 模式的工作机制。

包定位与安装

@unocss/cli的包描述为 "CLI for UnoCSS",当前仓库中版本号为66.10.0(见 package.json),通过bin字段暴露unocss可执行命令(bin/unocss.mjs)。它独立于 Vite、PostCSS、Webpack 等集成方式,核心价值在于:

  • 从任意 glob 匹配的文件中扫描并提取 utilities;
  • 内置--watch开发监听模式;
  • 通过uno.config.ts支持完整自定义配置;
  • 提供多个输出选项(输出文件名、stdout、压缩、重写源文件、CSS 拆分等);
  • 支持多个 entry pattern,分别产出不同 CSS 文件。

安装有两种方式。CLI 随unocss全量包一起分发:

pnpm add -D unocss # 或 yarn / npm / bun yarn add -D unocss npm install -D unocss bun add -D unocss

也可以只安装独立的 CLI 包:

pnpm add -D @unocss/cli yarn add -D @unocss/cli npm install -D @unocss/cli bun add -D @unocss/cli

注意:官方文档特别提示,如果你找不到unocss二进制(例如使用pnpm且只安装了unocss包),需要显式安装@unocss/cli独立包。

基本用法:glob 模式与多入口

CLI 接受一个或多个 glob 模式作为位置参数:

unocss "site/snippets/**/*.php" "site/templates/**/*.php"

配合 npm scripts 的典型配置(注意官方文档强调:npm script 中的 glob 模式要加转义引号,防止 shell 提前展开):

{ "scripts": { "dev": "unocss \"site/{snippets,templates}/**/*.php\" --watch", "build": "unocss \"site/{snippets,templates}/**/*.php\"" }, "devDependencies": { "@unocss/cli": "latest" } }

开发时用--watch(或-w)监听文件变化,生产构建直接运行不带--watch的命令即可。默认情况下,最终产物uno.css会生成在当前工作目录。

如果既没有提供 glob 模式,也没有在配置文件中定义cli.entry,CLI 会抛出一个友好的PrettyError,提示形如No glob patterns provided. Try unocss <path/to/**/*> or configure entries in uno.config file,并将进程退出码置为 1(见 resolveOptions 中的校验逻辑 与 errors.ts)。

选项解析细节

所有命令行选项在 cli-start.ts 中基于cac注册,默认值与文档表格一致:

  • --out-file默认解析为<cwd>/uno.css
  • --preflights默认true(默认开启 preflight 样式);
  • --split-css默认true
  • --preset默认wind4
  • --stdout模式下,--watch--out-file会被忽略,且日志会重定向到 stderr,保证 stdout 只有纯 CSS 输出(有专门的测试keeps cli logs off stdout验证这一点,见 cli.test.ts)。

配置文件:uno.config.tscli.entry

在项目根目录创建uno.config.jsuno.config.ts即可自定义 UnoCSS。除了 presets、theme、rules 等通用配置外(详见 UnoCSS 配置文档),CLI 提供了专属的cli配置块,用于"不同级别的文件打包与重写":

import { defineConfig } from 'unocss' export default defineConfig({ cli: { entry: {}, // CliEntryItem | CliEntryItem[] }, // ... }) interface CliEntryItem { /** * Glob patterns to match files */ patterns: string[] /** * The output filename for the generated UnoCSS file */ outFile: string /** * Whether to rewrite the transformed utilities. * * - For css: if rewrite is true, it will not generate a new file, but directly modify the original file content. * - For other files: if rewrite is true, it replaces the original file with the transformed content. * * @default false */ rewrite?: boolean /** * Whether to output CSS files scanned from patterns to outFile * * - false: Do not output CSS files * - true: Transform and output scanned CSS file contents to outFile * - 'multi': Output each CSS file separately with filename format `${originFile}-[hash]` * - 'single': Merge multiple CSS files into one output file named `outFile-merged.css` * * @default true */ splitCss?: boolean | 'multi' | 'single' }

从 resolveOptions 源码 可以看到入口的合并规则:

  1. 命令行传入的patterns会被包装成第一个 entry,outFile--out-file值(默认<cwd>/uno.css);
  2. uno.configcli.entry(单个对象或数组,经toArray归一化)逐项追加,每一项的rewrite/splitCss若未显式设置,则回落到命令行--rewrite/--split-css的值;
  3. 两套 entry 共同构成options.entries,构建时并行生成各自的输出文件。

测试用例supports unocss.config.js cli options验证了多入口场景:配置中声明views/index1.html → ./uno1.cssviews/index2.html → ./test/uno2.css两条 entry,构建后两个输出文件分别包含各自的.bg-blue.bg-red规则(见 cli.test.ts)。

Rewrite 源文件:--rewrite

--rewrite会让 CLI 把经过 transformers 变换后的内容写回源文件本身,适合希望把 Variant Groups、Compile Class 等变换直接固化进代码的场景:

unocss "src/**/*.vue" --rewrite

旧的--write-transformed选项已废弃,源码中遇到它时仍会兼容处理,但打印警告--write-transformed is deprecated, please use --rewrite instead(见 resolveOptions 中的警告逻辑)。

transformers 的执行顺序在 transformFiles 中固定为pre → default → post三个阶段依次调用applyTransformers。测试applies pre, default, and post transformers精确验证了这一顺序:三个自定义 transformer 分别向<div></div>前置<div class="bg-red">、追加<div class="bg-blue"><div class="p-4">,最终文件内容为三段拼接的确定顺序,且生成 CSS 中同时包含.bg-red.bg-blue.p-4

以 Variant Group 为例(官方文档推荐搭配 transformers/variant-group 或 transformers/compile-class):

# 配置中启用 transformerVariantGroup() 后 unocss "views/index.html" --rewrite # <div class="border-(~ solid red)"></div> → 被展开为 border-solid border-red 等标准类

对应测试见 supports variantGroup transformer。

CSS 拆分:--split-css

当扫描模式中混入了.css文件时,--split-css控制这些 CSS 如何进入产物:

unocss "src/**/*.vue" --split-css true|false|multi|single
取值行为
false不输出 CSS 文件(直接丢弃扫描到的.css
true转换后的 CSS 内容并入outFile
multi每个 CSS 文件单独输出,文件名为${originFile}-[hash].css
single合并为outFile-merged.css

parseEntries 源码 清晰展示了这四种分支:

  • true:CSS 文件内容追加进outFile对应的缓存桶;
  • single:全部 CSS 归入以outFile去掉.css后拼-merged.css命名的桶(outFile.replace(/(\.css)?$/, '-merged.css'));
  • multi:为每个文件计算hash(file),输出${file}-${hash}.css当该 entry 只匹配到一个文件时,退化为直接写入outFilefiles.length > 1 ? currentOutFile : outFile);
  • false:CSS 文件被静默丢弃。

并入outFile的 CSS 在产物中带有/* Source: <file> */来源注释,便于溯源(CI 环境下不带注释,见 generateSingle)。

默认 Preset:--preset

当项目中没有找到uno.config时,可以用--preset指定 CLI 使用的默认 preset:

unocss "src/**/*.vue" --preset wind3|wind4
  • wind4:加载@unocss/preset-wind4
  • wind3:加载@unocss/preset-wind3

注意:如果配置了uno.config,该选项会被忽略。

源码层面,initializeConfig 在configSources为空时动态import对应 preset 包,并同时挂入transformer-directives(即默认支持@apply指令),然后ctx.uno.setConfig注入。这与 use default preset via cli option 测试(--preset wind4bg-blue@apply均生效)相互印证。

官方文档还有一条版本约束值得记住:v66.6.0起,@unocss/cli不再"静默"提供默认 preset——要么显式传--preset,要么在配置文件中声明 presets。在wind3wind4两代 preset 并存期间,这一显式选择可以避免产物差异带来的困惑。

完整命令行选项速查

以下为 CLI 文档选项表 的完整内容,并对照 cli-start.ts 中的注册代码 核实了默认值:

Options说明默认值
-v, --version显示当前 UnoCSS 版本
-c, --config [file]指定配置文件路径自动探测
-o, --out-file <file>生成的 UnoCSS 文件名<cwd>/uno.css
--stdout将生成的 CSS 写入 STDOUT;会忽略--watch--out-filefalse
-w, --watch监听 glob 匹配到的文件变化false
--preflights是否输出 preflight 样式true
--rewrite用变换后的 utilities 回写源文件false
--write-transformed--rewrite(已废弃)false
-m, --minify压缩生成的 CSSfalse
--debug启用调试模式(打印文件生成明细表)false
--split-css [mode]控制扫描到的 CSS 文件的输出方式:true/false/multi/singletrue
--preset [default-preset]在无配置文件时切换wind3/wind4默认 presetwind4
-h, --help显示可用 CLI 选项

补充两个源码中可见但文档未逐字展开的行为:

  • --stdout--out-file互斥校验:显式同时指定时直接logger.fatal报错退出;
  • --debug会调用 debugDetailsTable,以表格形式打印每个输出文件与其来源文件的对应关系(File Generation Details:),排查多 entry 映射问题时非常有用。

内部构建流程与 Watch 模式

build 函数 串起完整管线:initializeConfigresolveOptionsparseEntries(tinyglobby 扫描)→ 非 watch 模式直接generate,watch 模式则先startWatcher再按需重建。

Watch 模式要点(实现见 watcher.ts):

  • 底层使用chokidarusePolling: trueinterval: 100(轮询而非 inotify,兼容性优先),并忽略**/{.git,node_modules}/**
  • 监听范围包括所有已匹配的源文件以及配置文件本身ctx.getConfigFileList());
  • 触发事件后统一经 100ms 的perfect-debounce防抖再重新generate
  • 源文件change时只更新缓存中的代码内容,unlink时从缓存移除,add时重新parseEntries
  • 配置文件变化会触发ctx.reloadConfig(),重新解析 options 与 entries 后再重建——测试supports uno.config.ts changed rebuild验证了修改uno.config.ts主题色后产物即时从red变为blue(见 cli.test.ts)。

产物生成阶段(generateSingle)的关键步骤:

  1. 对每个源文件依次执行 pre/default/post transformers;
  2. 去除@unocss-skip-start/@unocss-skip-end之间的内容(SKIP_COMMENT_RE),这是官方测试@unocss-skip uno.css覆盖的特性:skip 块中的bg-redtext-white不会出现在产物里;
  3. 非 CSS 文件调用ctx.uno.generate(input, { preflights: false, minify: true, id })只收集matched token 集合,不产出 CSS;
  4. rewrite开启,将transformedCode写回原文件;
  5. 用 token 集合做最终一次generate(此时才应用preflightsminify选项),拼接扫描到的 CSS 内容后写入outFile(目录不存在会自动mkdir -p)。

两阶段 generate 的设计意味着:preflight 与最终压缩只执行一次,与源文件数量无关。

测试覆盖一览

cli.test.ts 为上述行为提供了完整回归保障,主要用例包括:

  • 基本构建:<div class="p-4 max-w-screen-md">→ 快照断言uno.css
  • CSS 扫描 + 变换:@apply指令经transformer-directives展开;
  • --preset wind4默认 preset 行为;
  • unocss.config.js(shortcuts)与cli.entry多输出文件;
  • --rewrite下 Variant Group、directives 的源文件回写;
  • pre/default/post transformer 顺序与错误传播(transformer 抛错会中断构建);
  • @media的混合类型文件去重正确性;
  • @unocss-skip注释块排除;
  • --stdout模式下 stdout 纯净性;
  • watch 模式下源文件变更与配置文件变更的重建(Node 20 下跳过 watch 用例)。

小结

@unocss/cli把 UnoCSS 的核心能力压缩成一条命令:glob 模式定义"扫什么",uno.config.tscli.entry定义"输出到哪",--rewrite让 transformers 直接改写源码,--split-css精确控制伴随 CSS 的去向,--preset决定无配置时的默认风味。对于 PHP、Laravel、Django 等传统后端模板项目,或者任何不便引入前端构建工具的场景,它提供了与 Vite/PostCSS 集成同等表达力的替代路径,且 watch 模式下的文件级增量缓存与配置热重载使开发体验同样完整。

【免费下载链接】unocssThe instant on-demand atomic CSS engine.项目地址: https://gitcode.com/GitHub_Trending/un/unocss

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 23:11:38

Cursor动态上下文管理:提升AI编程效率的核心技术

1. Cursor动态上下文工程管理概述作为一款革命性的AI编程工具&#xff0c;Cursor正在重新定义开发者与代码交互的方式。动态上下文管理是Cursor区别于传统IDE的核心竞争力&#xff0c;它解决了大型语言模型(LLM)在编程场景中的关键瓶颈——上下文窗口限制问题。在实际开发中&am…

作者头像 李华
网站建设 2026/9/13 23:10:52

质量属性之可用性(Availability)

可用性的定义 可用性是指当你需要它时&#xff0c;它就在那里&#xff0c;随时准备执行任务。可用性建立在可靠性概念的基础上&#xff0c;增加了恢复的概念。可用性和可靠性的区别。 可靠性关注“多久坏一次”&#xff0c;可用性关注“坏了多久能修好”此时能不能用。 对比维…

作者头像 李华
网站建设 2026/9/13 23:09:13

c++并发--同步

1.std::condition_variable&#xff08;条件变量&#xff09; 1.1.核心作用 条件变量用于线程间等待某个条件成立&#xff0c;配合 std::mutex 使用&#xff0c;解决"忙等"问题。 1.2.为什么需要它&#xff1f; 不用条件变量的经典错误写法&#xff1a; // 错误&…

作者头像 李华