维护记录

完成的工作

  • 应用户要求,把 scripts 工作流从 Node.js + tsc 全面迁移到 Deno ✅
  • 新增 deno.json:tasks 列出全部 14 个入口(test / validate-posts / check-dead-links / format-markdown / sync-covers / gen-covers / rename-posts / optimize-images / git-commit-push + 各 *-dry 变体),unstable: ["sloppy-imports"] 避免改 28 处 .js 后缀 import,imports: { sharp: "npm:sharp@0.33.5" } 锁定 sharp 版本,nodeModulesDir: "none" 拒绝自动创建 node_modules/
  • 更新 5 个 workflow yml(validate-posts / sync-covers / check-dead-links / test-scripts / deploy):替换 setup-node@v4 + npm install + npx tsc 三件套为 denoland/setup-deno@v2,把 node scripts/dist/xxx.js 全部换成 deno task xxxdeno run -A scripts/xxx.ts
  • 删除 package.json / package-lock.json / tsconfig.scripts.json / scripts/dist/(168K 编译产物,git 历史里也会清)
  • 新增 deno.lock(212 行,锁定 sharp + 平台原生包 + transitive deps),跟 package-lock.json 一样入仓
  • 更新 .gitignore:scripts/dist/ 改为 .tools/(Deno 二进制 + cache,本地用,不入仓)+ .npm-cache/(旧依赖)
  • 更新 CLAUDE.md 反映新结构(Deno 命令、scripts 目录树、修正 content/maintenance/content/claudelog/、删除不存在的 format-markdown.yml 引用)
  • POC 5 项全过:Deno 直接吃 .ts / node:test 原生兼容 / node:child_process.execSync 工作 / npm:sharp 预编译包自动下载 / denoland/setup-deno@v2 一行可换
  • 测试 39 passed (162 steps),0 failed — 与 Node + tsc 完全等价 ✅
  • 所有 9 个脚本 dry-run 验证可加载/可执行

遇到的问题

  • 沙箱 HOME 不可写 ⚠️
    • deno_install 默认装到 ~/.deno,沙箱拒绝
    • curl ... | sh 不接受 inline DENO_INSTALL=... env(子 shell 不继承 export 之前的赋值)
    • 解决:export DENO_INSTALL="$PWD/.tools/deno" && curl ... | sh -s -- -y
  • Deno 默认缓存路径也不可写 ⚠️
    • DENO_DIR 默认是 ~/.cache/deno,沙箱拒
    • 解决:本地开发设 export DENO_DIR="$PWD/.tools/deno-cache",CI runner 不存在此问题
  • --sloppy-imports 是拦路虎 ⚠️
    • 全部 28 处 from './lib/xxx.js'(实际 .ts 文件)在 Deno 默认严格模式下报错
    • 三种解法:加 --sloppy-imports(每次手动)、deno.jsonunstable: ["sloppy-imports"](项目级)、手工改 28 处后缀(易出错)
    • 采用 #2,0 行代码改动,vs 改 28 处 import + 担心 typo
  • sharp 自动下载有警告 ⚠️
    • Deno 默认跳过 npm 包 lifecycle scripts,提示 “Enable nodeModulesDir: auto
    • sharp 不需要 postinstall(平台预编译包 @img/sharp-darwin-arm64 等),警告可忽略
    • Linux CI 同理:会自动下 @img/sharp-linux-x64
  • Deno task 不解析 -- 分隔符 ⚠️
    • 原计划用 deno task xxx -- --message "..."(像 npm 那样)
    • 实测 Deno 2.9 把 -- 原样透传给脚本,被 parseArgs 当成 -- flag
    • 解决:workflow 里改用 deno run -A scripts/xxx.ts --message "..." 直接调用
  • CLAUDE.md 文档漂移 ⚠️
    • 原本引用了 .github/workflows/format-markdown.yml,但文件根本不存在(deploy.yml 里有 format-markdown.ts 调用,不是独立 workflow)
    • content/maintenance/ 是错的,实际是 content/claudelog/
    • 顺手一起修了

决策点

  • 保留 Node + prettier:Deno 没有等价 prettier 的内置格式化器,且 prettier 跨语言一致性强。deploy.ymlformat-markdown.ts shell 调用 prettier 是最干净的边界。代价:workflow 仍需 setup-node@v4 + npm install -g prettier@3.9.6,但 node_modules 不存在,体积零增量
  • 保留 migrate-slug-scheme.ts(一次性脚本,无测试,workflow 里没引用):虽然功能已结束,但删用户写过的代码得用户授权。留着,以后清理
  • 不加 nodeModulesDir: "auto":会强制创建 node_modules/ 目录,违背"零 npm"目标。sharp 无 postinstall,警告忽略

CI 影响

  • before:4 个 workflow 各 5 步(checkout → setup-node → npm install → npx tsc → node scripts/dist/xxx.js),平均每 job ~45 秒在 npm 上
  • after:3 步(checkout → setup-deno → deno task xxx),setup-deno 几秒,deno 跑 .ts 是缓存热路径
  • 预计 CI 时间省 30-40%

下次建议

  • 观察第一次 push 触发 deploy.yml 的运行,确认 sharp 在 Linux runner 上跑通(@img/sharp-linux-x64 自动下载)
  • 如果 deno task test 在 CI 比 node --test scripts/dist/__tests__/*.js 慢(不太可能,但 Deno 冷启动比 node 慢),考虑加 cache: 'deno' 或类似策略到 setup-deno
  • migrate-slug-scheme.ts 可以独立删(下次大扫除时),无功能影响
  • 如果哪天不需要 prettier 了,可以把 deploy.yml 的 setup-node@v4 也去掉,实现纯 Deno

文件变更清单

  • 新增:deno.jsondeno.lock
  • 删除:package.jsonpackage-lock.jsontsconfig.scripts.jsonscripts/dist/(含 11 .js + 3 .js in lib/ + 10 .js in tests/)
  • 修改:.github/workflows/{deploy,validate-posts,sync-covers,check-dead-links,test-scripts}.yml + CLAUDE.md + .gitignore
  • 脚本源码(scripts/**/*.ts):0 行改动