FSTS 前端編碼規範

OMS 專案前端(React 18 + TypeScript 5 + Vite)的編碼規範(v1.1,2026-03-02)。適用範圍:證券業 Order Management System 前端。回到 FSTS 專案總覽、搭配後端:FSTS 後端編碼規範

一句話

OMS 前端以 Vite + React 18 + TypeScript 5 為骨幹,UI 採 Radix UI + Tailwind CSS headless 路線,狀態切為 TanStack Query(server)+ Zustand(client)+ useState(local) 三層,禁用中國大陸來源套件(Ant Design / UMI / dayjs / Taro 等)並要求 MIT / Apache 2.0 / BSD 授權。12

1. 技術選型原則

1.1 核心原則

  • 不使用中國大陸來源套件(如 Ant Design、UMI、dva、Taro、dayjs 等)
  • 優先選擇歐美主流開源生態系,確保長期維護性與合規性
  • 所有套件須有 MIT / Apache 2.0 / BSD 授權1

1.2 官方技術棧

類別選用套件說明
建置工具Vite快速 HMR、原生 ESM
UI 元件庫Radix UI + Tailwind CSSHeadless + 自訂樣式
狀態管理Zustand (client) + TanStack Query (server)輕量 + 資料快取
路由React Router v6巢狀路由、lazy loading
表單React Hook Form + Zod高效能 + 型別安全驗證
表格TanStack TableHeadless、支援虛擬滾動
圖表Recharts 或 Lightweight Charts金融圖表
HTTP 客戶端Axios攔截器、取消請求
日期處理date-fns純函數、Tree-shakable
國際化react-i18next多語系
測試Vitest + Testing Library與 Vite 整合
代碼檢查ESLint + Prettier統一風格

1.3 禁用套件清單

禁用替代方案原因
Ant Design (antd)Radix UI + Tailwind中國來源
UMIReact Router + Vite中國來源
dvaZustand中國來源
dayjsdate-fns中國來源
TaroN/A中國來源
element-plusN/A中國來源(Vue 生態)
naive-uiN/A中國來源(Vue 生態)
cnpm / tnpmnpm / pnpm中國來源 Registry

2. 專案結構

frontend/src/
├── app/           # 應用層:路由、Provider、全域設定
│   ├── App.tsx, routes.tsx
│   └── providers/ (AppProvider, QueryProvider)
├── features/      # 功能模組(按業務領域分)
│   └── {orders, products, dashboard}/
│       └── (api/, components/, hooks/, types/, pages/)
├── shared/        # 跨功能共用
│   ├── components/ (ui/, layout/, data-display/)
│   ├── hooks/, utils/, types/, constants/
├── services/      # 外部服務整合
│   ├── api/ (Axios instance、攔截器)
│   └── websocket/ (即時行情)
├── stores/        # Zustand 全域狀態
└── styles/ (globals.css)

根目錄另有 index.htmlpackage.jsonvite.config.tstailwind.config.tseslint.config.jsprettier.config.jstsconfig.json3

2.1 模組邊界規則

  • features/ 內的模組之間禁止直接引用,必須透過 shared/ 共用
  • shared/ 不得引用任何 features/ 模組
  • services/ 為純技術層,不包含業務邏輯
  • 每個 feature 可獨立 lazy load
  • 禁止使用 barrel fileindex.ts re-export),直接引用具體檔案以利 tree-shaking4

3. 命名規範

3.1 檔案命名

類型規則範例
React 元件PascalCase .tsxOrderTable.tsx
HookcamelCase,use 開頭useOrdersQuery.ts
工具函式camelCaseformatters.ts
型別定義camelCaseorderTypes.ts
常數camelCase 檔名,UPPER_SNAKE 值appConstants.ts
Query Key FactorycamelCaseorderQueryKeys.ts
測試與原始檔同名 + .testOrderTable.test.tsx

說明:除 React 元件檔案使用 PascalCase 外,其他所有 .ts 檔案統一使用 camelCase(與 TanStack、Zustand 等主流套件一致)。5

