凌晨睡不著,我給颱風巴威寫了一個追蹤網站

> 這是一份寫給開發者、設計師、氣象愛好者的共建指南。

也是一篇碎碎念,關於我為什麼要做這個東西。

倉庫:github.com/Trade-Offf/…
線上:chinaupdated.com


一、緣起

超強颱風「巴威」逼近的那個凌晨,我睡不著。

不是因為怕,是白天當了一天牛馬,腦子轉不動了,躺在床上習慣性打開手機,想看看颱風到底什麼情況。結果越刷越亂:

  • 這個博主說「史上最強,千萬別出門」,
  • 那個博主說「沒那麼嚴重,都是標題黨」,
  • 划兩下刷到一條三天前的舊聞,還有人在留言區吵「到底信誰的」。

刷了二十分鐘,我一則消息沒搞清楚,倒是學會了三種「颱風穿搭」和兩首「颱風 BGM」。躺在出租屋的床上,我腦子裡其實只剩三個問題:

  1. 颱風現在在哪、多強?
  2. 離我家還有多久?
  3. 我現在到底該幹嘛?

就這三個問題,翻遍手機裡的軟體,居然沒有一個地方能一次講清楚。

乾脆爬起來,打開電腦,用 Claude Fable 5 把想法一點點敲了出來。把基於中央氣象台、日本氣象廳、美國 JTWC、台灣氣象署四家的路徑資料放在同一張地圖上之後,很多事一眼就看明白了——比如此刻,幾家的預測登陸點正在往溫州附近收斂。

然後順手加了幾樣東西:

  • 即時新聞聚合。比官方資料更快,分散式資料的二次驗證,但不一定準,請自行辨別;
  • 城市波及倒數。大概還有多久,巴威到你所在的城市,基於風速和地圖向量估算的,不一定準;
  • 緊急應變指南和緊急電話。真的到了要用的時候,不用再去搜尋。

這個網站純粹是自己做的:沒有廣告,不收集資料,資料來源全是官方,防災決策請以官方預警為準(不信謠、不傳謠)。

做這個的時候就一個念頭:能讓身邊人早知道一點,心裡也能踏實一點。

如果你有江浙滬的朋友,歡迎轉給 ta。如果你是開發者,往下讀——我會把它怎麼運轉的、哪裡還很粗糙、你能怎麼幫忙,都攤開講清楚。


二、它長什麼樣

先看圖,再聊技術。

打開就是一張會動的地圖

01-overview-city-countdown.png

實測路徑按國標六級強度配色,從深海一路「燒」到近海。左邊掛著一列城市倒數,最緊迫的排最前面。頂上一條預警橫幅,告訴你現在誰最危險。

點一下你關心的城市

02-city-popup.png

鏡頭飛過去,彈出一張小卡片:風圈預計什麼時候到、最近距離多少公里、現在該做什麼。分享連結也幫你想好了——?city=溫州,發給溫州的朋友,打開直接聚焦到 ta 家。

四家機構的預報,擺在一起看

截屏2026-07-07 12.09.07.png

中、日、美、台四家的預報虛線可以獨立開關。預報本來就有分歧,分歧本身就是資訊——四條線收得越攏,說明路徑越確定;散得越開,越要多留個心眼。

新聞和指南,都在手邊

03-news-panel.png

04-guide-panel.png

新聞是媒體視角,比官方報文快,但請自行辨別。指南是靜態內容,從「來臨前 48 小時」寫到「過後安全確認」,緊急電話都列好了——真正慌亂的時刻,沒人有耐心再去搜尋。


三、它是怎麼轉起來的

架構簡單到有點不好意思:一個 Cloudflare Worker,一堆純函數,沒有資料庫,沒有伺服器。

bash 代碼解讀複製代碼┌─────────────────────────────────────────────────────────────┐
│  使用者瀏覽器(MapLibre GL + TypeScript)                       │
│  · 路徑回放 / 風圈動畫 / 城市標記 / HUD / 分享深鏈            │
└──────────────────────────┬──────────────────────────────────┘
                           │ /api/typhoon/:id  /api/news
