主題: Cloudflare
綠色 Build 不等於已上線:Astro 靜態站的發佈驗證紀錄
從這個 Astro 部落格出發,拆開本機檢查能證明什麼、不能證明什麼,以及 static assets 如何進到 Cloudflare Worker。
看到 pnpm build 綠燈後,就把一篇技術文章叫做「已發布」,很誘人。這個感覺也不完全錯:頁面 render 了、MDX parse 了,dist 也產生了。
但證據還差一段。
這篇記錄本站採用的發佈邊界。它不是 benchmark,也不會因為本機指令成功就聲稱 production 已更新。這個差別平常聽起來像吹毛求疵,直到 stale deployment、錯 branch 或 asset path 出錯,讓本機完全正確的頁面根本沒被讀者看見。
我正在驗證的發佈形狀
這個 repo 的 release path 很窄:
{
"deploy": "pnpm build && wrangler deploy"
}
Wrangler 設定把 static assets 指向 build output:
{
"assets": {
"directory": "./dist"
}
}
Cloudflare 會把設定的 assets directory 當成 Worker deployment 的一部分上傳,再將檔案送給讀者。因此 dist 是必要 artifact,卻仍只是本機檔案,直到 Wrangler 成功部署為止。正確的 static-site workflow 必須拆成兩個問題:build 有沒有產出正確檔案?與live domain 是否正在送出這批檔案?
這次驗證了什麼
在 2026-08-10 的內容更新中,我先跑三個檢查才把 source 視為 ready:
pnpm lint
pnpm build
pnpm seo:check
每個指令回答的問題不同:
| 檢查 | 能提供的證據 | 不能提供的證據 |
|---|---|---|
pnpm lint |
編輯到的 Astro、TypeScript 與 MDX 相鄰 source 通過既有 lint 規則。 | 頁面已 build 或已 deploy。 |
pnpm build |
Astro 可 render routes 並產生 dist。 |
production Worker 已收到這份 dist。 |
pnpm seo:check |
已建好的 sitemap、canonical URL、hreflang、JSON-LD 與 route assertion 符合本站規則。 | 搜尋引擎已 crawl 或 rank 這項更新。 |
這個拆分修正了我自己的 release 用語:local valid 與 live 不是同義詞。本機 build 後正確的交接是 ready to deploy,不是 deployed。
先看 build 出來的證據,再打開 dashboard
第一輪 inspection 不需要 browser automation:
test -f dist/sitemap.xml
test -f dist/robots.txt
rg 'static-astro-release-evidence' dist/en dist/zh-TW
前兩個指令確認 crawler entry points 已生成;最後一個確認新 field note 的雙語版本都進入 static output。這是一個便宜卻重要的檢查:MDX 檔名或 locale suffix 打錯時,很容易誤以為是內容問題,其實 route 根本不存在。
在獲得授權並完成部署後,live check 是另一個步驟:
curl -fsSI https://tech-blog.hungchihsueh.com/en/
curl -fsS https://tech-blog.hungchihsueh.com/sitemap.xml | xmllint --noout -
第一個指令確認已發布的 route 有回應;第二個驗證 live sitemap XML。兩者都不能保證每位讀者都已穿透每一層 cache 看見新版本,但證據強度遠高於只看本機 dist。
取捨與失敗模式
這個 static setup 刻意讓 runtime 很小:MDX 在 build 時變成 HTML,Worker 只送 assets。一般文章閱讀因此沒有 database call 或 server rendering。代價是內容變更一定要 build 與 deployment;不存在一個隱藏 CMS write 可以讓 production 自己變新。
有三種 failure mode 值得直接寫出來,因為它們很容易導向信心滿滿卻錯誤的狀態回報:
- 在錯的 branch build。 artifact 合法,卻沒有目標文章。
- build 成功但沒有 deployment。 本機的
dist更新了,live Worker 仍送出舊 assets。 - deployment 漏掉需要的生成檔。 route 雖然能開,
robots.txt、sitemap output 或某個 locale page 可能不見了。
對策同樣很無聊:發布前檢查 branch 與 worktree,跑 build checks,只在獲得授權後 deploy,再測試精確的 live URLs。我寧可保留這條順序,也不想為了它再建一層 release abstraction;這個站已經有能證明每個邊界的指令。
我刻意沒有加入什麼
我沒有為此加入 CMS、release dashboard 或 Container。本站已有 static build output 與 Worker assets directory;增加基礎設施只會多一個要驗證的狀態,卻不會讓證據邊界更清楚。
若未來真的需要排程動態內容或個人化頁面,那是新的需求,值得重新設計。現在則是小清單加上直接 URL,更容易信任,也更容易除錯。