3.2 程式碼命名

  • 元件 — PascalCase:export function OrderDetailPanel(...)
  • Hook — camelCase,use 開頭:export function useOrderQuery(...)
  • 型別 / 介面 — PascalCase,不加 I 前綴export interface OrderResponse { }
  • 常數 — UPPER_SNAKE_CASE:export const MAX_PAGE_SIZE = 100
  • 事件處理handle 前綴:const handleSubmit = () => { }
  • Boolean 變數is / has / should 前綴:isLoading, hasPermission, shouldRefresh6

反例(禁止):function orderDetailPanel()(元件非 PascalCase)、interface IOrderResponse(用 I 前綴)、const loading(Boolean 缺語意前綴)。6

4. 元件設計規範

4.1 撰寫原則

  • 使用函式元件 + 具名匯出
  • Props 型別獨立定義於元件上方
  • 禁止使用 React.FC(型別推斷不精確)7

4.2 Export 規則

情境使用方式原因
元件、Hook、工具函式export function 具名匯出可搜尋性佳、支援 tree-shaking
Page 元件export default functionReact.lazy() 要求 default export
forwardRef 元件export const X = forwardRef(...)React API 限制,允許此例外

4.3 元件分類

分類位置特性
Page Componentfeatures/*/pages/對應路由、組合子元件、處理資料取得
Feature Componentfeatures/*/components/業務邏輯相關、可存取 feature 的 store/api
Shared Componentshared/components/純展示、無業務邏輯、只接收 props
Layout Componentshared/components/layout/頁面框架(Sidebar, Header)

4.4 元件大小限制

  • 單一元件檔案不超過 250 行
  • 超過則拆分子元件或抽離 Hook
  • 一個檔案只匯出一個元件(小型輔助元件例外)8

5. 狀態管理規範

5.1 狀態分層

層級套件說明
Server State(API 資料、快取、同步)TanStack Query自動快取、refetch、stale time
Client Global State(用戶偏好、UI 主題、認證)Zustand跨頁面持久狀態
Component Local State(表單輸入、展開收合、對話框)useState / useReducer不需跨元件共用

5.2 TanStack Query 使用規範

Query Key Factory 獨立檔案(與 Query Hook 分離),擺在 features/orders/api/orderQueryKeys.ts9

6. API 整合規範

