SDTTTTT

2026-10-26

维护记录

完成的工作

  • 工具链从 Bun 迁回 Node 24 + pnpm + vitest(2026-07 才从 Deno 迁到 Bun,这次是反向)✅
    • scripts/*.ts 改为 Node 原生类型剥离直接执行:package.json 的 scripts 全换成 node scripts/xxx.ts,相对导入统一改写成带 .ts 后缀的真文件名,shebang 改为 #!/usr/bin/env node
    • 单测从 node:test + 自制的 scripts/__tests__/expect.ts 换成 vitest:运行器、expect、mock(vi.fn / vi.restoreAllMocks)全部来自 vitest,expect.ts 删除;新增 vitest.config.ts,把 pool 钉成 forks
    • 包管理换成 pnpm:删除根与 themes/self/ 的 bun.lock,生成 pnpm-lock.yaml;bin/*.sh、bin/hooks/* 里的 bun run / bun install / require_bun 一并改写
    • CI 四个 workflow 的 oven-sh/setup-bun 换成 pnpm/action-setup + actions/setup-node(Node 24),test-scripts.yml 补上 pnpm install 步骤
    • 新增 tsconfig.json(noEmit + allowImportingTsExtensions + erasableSyntaxOnly),最初只服务编辑器与 vitest,当天晚些时候接上了真正的类型检查(见下一条)
  • 加上 typescript 依赖与 pnpm run typecheck,并接进 CI ✅
    • 用 TypeScript 7.0.2(Go 原生编译器),全项目 16 个 scripts/** 文件 tsc --noEmit 只要 0.26 秒,接进 preflight 的成本可以忽略
    • 第一次跑就是 0 个类型错误(strict + noUncheckedIndexedAccess 全开)——为防止「检查了但什么都没看」,特意往 scripts/lib/paths.ts 注入一行 const __probe: number = 'string' 验证 tsc 会报错,确认后还原
    • bin/preflight.sh 从五步变六步(类型检查插在 front matter 之后、单测之前),bin/test.sh 也加了同一步;CI 的 deploy 与 test-scripts 两条链路都会跑
  • 产物零漂移:uno.css 用 pnpm + unocss 66.11.0 重新生成后与原产物逐字节一致;particles.wasm 重编译后同样逐字节一致,两个指纹文件按新源文件重新登记 ✅
  • 文档同步:README.md、AGENTS.md、themes/self/README.md、hugo.toml、particles.html 与 Rust 注释里的 bun 引用全部改为 pnpm / Node

遇到的问题

  • Node 不做 .js → .ts 的导入映射 ⚠️ - 原来 import './lib/args.js' 在 Bun 下能解析到 args.ts,Node 直接 ERR_MODULE_NOT_FOUND。批量改成 .ts 后缀后解决,同时这也逼出 tsconfig.json 需要开 allowImportingTsExtensions。
  • pnpm add --no-save 不存在 ⚠️ - optimize-images 原来靠 bun add --no-save sharp 装临时依赖而不改清单。pnpm 明确不支持该选项(ERR_PNPM_OPTION_NOT_SUPPORTED),文档改成 pnpm add -D sharp@0.33.5 + 用完 pnpm remove sharp,并注明这两处改动别提交。
  • unocss 的 ^66.11.0 会解析出新版本 ⚠️ - 迁移时会重新解析成 66.12.0,产物字节可能变化。把 themes/self/package.json 的三个 unocss 包钉成精确的 66.11.0,重新生成后与原产物逐字节一致。
  • 测试里的 process.chdir() 不能在 worker 线程跑 ⚠️ - temp-dir.ts 的 inTempDir 会切工作目录,worker_threads 下抛 ERR_WORKER_UNSUPPORTED_OPERATION。vitest.config.ts 显式写 pool: 'forks'(虽是默认值,但这是有原因的,不能让人随手改掉)。
  • import.meta.main 不用改 ✅ - 这是脚本里唯一的 Bun 专有 API,Node 24.2+ 已原生提供,实测可用。

下次建议

  • 类型检查目前只覆盖 scripts/**(tsconfig.json 的 include)。以后若把 bin/ 里的 shell 逻辑搬进 TypeScript,记得同步扩 include,否则新文件会被静默漏掉。
  • themes/self/ 与根各有一份 pnpm-lock.yaml。若以后还想省事,可以考虑改成 pnpm workspace,但要注意 UnoCSS 产物对解析结果的敏感性。