
UnoCSS Preflights 配置指南注入全局原始 CSS 与主题联动实战【免费下载链接】unocssThe instant on-demand atomic CSS engine.项目地址: https://gitcode.com/GitHub_Trending/un/unocssUnoCSS 的preflights预检样式机制允许你在配置文件中直接注入原始 CSS例如全局 Reset、字体声明与基础样式。本指南以 docs/config/preflights.md 为核心结合unocss/core的源码实现讲解 preflights 的定义方式、与theme主题对象的联动、layer 分层机制以及它如何与 preset 内置 preflights 协同工作。读完本文你将能够写出类型安全、可被处理器加工、且能与 UnoCSS 分层体系深度整合的自定义 preflight 配置。什么是 PreflightPreflight 是 UnoCSS 在生成最终 CSS 时无条件注入的一段原始 CSS 文本。它与按需提取的原子类utilities不同原子类只有出现在源码中才会被生成而 preflight 不受提取过程约束配置了就会输出。在 packages-engine/core/src/types.ts 中preflight 的类型定义非常简洁export interface PreflightTheme extends object object { getCSS: (context: PreflightContextTheme) Promisestring | undefined | string | undefined layer?: string }getCSS返回要注入的 CSS 字符串支持同步或异步返回Promise也允许返回undefined表示本次不注入layer可选指定该 preflight 归属的 CSS 层默认值为preflights见 packages-engine/core/src/constants.ts 的LAYER_PREFLIGHTS。PreflightContext继承自BaseContextpackages-engine/core/src/types.ts提供两个关键成员export interface BaseContextTheme extends object object { generator: UnoGeneratorTheme // UnoCSS 生成器实例 theme: Theme // 解析完成后的主题对象 } export interface PreflightContextTheme extends object object extends BaseContextTheme { }也就是说每个 preflight 的getCSS都能拿到已经合并解析完成的theme与生成器实例这让 preflight 可以完全基于主题变量生成动态 CSS。在配置中定义 Preflight官方文档给出的最小用法是在uno.config.ts或任意支持UserConfig的配置入口的preflights数组中注册一个对象// uno.config.ts import { defineConfig } from unocss export default defineConfig({ preflights: [ { getCSS: ({ theme }) * { color: ${theme.colors.gray?.[700] ?? #333}; padding: 0; margin: 0; } , }, ], })这段配置的作用通过解构PreflightContext拿到解析后的theme使用可选链theme.colors.gray?.[700]安全取值取不到时回退到#333保证配置在主题缺失时也不会抛错注入一条通配选择器规则将全局颜色、内边距、外边距统一初始化。由于theme来自 packages-engine/core/src/config.ts 中mergeThemes(...)合并各 preset 主题的结果因此你可以在 preflight 中引用theme.colors、theme.fontFamily、theme.breakpoints等任意已注册的主题键实现主题驱动的全局样式。关于类型Preflight是一个泛型接口Theme extends object。当你使用defineConfigTheme()声明了自定义主题类型后getCSS回调中的theme会自动获得对应的 TypeScript 类型提示从而在编写theme.colors.gray[700]这类访问时获得编译期检查。底层执行流程preflight 如何进入最终 CSS了解配置写法后再看 packages-engine/core/src/generator.ts 中 preflight 的生成逻辑可以更清楚它的行为边界const preflightContext: PreflightContextTheme { generator: this, theme: this.config.theme, } const preflightLayerSet new Setstring([]) this.config.preflights.forEach(({ layer LAYER_PREFLIGHTS }) { layerSet.add(layer) preflightLayerSet.add(layer) }) preflightsMap Object.fromEntries( await Promise.all(Array.from(preflightLayerSet).map( async (layer) { const preflights await Promise.all( this.config.preflights .filter(i (i.layer || LAYER_PREFLIGHTS) layer) .map(async i await i.getCSS(preflightContext)), ) const css preflights .filter(Boolean) .join(nl) return [layer, css] }, )), )从这段源码可以归纳出几个重要事实按层分组、并行执行所有 preflight 会先按layer分组同一层内的多个 preflight 通过Promise.all并行调用getCSS再按声明顺序拼接结果过滤返回undefined、空字符串等 falsy 值的 preflight 会被.filter(Boolean)剔除不会污染输出默认层为preflights未指定layer的 preflight 归入preflights层注入位置在getRawLayer中preflight CSS 会被拼接到对应 layer 的规则之前packages-engine/core/src/generator.ts因此 preflight 优先于同层 utility 输出可关闭生成时传入GenerateOptions.preflights false可整体跳过 preflightpackages-engine/core/src/generator.ts。此外GenerateResult还支持preflights?: booleanpackages-engine/core/src/types.ts用于单独控制生成结果中是否携带 preflight 部分。多 preflight 与 layer 定制preflights是数组可以注册多个条目配合layer字段你可以把全局样式放进自定义层再通过layers配置控制层间顺序export default defineConfig({ preflights: [ { // 未指定 layer归入默认 preflights 层 getCSS: () * { box-sizing: border-box; } , }, { // 放入自定义层配合 layers 排序 layer: base-styles, getCSS: ({ theme }) body { font-family: ${theme.fontFamily?.sans ?? system-ui, sans-serif}; line-height: 1.5; } , }, ], layers: { base: -10, // 数字越小越靠前 preflights: -5, base-styles: 0, default: 1, }, })层级排序由sortLayers完成packages-engine/core/src/generator.ts其逻辑是先按config.layers[layer]的数字排序数字相同的再按名称的字典序排列。合理设置层号可以精确控制 preflight 与 utilities、shortcuts 的覆盖关系。Preset 内置 Preflight全局 Reset 的来龙去脉很多 preset 本身就是通过preflights机制注入基础样式的。最典型的例子是preset-mini的 Resetpackages-presets/preset-mini/src/preflights.tsexport function preflights(options: PresetMiniOptions): PreflightTheme[] | undefined { if (options.preflight) { return [ { layer: preflights, getCSS({ theme, generator }) { if (theme.preflightBase) { let entries Object.entries(theme.preflightBase) if (options.preflight on-demand) { const keys new Set(Array.from(generator.getActivatedRules()).map(r r[2]?.custom?.preflightKeys).filter(Boolean).flat()) entries entries.filter(([k]) keys.has(k)) } // ... const roots toArray(theme.preflightRoot ?? [*,::before,::after, ::backdrop]) return roots.map(root ${root}{${css}}).join() } }, }, ] } }从中可以看到几个值得借鉴的实战点preflight 可以读取generatoron-demand模式通过generator.getActivatedRules()获取当前激活的规则只输出这些规则真正用到的 reset 片段实现按需 reset主题控制输出theme.preflightBase决定注入哪些声明theme.preflightRoot决定选择器根默认*,::before,::after与::backdrop可开关通过presetMini({ preflight: false })即可关闭该 preset 自带的 reset详见 preset-mini 配置文档。同样地preset-web-fonts也通过preflights注入import与font-facepackages-presets/preset-web-fonts/src/preset.tspreset-wind4同样在入口处注册了自己的 preflightspackages-presets/preset-wind4/src/index.ts。这说明 preflights 是 UnoCSS 生态中注入非原子类全局样式的通用通道。异步 Preflight 与预处理管线getCSS支持返回Promise这一点对需要远程获取数据的场景非常关键。preset-web-fonts的getCSSDefault内部就大量使用异步逻辑先并行收集各 provider 的import与font-face再.join(\n)拼成一段完整 CSSpackages-presets/preset-web-fonts/src/preset.ts并且 fetch 失败时会输出警告而非中断整个构建。自定义异步 preflight 的示例export default defineConfig({ preflights: [ { async getCSS() { const css await fetchSomeRemoteStylesheet() return css }, }, ], })此外preflight 注入的 CSS 会像普通规则一样进入统一的层处理管线若配置了processors生成的每一层 CSS 都会按order依次经过处理packages-engine/core/src/generator.ts若开启outputToCssLayerspreflight 层还会被包装进 CSSlayerpackages-engine/core/src/generator.ts。因此 preflight 并不是旁路文本而是完整参与 UnoCSS 的分层与后处理体系的。最佳实践小结优先复用 preset 的 Reset默认presetMini/presetWind3已通过 preflight 提供 Reset只有需要定制时才用preflight: false关闭后自行定义参考 style-reset 指南善用theme兜底在getCSS中访问主题时始终提供回退值如?? #333避免主题缺键导致生成崩溃用layer控制覆盖顺序全局基础样式放入靠前的层让 utilities 默认能覆盖它注意on-demand模式需要按需输出 reset 时可读取generator.getActivatedRules()过滤未用到的声明如 packages-presets/preset-mini/src/preflights.ts 所示异步内容集中管理远程字体、远程样式等异步 preflight 应做好失败兜底与缓存避免每次生成都重复请求。Preflight 是 UnoCSS 配置体系中全局样式的标准入口配合主题、分层与处理器它足以覆盖 Reset、字体、CSS 变量初始化、自定义全局样式等绝大多数场景。结合 docs/config/preflights.md、preflights 相关源码 与 preset-mini 的 preflight 实现 一起阅读可以完整掌握从配置到产出的全链路。【免费下载链接】unocssThe instant on-demand atomic CSS engine.项目地址: https://gitcode.com/GitHub_Trending/un/unocss创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考