┌──────────────────────────▼──────────────────────────────────┐
│  Cloudflare Worker(邊緣代理 + 快取 + 容災)                    │
│  · normalize.ts  雙源歸一化                                   │
│  · news.ts        RSS 資訊聚合                                │
│  · 快取:颱風 5 分鐘 / 資訊 10 分鐘                            │
└──────────┬─────────────────────────────┬────────────────────┘
           │                             │
   浙江水利廳 API(主)              Google/Bing News RSS
   中央氣象台 NMC(備)

但簡單是刻意的。災害面前,系統越簡單越可靠。 沒有資料庫可以當機,沒有伺服器需要半夜爬起來重啟,邊緣節點掛了還有下一個。一個防災工具首先要做到的,是它自己別先倒下。

選型時想的也是同一件事:

層級選型為什麼邊緣運算Cloudflare Workers零運維、全球 CDN、國內可訪問前端地圖MapLibre GL開源、靈活,不依賴 Google 底圖高德衛星 + 中文註記國內 CDN 穩,中文標註,合規踏實建置Vite + TypeScript快,且型別兜底資料無資料庫源站回傳全量軌跡,邊緣快取就夠了### 目錄一覽

python 代碼解讀複製代碼worker/
  index.ts       # 路由、邊緣快取、雙源容災
  normalize.ts   # CMA/ZJ 資料 → TyphoonData(純函數)
  news.ts        # RSS 解析、聚合與快照合併(純函數)

src/
  app.ts         # 入口:回放控制、HUD、分享、倒數刷新
  map.ts         # MapLibre 圖層、城市標記、風圈動畫
  impact.ts      # 城市波及倒數演算法(純函數)
  geo.ts         # 球面距離、風圈多邊形、軌跡插值
  guide.ts       # 應對指南內容
  news.ts        # 資訊面板渲染
  mobile.ts      # 行動端版面:頂部實況條 + 底部三檔抽屜
  slogan.ts      # 正能量口號輪播

幾個寫程式時守著的習慣:

  • 資料歸一化和演算法盡量寫成純函數normalize.tsimpact.tsgeo.ts),好測、好複用,出了問題也好定位;
  • 畫圖和動畫都關在 map.ts 裡,業務邏輯不跟渲染糾纏;
  • Worker 只做代理和快取。它越「笨」,越不容易壞。

一個踩過的坑,分享給你

新聞聚合上過一次當。原來的邏輯是每次抓取後覆蓋快取快照——某個時刻 Google 被限流、Bing 恰好只回了 1 則,這份貧瘠的結果就把之前累積的 30 則完整快照沖掉了。使用者打開一看,資訊頁只剩孤零零一則。

修復之後,刷新改成了合併:新條目優先,歷史條目去重補位,七天窗口內只增不減。這個教訓值得寫在這裡:對一個防災工具來說,一次糟糕的抓取,永遠不該毀掉已有的積累。


四、如何上手?

bash 代碼解讀複製代碼git clone [email protected]:Trade-Offf/typhoon-bavi-tracker.git
cd typhoon-bavi-tracker
npm install
npm run dev          # Vite 開發伺服器
npm run typecheck    # TypeScript 檢查
npm run preview      # 建置 + wrangler 本地模擬 Worker

本地 vite dev 時,/api/typhoon 會代理到浙江水利廳介面。想看完整的 Worker 行為(快取、容災、新聞聚合),用 npm run preview


五、這些事,等你來做

下面的方向按「能多幫到一個人」排序,不按技術難度。在這個專案裡,加一個城市比換一個框架更有價值。

防災價值直接提升

方向說明從哪改增加城市在 CITIES 陣列加 { name, lng, lat },就這麼簡單src/impact.ts10/12 級風圈倒數擴展 computeImpacts 返回多級 ETAsrc/impact.ts按定位排序城市navigator.geolocation + 距離排序src/app.ts多颱風切換TYPHOON_ID 改成路由參數——颱風年年來,這個網站不該只為巴威活一次src/app.ts · worker/index.ts地方化指南各省防汛細則、避險點。你比我更懂你的城市src/guide.ts### 體驗與傳播

