SDTTTTT

2026-10-24

维护记录

完成的工作

  • 把 CSS 管线从 Tailwind v4 迁到 UnoCSS(@unocss/postcss 66.11.0):package.json 换掉 @tailwindcss/* 与 tailwindcss,新增 unocss / @unocss/postcss / @unocss/preset-wind4 / @unocss/preset-typography,bun.lock 重新生成;postcss.config.mjs 用 UnoCSS() 取代 tailwindcss(),postcss-preset-env 保留 ✅
  • 新增 themes/self/uno.config.ts:presetWind4() + presetTypography(),扫描范围显式限定为 layouts/**/*.html —— 从此 README.md、i18n/*.yaml、上一版 main.css 都不再进产物 ✅
  • assets/app.css:@import 'tailwindcss' / @plugin / @custom-variant / @theme / @utility dark-bg 改成 @unocss all; + :root { --w } + 内联的 dark:before:… 工具链;bg-(--tw-prose-pre-bg) 改成 bg-[--un-prose-pre-bg] ✅
  • 模板里 5 处 Tailwind v4 的 CSS 变量简写改成方括号写法:max-w-(--w) → max-w-[--w](3 处)、bg-(--bg) → bg-[--bg](2 处)✅
  • 迁移中补上的两处行为差异:① 标题字重 —— UnoCSS 不再有 :not(#\#) 特异性炸弹,typography 的 .prose h1/h2(800 / 700)会压过 h1,h2,h3 { font-weight: 600 },改成带 .prose 前缀的规则压回去;② before: 变体不再自动补 content,body / .nav-wrapper 的暗色遮罩显式加了 dark:before:content-[''],否则伪元素压根不渲染 ✅
  • 修掉一个构建可复现性问题:UnoCSS 的主题变量按需发射、扫描又是并发的,同一份源连编两次变量块的顺序会抖(字节不同 ⇒ 指纹永远对不上)。postcss.config.mjs 加了一个 20 行的本地插件,把 :root 里的声明按属性名排序钉死顺序;试过 preflights.theme: true(稳定但产物 68.7KB / gzip 13KB,比 Tailwind 还大)所以放弃。现在连编三次 main.css 的 sha256 完全一致 ✅
  • 文档与脚本同步:AGENTS.md(管线、扫描范围、踩坑清单、命令注释)、themes/self/README.md(「The CSS pipeline (UnoCSS)」一节 + 历史条目)、bin/build-css.sh / bin/artifacts.sh / bin/lib.sh 的注释与提示文案 ✅

验证

  • 迁移前对首页 / 文章页(浅色 + 深色)/ 归档页 / 首页 375 宽抓了计算样式基线(字体、字重、行高、颜色、margin、padding、display、盒子尺寸),迁移后逐项 diff:只有两类差异 —— ① 颜色序列化从 rgb(...) 变成 oklab(...),用 canvas 取像素验证 oklab(0.978733 …) 就是 (250, 248, 241),逐像素一致;② .home-title 的行高从 106.667px 变 105.6px(Tailwind 时代 typography 的 line-height: 1.1111 压过了 custom.css 的 1.1,UnoCSS 下后者终于生效),1px 的差别,页面总高 1477 → 1476 ✅
  • 暗色伪元素逐项核对(375 与 1280 两档):body::before fixed / inset 0 / z -1 / 黑 85%,.nav-wrapper::before 在移动端 absolute、在桌面 display: none,与 Tailwind 的展开一致 ✅
  • 首页 hero 粒子照常:状态 wasm、2667 颗粒子、step 3 / 边长 2,画布 1360×250(行高差 1px 导致画布矮 2 设备 px)✅
  • 产物对比:main.css(未压缩)58,032 → 42,342 字节;但把 custom.css 一起 concat + minify 之后的实际发布文件几乎没变(58,123 → 58,060 字节,gzip 8,927 → 8,920)—— 换引擎换来的是可维护性,不是体积。./bin/preflight.sh 五步全绿,./bin/build.sh 生产构建正常 ✅

遇到的问题

  • UnoCSS 的 @unocss/postcss 插件官方标注 experimental、不跟 semver —— 升级 UnoCSS 时要盯一下 main.css 的字节变化,artifacts.sh check 会把差异摆在明面上 ⚠️ - 已在 README 里写明这条约束。
  • UnoCSS 的 shortcut 展开不了带变体的工具链(dark:before:*),dark-bg 只能内联成 @apply 或者手写规则 ⚠️ - 现在直接写进 body / .nav-wrapper 的 @apply,并留了注释解释原因。
  • 构建不可复现(见上)—— 根因是 on-demand 主题变量 + 并发扫描 ⚠️ - 用 PostCSS 插件排序;theme: true 虽然也稳定但体积翻倍,不划算。

下次建议

  • 如果以后要在 JS 里拼工具类,记得把 assets/js 加进 uno.config.ts 的 content.filesystem,否则类名不会被生成(Tailwind 时代是整目录扫描,不会有这个问题)。
  • bin/artifacts.sh 的 CSS 指纹仍覆盖整个主题目录(宁可多报)。若觉得 README 改动也要重跑 build-css 太啰嗦,可以把 css_sources 收窄到 assets/app.css + layouts/** + uno.config.ts + package.json + bun.lock + postcss.config.mjs,但要先确认没有别的输入。
  • custom.css 里那些为 :not(#\#) 炸弹准备的 !important 现在大多是多余的,可以逐条验证后删掉(本次没动,避免把迁移和清理搅在一起)。

当日二次调整:去掉 PostCSS(unocss CLI 直接生成)

用户评估后决定不再依赖 PostCSS,改为「CLI 生成 + 普通 CSS」。上面那节的 @unocss/postcss 管线已废弃,保留作为过程记录。

完成的工作

  • bin/build-css.sh 改为 bun install --frozen-lockfile → unocss 'layouts/**/*.html' -o assets/uno.css → artifacts.sh stamp-css;产物从 assets/main.css 换成 assets/uno.css(30,670 字节),指纹同步改名 ✅
  • 删除 postcss.config.mjs 与 postcss / postcss-cli / postcss-preset-env / @unocss/postcss,连同自写的 sortThemeVariables() 插件;bun.lock 重新生成(少 4 个包)✅
  • assets/app.css 改写成普通 CSS:去掉 @unocss all; 与全部 28 处 @apply,规则展开成 12 个块,颜色 / 圆角 / 间距一律写字面量 ✅
  • layouts/partials/head.html 改成 slice $uno $app $custom | resources.Concat "main.css" | minify | fingerprint,顺序即层叠顺序 ✅
  • bin/lib.sh / bin/artifacts.sh 同步:产物路径、--rebuild 校验(改成重跑 CLI 再 cmp)、失败提示文案 ✅
  • 文档同步:AGENTS.md、themes/self/README.md(含 History)、uno.config.ts 头注释 ✅

