維護記錄#
完成的工作#
- 應用戶要求,把 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 xxx 或 deno 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.json 配 unstable: ["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.yml 裡 format-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.json、deno.lock - 刪除:
package.json、package-lock.json、tsconfig.scripts.json、scripts/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 行改動