6.1 Axios Instance

  • baseURLimport.meta.env.VITE_API_BASE_URL(預設 /api/v1),timeout: 15_000
  • Request 攔截器:自動帶 Token(Authorization: Bearer ${token}
  • Response 攔截器:401 自動清除 auth + 導 /loginerror.response.data 作為 ProblemDetails 拋出10

6.2 API 函式規範

每個 Domain 一個 API 模組,函式命名對應 HTTP Method(getOrders, getOrderById, createOrder, updateOrderStatus)。檔案位置:services/api/orderApi.ts11

6.3 API 錯誤型別(RFC 7807 ProblemDetails)

後端回傳的錯誤格式遵循 RFC 7807;前端使用共用型別 ProblemDetails12

interface ProblemDetails {
  type: string;
  title: string;
  status: number;
  detail: string;
  traceId?: string;
  errors?: Record<string, string[]>;
}

禁止使用 inline 型別斷言(如 (error as { detail?: string })?.detail)。12

7. 金融業專用規範

7.1 數值格式化

所有金額一律使用專用格式化函式,禁止手動拼接13

  • formatCurrency(value, currency = 'TWD')Intl.NumberFormat('zh-TW', { style: 'currency', currency })
  • formatStockPrice(value) — 2 位小數
  • formatChangePercent(value) — 含 + / - 符號

7.2 即時資料(WebSocket)

金融業需要即時行情推送。核心設計要點:14

  • 使用 useRef 穩定 symbols reference(避免重複連線)
  • 斷線自動重連(exponential backoff)
  • onerror 錯誤處理
  • JSON.parse try-catch
  • useEffect 用空依賴,連線只建立一次,symbols 透過 ref 讀取

7.3 安全性要求

  • Token 優先使用 httpOnly Secure Cookie(後端設定,前端碰不到 Token)
  • 若因架構限制使用 localStorage,須搭配嚴格 CSP 政策防止 XSS
  • 所有 API 請求必須走 HTTPS
  • 敏感頁面(交易、帳務)需設 Session Timeout(建議 15 分鐘
  • 禁止在前端 console.log 輸出敏感資料(帳號、金額、身分證字號)
  • Production build 應透過 Vite 設定 esbuild.drop: ['console', 'debugger'] 移除所有 console
  • 使用 CSP Header 防止 XSS15

8. 樣式規範

8.1 Tailwind CSS 原則

  • 使用 Tailwind 工具類別(className="rounded-md bg-blue-600 px-4 py-2 ..."
  • 複雜樣式用 clsx + tailwind-merge(合併成 cn() 工具函式)
  • 語意化顏色透過 Tailwind config 定義text-market-up(紅)、text-market-down(綠)— 台灣證券業慣例:漲紅跌綠16

本專案唯一樣式方案為 Tailwind CSS,不使用 CSS Modules、styled-components 或其他 CSS-in-JS。16

8.2 響應式設計

  • Mobile-first 設計(sm:md:lg:xl:
  • 金融交易畫面最小支援 1280px 寬螢幕
  • Dashboard 支援多螢幕分割顯示17

9. Import 排序規範

所有檔案的 import 依以下順序排列,各群組之間空一行:18

  1. React 核心(import { useState } from 'react'
  2. 第三方套件(@tanstack/react-queryzod 等)
  3. @/ 路徑別名(shared → services → stores)
  4. 相對路徑引用(feature 內部)
  5. 型別 import(使用 import type

可搭配 ESLint import/order@trivago/prettier-plugin-sort-imports 自動排序。

10. ESLint 檢核規則

本專案使用 ESLint Flat Config 格式eslint.config.js),搭配 typescript-eslintstrictTypeChecked 預設規則集。19

10.1 TypeScript 嚴格規則

規則設定說明
@typescript-eslint/no-unused-varserror未使用變數為錯誤,_ 開頭參數除外
@typescript-eslint/no-explicit-anyerror禁止使用 any 型別
@typescript-eslint/explicit-function-return-typeoff由 TypeScript 推斷
@typescript-eslint/consistent-type-importserror型別 import 必須用 import type
@typescript-eslint/no-misused-promiseswarnPromise 誤用警告

10.2 命名規範

對象格式範例
interfacePascalCaseOrderResponse, AuthState
typeAliasPascalCaseOrderStatus, UserRole
enumPascalCaseTheme, Locale
Boolean 變數is / has / should / can / will 開頭isLoading, hasPermission

10.3 React 規則

  • react-hooks/rules-of-hooks: error — Hook 必須在頂層呼叫
  • react-hooks/exhaustive-deps: warnuseEffect 依賴陣列完整性檢查
  • react-refresh/only-export-components: warn — 檔案只匯出元件(支援 HMR),允許 const 匯出19

10.4 一般規則

  • no-console: warn — 禁止 console.log,允許 console.warn / console.error
  • prefer-const: error
  • no-var: error19

10.5 刻意關閉的規則

  • @typescript-eslint/no-confusing-void-expression — 與 React event handler 慣例衝突
  • @typescript-eslint/restrict-template-expressions — 過度嚴格,影響開發效率19

10.6 繼承規則集

  • js.configs.recommended(來自 @eslint/js
  • tseslint.configs.strictTypeChecked(來自 typescript-eslint20

單行忽略(僅在必要時使用,需附註原因):// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 第三方套件型別不完整21

11. 環境變數規範

Vite 要求前端可存取的環境變數必須以 VITE_ 開頭22

變數說明預設值
VITE_API_BASE_URL後端 API 基礎路徑/api/v1
VITE_WS_URLWebSocket 即時行情位址
  • .env 檔案禁止納入版控(加入 .gitignore
  • 不得在 VITE_ 變數中存放敏感資訊(API Secret、DB 密碼)
  • 提供 .env.example 作為範本

12. 測試規範

12.1 Co-location(與原始碼並排)

前端業界主流是將測試檔案放在原始碼旁邊,而非像後端獨立成專案:23

src/shared/utils/formatters.ts
src/shared/utils/formatters.test.ts    ← 同目錄

規則:foo.ts 的測試就是同目錄下的 foo.test.ts(元件則為 foo.test.tsx)。

不獨立資料夾的原因:Vite 打包不會包含 .test.ts、就近維護、刪除方便、IDE 側邊欄切換快。另一種做法是同層建立 __tests__/ 子資料夾收納測試(視覺較乾淨),兩種都是主流,團隊統一即可23

12.2 測試優先順序(投資報酬率由高到低)

順序類型說明範例
1工具函式 / 純邏輯最容易測、最穩定formatters.test.ts, cn.test.ts
2Store / Hook商業邏輯集中處,改壞影響大authStore.test.ts, useOrderFilters.test.ts
3元件行為條件渲染、使用者互動Pagination.test.tsx, UserStatusBadge.test.tsx
4整頁 E2E通常用 Playwright,不算單元測試

原則:測「有邏輯的部分」,純 UI 排版通常不值得寫單元測試。24

12.3 強制寫測試時機

PR 合併前必須完成25

  • 新增前端 utility 函式
  • Bug 修復:先寫失敗的測試,再修正程式碼

建議:Zustand Store 的新 action、React 元件的互動邏輯(Pagination / Modal 等)、Custom Hook 的狀態管理邏輯。

12.4 測試命名與原則

  • 測試使用者行為,不測實作細節
  • 使用 screen.getByRole() 優先,避免 getByTestId()
  • Mock 外部 API,不 Mock 內部模組26

12.5 覆蓋率目標

範圍目標說明
Utility 函式90%+純函式,無副作用
Store80%+狀態管理邏輯
元件60%+著重互動邏輯

12.6 測試工具

工具版本用途
Vitest2.1.5測試框架(與 Vite 原生整合)
@testing-library/react16.0.1React 元件測試
@testing-library/jest-dom6.6.3DOM 斷言擴充
@testing-library/user-event14.5.2使用者互動模擬
jsdom25.0.1瀏覽器環境模擬

13. 效能規範

  • Code Splitting:每個 feature 頁面使用 React.lazy() + Suspense
  • 虛擬滾動:超過 100 筆資料的列表使用 @tanstack/react-virtual
  • 圖片:使用 WebP 格式,搭配 loading="lazy"
  • Bundle 分析:定期使用 rollup-plugin-visualizer 檢查 bundle 大小
  • 首次載入:主 Bundle < 200KB (gzipped)
  • 避免過早優化useMemo / useCallback 僅在確認有 re-render 效能問題時使用,不要預設加上27

14. 無障礙(WCAG 2.1 Level AA)

證券業因合規需求,需符合 WCAG 2.1 Level AA:28

  • 所有互動元素(按鈕、連結、表單輸入)必須可透過鍵盤操作
  • icon-only 按鈕必須提供 aria-label
  • 表單輸入需搭配 <label>aria-label,錯誤訊息使用 aria-describedby 關聯
  • 顏色不得作為唯一的資訊傳達方式(漲跌須同時用顏色 + 符號 ↑↓)
  • 使用 Radix UI 的 headless 元件時,框架已內建 ARIA 屬性

附錄:Quick Reference

DO29

  • 元件使用具名匯出 (named export)
  • Page 元件使用 default export(React.lazy 要求)
  • Props 型別獨立定義
  • Server State 用 TanStack Query
  • 金額用 formatCurrency() 格式化
  • Feature 模組之間透過 shared/ 溝通
  • Boolean 變數加 is / has / should 前綴
  • API 錯誤使用 ProblemDetails 型別
  • icon-only 按鈕加 aria-label

DON’T29

  • 使用 Ant Design 或任何中國來源套件
  • 使用 React.FC 定義元件
  • 在非 Page 元件中使用 default export
  • 在 Page 元件中直接呼叫 axios
  • console.log 輸出敏感資料
  • 單一元件超過 250 行
  • 使用 CSS Modules / styled-components
  • 使用 barrel file(index.ts re-export)
  • API error 使用 inline 型別斷言

相關頁面

補充資訊

來源補充:OMS Coding Rule & CI/CD 簡報(2026-03,OMS Team)

OMS Team 於 2026-03 對前端規範做了一份簡報版摘要。大多數內容與本頁主要規範一致(Radix UI + Tailwind、TanStack Query + Zustand 三層狀態、禁用中國大陸來源套件、ESLint + CI 強制命名檢核、金融業 formatCurrency() 與漲跌顏色+符號雙標示),但在建置工具 / 框架選型上與主要規範衝突,因此本頁 status 改為 contested,不主觀仲裁。

衝突內容

面向主要規範(Frontend-CodingRule v1.1,2026-03-02)簡報(OMS Coding Rule & CI/CD,2026-03)
建置工具 / 框架Vite + React 18 + TypeScript 52Next.js 15 (App Router) + React 19 + TypeScript 530
HTTP 請求axios Instance10API Routes + fetch30

補充(兩份來源一致的重點)

  • Bulletproof React 架構理念(作者 Alan Alickovic,GitHub ★ 30k+):Feature-based 結構、明確模組邊界、關注點分離、可擴展性 — 與 Clean Architecture 精神一致。簡報點出 Bulletproof React 「填補了 React 社群長期缺乏官方專案結構的空缺」。31
  • 禁止使用中國大陸來源套件清單(Ant Design / UMI / dva / dayjs / Taro / cnpm / tnpm),理由為「確保長期維護性與合規性」。32
  • 模組邊界:features 之間禁止直接引用,共用元件必須經過 shared/;services 純技術層,不含業務邏輯;禁止 barrel fileindex.ts re-export)以利 tree-shaking。33
  • 命名規則由 ESLint + CI 自動檢核:違反者無法 push、PR 無法合併(pre-commit hook + GitHub Actions 雙重把關)。34
  • 金融業特殊規範:金額一律用 formatCurrency()(禁止手動拼接);漲跌顯示用「顏色 + 符號(↑↓)」雙標示(無障礙要求);即時行情走 WebSocket 並處理斷線重連;Production 移除 console.log 並套用嚴格 CSP 政策。35

CI/CD 章節獨立成頁:CD Pipeline


參考資料

Footnotes

  1. Frontend-CodingRule §1.1 核心原則 2

  2. Frontend-CodingRule §1.2 官方技術棧 2

  3. Frontend-CodingRule §2 專案結構

  4. Frontend-CodingRule §2.1 模組邊界規則

  5. Frontend-CodingRule §3.1 檔案命名

  6. Frontend-CodingRule §3.2 程式碼命名 2

  7. Frontend-CodingRule §4.1 元件撰寫原則

  8. Frontend-CodingRule §4.4 元件大小限制

  9. Frontend-CodingRule §5.2 TanStack Query 使用規範

  10. Frontend-CodingRule §6.1 Axios Instance 2

  11. Frontend-CodingRule §6.2 API 函式規範

  12. Frontend-CodingRule §6.3 API 錯誤型別規範 2

  13. Frontend-CodingRule §7.1 數值格式化

  14. Frontend-CodingRule §7.2 即時資料 WebSocket

  15. Frontend-CodingRule §7.3 安全性要求

  16. Frontend-CodingRule §8.1 Tailwind CSS 原則 2

  17. Frontend-CodingRule §8.2 響應式設計

  18. Frontend-CodingRule §9 Import 排序規範

  19. Frontend-CodingRule §10.1 ESLint 啟用規則 2 3 4

  20. Frontend-CodingRule §10.2 繼承的預設規則集

  21. Frontend-CodingRule §10.3 如何修改 ESLint 規則

  22. Frontend-CodingRule §11 環境變數規範

  23. Frontend-CodingRule §12.1 測試檔案放置 Co-location 2

  24. Frontend-CodingRule §12.2 測試優先順序

  25. Frontend-CodingRule §12.3 何時必須寫測試

  26. §12.5 測試命名 + 原則

  27. Frontend-CodingRule §13 效能規範

  28. Frontend-CodingRule §14 無障礙規範

  29. Frontend-CodingRule 附錄 Quick Reference 2

  30. OMS-CodingRule-CICD §Slide 9 技術棧與套件原則 2

  31. OMS-CodingRule-CICD §Slide 8 Bulletproof React 架構基礎

  32. OMS-CodingRule-CICD §Slide 9 禁止使用清單

  33. OMS-CodingRule-CICD §Slide 10 專案目錄結構與職責

  34. OMS-CodingRule-CICD §Slide 11 命名規範 工具強制檢核

  35. OMS-CodingRule-CICD §Slide 12 狀態管理 · 金融業規範