为什么要写字面量

  • UnoCSS 的主题变量按需发射 —— 模板没用过的 token(--radius-md、--fontWeight-semibold)压根不在产物里。第一版 app.css 用 var() 引用它们,实测标题字重退回 400、代码块圆角退回 0;改成 600 / 0.375rem 后与旧版逐项一致 ✅

验证

  • 改造前后各抓一遍计算样式基线:首页、文章页 ×2、归档页、搜索页(1280×800)+ 归档页(800×800)+ 首页(375×800),明暗双模式共 7 组。颜色(oklch / oklab → sRGB)与字体栈归一化后差异为 0,盒子位置与尺寸逐项一致 ✅
  • 补查基线未覆盖的部分:暗色 body::before(fixed / inset 0 / 黑 85%)、.nav-wrapper::before 桌面端 display: none、汉堡按钮展开态(rotate 45deg / translate 0 6px)、代码块 pre 圆角 6px ✅
  • ./bin/preflight.sh 五步全绿;./bin/artifacts.sh check --rebuild 重新生成后逐字节一致(CLI 连跑 5 次哈希不变)✅
  • 体积:uno.css 30,670 + app.css 4,454 + custom.css 15,711,minify 后发布文件 38,009 字节(PostCSS 版 44,634);顺带清掉旧产物里 13 处把 @property 描述符漏进规则体的脏声明(syntax:"*";inherits:false;…)✅

遇到的问题

  • unocss CLI 不读输入 CSS,@apply 彻底不可用;试过独立调用 transformer-directives,它接收 MagicString、会顺带发射 @property,还有 5 处 @apply 解析不掉 —— 内部 API,不可靠 ⚠️ - 放弃,改写普通 CSS。
  • Hugo dev server 在模板首次渲染时 resources.Get "uno.css" 仍是 nil,把这次 miss 缓存住了,之后重建一直报 resources.Concat: expected slice of Resource objects ⚠️ - 重启 hugo server 即可;生产构建 hugo --minify 一直是好的。
  • public/ 里残留大量历史 main.min.*.css,容易看错文件 ⚠️ - 以 public/index.html 实际引用的哈希为准。