跳到主要内容

认识

2025年01月03日
柏拉文
越努力,越幸运

一、认识


UnoCSS 是一个轻量级、高性能、按需生成的原子 CSS 框架,旨在为前端开发提供快速、灵活的样式解决方案。它的核心理念是 原子化(atomic,意味着每个 CSS 类只应用单一的样式属性。UnoCSS 的设计目标是提供极致的性能,同时保持高度的可定制性和灵活性。

UnoCSS 受到了许多现代工具和框架(如 Tailwind CSS)启发,但它在设计上更注重极简主义和灵活性。与 Tailwind CSS 不同,UnoCSS 是按需生成类名的,这意味着它只会生成你实际使用的类,从而减小了 CSS 文件的大小。

二、特点


  1. 按需生成UnoCSS 只会根据你实际使用的类生成 CSS 样式,而不会像传统的 CSS 框架那样加载大量的预定义类。因此,它能极大地减小最终的 CSS 文件大小。

  2. 高度可定制性: UnoCSS 提供了非常灵活的配置系统,你可以通过配置文件来调整类名、颜色、间距等各类样式的规则,甚至可以定义自己的类名或自定义功能。

  3. 原子化设计UnoCSS 的设计灵感来自原子 CSS,意味着每个类名都对应一个单一的 CSS 属性,例如 .m-44px 的外边距),.text-red(红色文本),.bg-blue(蓝色背景)等。

  4. 快速生成和低运行时开销UnoCSS 在构建时通过预生成和按需生成机制来减少运行时的性能开销,减少了样式计算的时间,特别适用于大规模项目。

  5. 轻量和快速UnoCSS 的核心非常小,且由于按需生成 CSS,它非常适合性能要求高的前端项目,特别是当你希望通过细粒度控制来提高性能时。

  6. 与现有工具链兼容UnoCSS 可以与现有的开发工具(如 ViteWebpackVueReact 等)无缝集成。它还支持与其他工具(如 PostCSSTailwind CSSCSS-in-JS 等)共存。

  7. 支持类型推导: UnoCSS 提供了 TypeScript 类型支持,能帮助开发者避免样式上的拼写错误,并且提供自动补全功能。

三、对比


3.1 UnoCSS Vs Tailwind CSS

Css 原子化方案其实有很多, 关注比较多的有 TailwindUnoCss,他们都支持按需生成 Css,都提供响应式,可以定制预设,并支持主题化和暗盒模式。但是 Tailwind 是重量级的,更注重定义系统,它提供了全面的预设样式,大部分在我们项目中是用不到的。强约束比较多,配置项也比较多,另外 Tailwind 会经过 PostCss , 本质上 TailwindPostcss 插件。而我们的 UnoCss 非常灵活,通过在项目根目录下使用 JavaScript 灵活定义规则, 可以使用正则和函数,还有更加复杂的逻辑和条件判断。另外多个规则也可以组合成一个快捷键。UnoCSS 是一个同构引擎, 可以灵活的在不同的地方使用, 可以作为 Webpack Plugin 动态生成 Css 文件。只依赖于 css-loaderstyle-loader 或者 MiniCssExtractPlugin 等。UnoCss 直接操作字符串,不会转换成 AST,也不需要在内存中保存 AST 结构,所以 UnoCss 会比 Tailwind 构建编译更快,而且在多次构建之间复用生成的样式,增量编译很快。

四、工作


UnoCss 工作机制:

  1. 类名扫描(类名提取)UnoCSS 在构建时通过扫描项目中的代码(HTMLJSTSVueReact 等),提取出所有实际使用到的 CSS 类名。UnoCSS 会扫描你项目中的源代码,识别出所有的类名,并构建出一个类名-样式的映射。

  2. 样式生成: 根据扫描到的类名,UnoCSS 会从预定义的规则中生成最小的 CSS 文件。生成的 CSS 只包含被实际使用的类和属性,避免了传统 CSS 框架中的冗余样式。UnoCSS 通过一套精密的规则生成最小化的样式表,这意味着不需要生成所有可能的类,只生成实际用到的类。

  3. 即时生成(按需生成)UnoCSS 是一个按需生成的 CSS 框架。即使项目中存在很多潜在的 CSS 类,UnoCSS 只生成当前项目中被实际使用的类的 CSS。这个特性保证了最终的输出非常精简。

  4. 不依赖 AST 转换UnoCSS 的设计不依赖于传统的 AST(抽象语法树)转换。AST 转换通常是在工具(如 PostCSSBabel 等)中对源码进行语法解析和抽象,进而进行优化、压缩等处理。UnoCSS 不需要这一过程,因为它是基于类名匹配规则来生成样式的,而不是通过对整个 CSS 文件进行分析和转换。这使得 UnoCSS 具有非常高的性能,因为它可以直接根据类名生成规则,而不需要做复杂的 AST 操作。

注意: 我们在 Webpack/Rspack 中通过 css-loader/style-loader 处理的是入口文件显示引入的 uno.css 文件,而不是基于扫描到的类名动态生成的 Css 文件。

Webpack UnoCss 工作机制: 基于 compilation.hooks.processAssets(Webpack 4)compilation.hooks.optimizeAssets(5、6) Webpack 产物优化处理阶段, 等待 UnoCss 完成初始化后, 进行类名扫描,生成样式,随后遍历 Webpack 文件列表, 根据占位符替换成生成的样式,并重新生成源映射(SourceMap) 。也就是说: 在 Webpack 中, 基于扫描到的类名动态生成的样式会直接插入到 Webpack 最终的产物中。