技術棧
套件選型與設計決策
一覽
| # | 項目 | 決定 |
|---|---|---|
| 1 | 前端框架 | Next.js(App Router + TypeScript) |
| 2 | 套件版本 | 最新穩定版,不鎖舊版 |
| 3 | Package manager | npm |
| 4 | UI library | shadcn/ui(Tailwind 為底,preset = base-nova) |
| 5 | Icon | lucide-react |
| 6 | 字體 | Noto Sans TC(全站,next/font/google) |
| 7 | Schema 驗證 | Zod |
| 8 | State management | 不引入 library(React state + localStorage) |
| 9 | Client 資料 fetching | 不引入 library(全 Server Component + URL navigation) |
| 10 | 資料載入 | Server Component + fs.readFile,含索引檔 |
| 11 | 搜尋 | MVP 走 server-side brute force(String.includes);未來再升級 |
| 12 | 地圖 | Leaflet + react-leaflet + MapTiler SDK(@maptiler/leaflet-maptilersdk) |
| 13 | 圖表 | mermaid(參考頁用) |
| 14 | 時間軸 | D3 + 自製 React 元件(post-MVP) |
| 15 | 圖譜 | react-force-graph(post-MVP) |
| 16 | 部署 | 本機 npm run dev -p 7000;未來升級路徑見下方 |
資料層
載入策略:Server Component + fs.readFile
所有資料讀取(譯本、索引檔、實體檔)都在 Server Component 用 Node fs 直接讀檔,render HTML 給 client。Client 不直接 fetch 資料。
資料處理腳本:scripts/*.ts
原始資料 → normalized JSON 的 transform 用 tsx 直接執行 TypeScript,不需 build 步驟。執行:npx tsx translations/scripts/<name>.ts 或 npx tsx src/scripts/<name>.ts
| 腳本 | 輸入 | 輸出 |
|---|---|---|
| build-theographic-people.ts | datasets/raw/theographic/people.json | src/data/people.json |
| build-openbible-place-annotations.ts | annotation output + datasets/raw/openbible-geocoding/ | src/data/place-meta.json + cunp-place-annotations.json |
| build-places-compare.ts | TIPNR + Theographic + OpenBible | src/data/places-comparison.json |
| build-translation-diff.ts | 三譯本 | src/data/translation-diff.json |
| fetch-biblegateway.ts | BibleGateway scrape | translations/raw/biblegateway_*/ |
| fetch-youversion.ts | YouVersion scrape | translations/raw/youversion_*/ |
功能層設計決策
搜尋:server-side brute force(MVP)
CUNP 全文 70 萬字,brute force ~10ms,個人用感覺不到。未來升級觸發點:擴大到實體搜尋或轉 static export 時,再換 FlexSearch。
時間軸:D3 + 自製 React 元件(post-MVP)
BC 日期用年份數字當座標,繞開 JS Date 的負年份陷阱。ChronoDate 的 approximate/range/uncertain 需要客製不確定性視覺化,現成 lib 不支援。純 SVG + d3-scale + d3-zoom,約 300–500 行。
圖譜:react-force-graph(post-MVP)
視覺與互動最接近 Obsidian Graph View。與 schema 的 {from, to, type} 邊結構直接相容。規模:5,000 節點 + 10K–50K 邊,以焦點 + 1–2 層鄰居為主,不一次顯示全圖。
部署策略
| 觸發條件 | 升級到 |
|---|---|
| 現況 | 本機 npm run dev |
| 想開機自動可用 | 本機 static export + 系統服務啟動 |
| 想在手機/平板使用 | 私有 NAS + Tailscale + static export |
| 想分享公共領域版本 | 雙構建:個人版本機 + 公開版 Vercel(自動排除版權譯本) |
| 想做桌面軟體體驗 | Electron 打包 |