方向說明i18n 繁體/英文面向港澳台與外籍居民預警等級接入對接中央氣象台預警信號PWA 離線快取斷網前的最後一次資料,離線也能看——颱風天最容易斷網分享卡片動態生成 OG 圖按城市倒數即時渲染### 資料源擴充(需合規評估)

源現狀思路小紅書反爬,無法匿名抓取需使用者授權或官方 API微博需訪客 CookieWorker 端謹慎實作,注意 ToS地方氣象局多數有公開介面在 worker/ 加 fetcher 模組### 效能待辦(歡迎認領)

  • 風圈多邊形點數按需簡化(低縮放級別)
  • Service Worker 快取最近一次 API 回應
  • 截圖/OG 圖 WebP 壓縮
  • 單元測試:impact.ts · normalize.ts · geo.ts

六、提 MR 的姿勢

流程很平常,Fork、開分支、自測、發 PR:

bash 代碼解讀複製代碼git checkout -b feat/your-feature-name
npm run typecheck   # 必須過
npm run build       # 必須過
npm run preview     # 本地把 Worker + 前端跑通

幾個小約定:

  • commit message 講「為什麼」,別只寫「做了什麼」;
  • 一個 MR 只做一件事。加城市、修資料源、改樣式,分開提;
  • 附上驗證方式。截圖或錄影,讓 review 的人兩分鐘能確認。

比如這樣:

diff 代碼解讀複製代碼feat(impact): 新增廈門、泉州城市倒數

- 在 CITIES 陣列補充閩南沿海城市
- 驗證:打開 /?city=廈門 可看到倒數彈窗

Review 時我會看型別安全、依賴體積、資料源的逾時與容災。但有一條比所有程式碼規範都重要:

這個專案的每一行文案,都可能在某個深夜被一個正在擔心家人的人讀到。 我們提供確定性,不製造焦慮;傳遞緊迫感,不販賣恐慌。免責聲明必須保留:倒數是估算,防災決策以官方預警為準。


七、為什麼開源

防災資訊不應該被鎖在任何人的伺服器裡——包括我的。

這個專案誕生於一個睡不著的凌晨,但它不該只屬於那個凌晨。颱風年年來,資料源會失效,城市名單會過時,指南會需要更新。一個人的熱情撐不起一件需要長期存在的事,能撐起它的只有社群。

開源之後,事情就變得可以想像:資料源掛了,有人半小時內提個 fix;福建的朋友補上福建的避險點;有人 fork 一份部署到自己的網域,哪怕有一天 chinaupdated.com 不在了,程式碼還在,還能救急。

寫程式的人常常懷疑自己做的東西有沒有意義。但防災這件事給了一個罕見的、清晰的答案——

技術人的理想主義,有時候就是寫一段程式碼,讓多一個人提前看到危險。

你修的每一個 bug,可能就是某個使用者在斷網前搶到的最後一次刷新;你加的每一個城市,背後都是真實住在那裡的人。這裡沒有 KPI,沒有成長曲線,只有一個樸素的衡量:有沒有人因為它,提前把窗戶加固了、把水囤上了、把老人接走了。

歡迎 Star、Fork、提 Issue、提 MR。一個人力量有限,眾人拾柴,總能多照亮一段路。

颱風會走,程式碼會留下。願它下一次被用到時,比這一次更好。


附錄

自訂網域在 wrangler.jsoncroutes 中設定,目前綁定 chinaupdated.comwww.chinaupdated.com

截圖索引

文件說明docs/screenshots/01-overview-city-countdown.png總覽:高德底圖 + 城市列表 + 預警條docs/screenshots/02-city-popup.png點擊城市:倒數彈窗 + 行動建議docs/screenshots/03-news-panel.png即時資訊:多源媒體報導docs/screenshots/04-guide-panel.png應對指南:五段式清單docs/screenshots/05-forecast-compare.png四機構預報路徑對比


原文出處:https://juejin.cn/post/7659393583027896330


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝17   💬3   ❤️4
709
🥈
我愛JS
📝2   💬5   ❤️3
140
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登