i18n¶
文件角色:implementation flow 投影;圖與步驟不得另建產品規則或參數 authority。
| Implementation authority | 產品 canon/流程 | 全域索引 |
|---|---|---|
| i18n.md | 語系清單 | 流程.md §2 |
啟動時語言偵測¶
flowchart TD
Start[App 啟動] --> URL{URL 前綴有支援語系?}
URL -->|有| UseURL[使用 URL 語系]
URL -->|沒有| Stored{settings 顯示語系<br/>已設定?}
Stored -->|有| UseStored[使用儲存的語言]
Stored -->|沒有| Browser[偵測 navigator.language]
Browser --> Match{對應到<br/>支援語言?}
Match -->|zh-TW| ZhTW[zh-TW]
Match -->|zh| ZhCN[zh-CN]
Match -->|ja| Ja[ja]
Match -->|其他| En[en 預設]
UseURL --> Load[載入 lazy 字典 chunk]
UseStored --> Load
ZhTW --> Load
ZhCN --> Load
Ja --> Load
En --> Load
Load --> Ready[App 啟動完成]
翻譯查找流程¶
sequenceDiagram
participant Comp as Component
participant Pipe as i18n Pipe
participant I18n as I18nService
participant Dict as Current Dict
participant Fallback as en Dict
Comp->>Pipe: {{ 'race.lap' | i18n:{ lap: 2 } }}
Pipe->>I18n: t('race.lap', { lap: 2 })
I18n->>Dict: get('race.lap')
alt 找到
Dict->>I18n: '第 {lap} 圈'
I18n->>I18n: interpolate
I18n->>Pipe: '第 2 圈'
else 沒找到
I18n->>Fallback: get('race.lap')
Fallback->>I18n: 'Lap {lap}'
I18n->>Pipe: 'Lap 2'
end
Pipe->>Comp: 翻譯結果
語言切換¶
flowchart TD
UI[設定頁選擇語系] --> Save[寫入 settings 顯示語系]
Save --> Hint[提示需重整才生效]
Hint --> Keep[目前 dict/router/font 保持不變]
Keep --> Refresh[玩家在安全時機重整]
Refresh --> Detect[bootstrap 讀取已保存語系]
Detect --> Chunk[載入 lazy dictionary chunk]
Chunk --> Font[只啟用目前語系字型 stylesheet]
Font --> Ready[啟動 App]
社群 PR 流程¶
flowchart TD
Fork[Contributor Fork repo] --> Copy[以完整 zh-TW.json 為撰寫源]
Copy --> Translate[翻譯所有 value]
Translate --> Register[在 LangCode 註冊新語言]
Register --> PR[提交 PR]
PR --> CI{CI 檢查}
CI -->|JSON 格式| FormatCheck
CI -->|Key 一致性| KeyCheck
CI -->|佔位符保留| ParamCheck
FormatCheck --> AllPass{全部通過?}
KeyCheck --> AllPass
ParamCheck --> AllPass
AllPass -->|是| Review[Maintainer Review]
AllPass -->|否| Fix[Contributor 修正]
Fix --> CI
Review --> Native{母語使用者<br/>Review}
Native -->|批准| Merge[Merge to main]
Native -->|建議修改| Comment[留言討論]
Comment --> Update[Contributor 更新]
Update --> Native
Merge --> Release[隨主分支部署上線]
字典缺漏處理¶
flowchart TD
NewKey[zh-TW.json 新增 key] --> Sync[以 zh-TW key tree 比對其他語系]
Sync --> Mark[列出 missing 與 extra keys]
Mark --> Lint{CI Lint}
Lint -->|一般語系 missing 或 extra| Warn[警告:缺漏或 dead translation]
Lint -->|fallback en missing| Error[錯誤:fallback 不完整]
Warn --> Report[CI 報告差異]
Report --> Wait[維護者或社群提交 PR]
Wait --> Translate[社群提交翻譯]
Translate --> Merge[Merge]
字典結構¶
graph TB
subgraph 字典檔
ZhTW[zh-TW.json<br/>主翻譯]
En[en.json<br/>fallback]
ZhCN[zh-CN.json]
Ja[ja.json]
end
subgraph 命名空間
Roots["固定 root 集合,以 zh-TW key tree 為權威<br/>materials/app/common/race/garage/settings/errors…"]
end
ZhTW --> Roots
En --> Roots
ZhCN --> Roots
Ja --> Roots
複數處理¶
flowchart TD
Call["I18nService.t('items', { count })"] --> Lookup[查找 items 單一 ICU 字串]
Lookup --> Parse["formatIcu(template, params, lang)"]
Parse --> Select[Intl.PluralRules<br/>依目前語系選 plural category]
Select --> Format[代入 count 與其他 params]
Format --> Result[最終字串]
PWA 字典快取¶
graph LR
App[App 啟動] --> SW[Service Worker]
SW --> Check{字典已快取?}
Check -->|是| Cache[從 Cache 讀]
Check -->|否| Net[從網路抓 + 快取]
Cache --> Use[I18nService 使用]
Net --> Use
Use --> Render[渲染翻譯文字]
classDef local fill:#e8f3ec,stroke:#3f8f5f,stroke-width:1.4px,color:#173525;
classDef consensus fill:#fdf3df,stroke:#c08a2d,stroke-width:1.4px,color:#3d2c0d;
class Cache local
class Net consensus