## React 專案建構
### 一、安裝執行/開發輔助套件
- 建立 React with TypeScript 專案
::: info
**npm init react-app** [project-name]
(不能加 template 參數)
或者
**npx create-react-app** [project-name] <font color='red'>\-\-template typescript</font>
範例與專案截圖: **npx create-react-app** my-app <font color='red'>\-\-template typescript</font>
安裝最新套件:

:::
:::success
:bulb: cra 會安裝最新的 React 版本,若有 **指定版本** 需求,則於安裝後執行覆蓋安裝。
以下為 React 指定為 v18 的指令:
:::info
npm i react@18.3.1 react-dom@18.3.1 @types/react@18.3.3 @types/react-dom@18.3.0 @testing-library/react@13.4.0
:::
:::danger
:bulb: **connected-react-router 已不支援 React v18**
套件 connected-react-router 設計用來串接 redux 與 react router,支援 redux-thunk 與 redux-saga,原則上僅支援到 **React v17**,因為 React v18 搭配的 React Router Dom 為 v6,若仍要使用則需將 React Router Dom 降為 v5。
React v18 以上版本可使用下列替代方案:
- **redux-first-history**
尚未用過
- **redux-react-router**
支援 React Redux v6 與 React Router v6 以上, 設定相關說明可參考 [官網](https://www.npmjs.com/package/@lagunovsky/redux-react-router) 連結,安裝指令如下:
:::info
npm i @lagunovsky/redux-react-router
:::
- 新版 cra 相依套件的補充

::: success
**解法:**
**npm i** \-\-save-dev @babel/plugin-proposal-private-property-in-object \-\-legacy-peer-deps
:::

- 安裝開發輔助套件
::: info
1. **安裝舊版 Eslint (<= v7)**
- <font color='blue'>[6.8.0 => es6, 2018] (兆豐案)</font>
- **npm i** eslint@6.8.0 -D
- **npx** eslint@6.8.0 \-\-init (生成 .eslintrc.json)
- **npm i** babel-eslint -D
- <font color='blue'>[7.32.0 => es2021, 2020] (臺銀案)</font>
- **npm i** eslint@7.32.0 -D
- **npx** eslint@7.32.0 \-\-init (生成 .eslintrc.json)
- **npm i** babel-eslint -D
- **eslint-plugin、parser** 降版至 v4.0.0(移除後重新安裝),否則會**無法編譯**

2. **安裝專案需要的語法規則套件**
**npm i** eslint-config-standard@16.0.0 eslint-config-standard-jsx@10.0.0 eslint-config-standard-react@11.0.0 -D
<font color='red'>**"extends":**</font> [
...
**"react-app"**,
**"standard-react"**,
...
],
**npm i** eslint-plugin-flowtype@5.2.0 eslint-plugin-import@2.25.4 eslint-plugin-node@11.1.0 eslint-plugin-promise@5.2.0 eslint-plugin-react@7.28.0 eslint-plugin-react-hooks@4.3.0 -D
<font color='red'>**"plugins":**</font> [
...
**"react"**,
**"react-hooks"**,
**"@typescript-eslint"**,
**"import"**,
...
],<br>
3. **覆寫共用規則**
<font color='red'>**"rules":**</font> {
**"react/prop-types"**: "off",
**"react-hooks/rules-of-hooks"**: "error",
**"react-hooks/exhaustive-deps"**: "warn",
**"@typescript-eslint/type-annotation-spacing"**: "error",
**"@typescript-eslint/no-unused-vars"**: "error",
**"import/no-anonymous-default-export"**: "off",
**"jsx-quotes"**: [
"error",
"prefer-double"
],
**"semi"**: [
"error",
"always"
]
}
4. 套件列表

:::
::: info
:bulb: **ESlint v8.57.0 安裝步驟** (搭配 Node v18.20.4 + React v18.3.1)
1. **ESLint 套件、ES2015+ (ES6+) 匯出/匯入語法套件**
npm i eslint@8.57.0 @eslint/js@9.5.0 globals@15.6.0 eslint-plugin-import@2.29.1 -D
2. **Typescript 語法規則套件**
npm i typescript-eslint@7.13.1 @typescript-eslint/parser@7.14.1 -D
3. **React 語法規則套件**
npm i eslint-plugin-react@7.34.3 eslint-plugin-react-hooks@4.6.2 -D
4. **建立設定檔並調整語法規則**
新增 eslint.config.mjs 檔案並加入各類規則,請參考 [設定內容](https://hackmd.io/@HolyCho/SyW60UMPlx)
:::
::: danger
:bulb: ESLint 導覽安裝指令: **npx eslint \-\-init**
- 安裝時會有問答引導
- 根據使用者需求於過程中會追加安裝: eslint @eslint/js globals typescript-eslint eslint-plugin-react
- 新版最後會生成設定檔: .eslint.config.mjs
:question: 安裝問題: 安裝指令 \-\-init 生成的設定檔,於重啟 VS Code 後似乎無法正常生效。
:star: <font color='ligreen'>**若是手動安裝 eslint @eslint/js globals typescript-eslint eslint-plugin-react 套件並自行建置 .mjs 檔,於重啟 VS Code 後正常檢查語法。**</font>
:::
::: warning
:bulb: 新版 ESlint 所有配置(**eslint.config.mjs**)於變更完成後,需<font color='red'>**重啟** VS Code 方可生效</font>。(否則不會生效)
:::
### 二、調整目錄 src/app
- **bff**
:::info
:bulb: **放置前端 API 服務與相關服務**
1. enums: API 所需的列舉
2. models: API 所需的資料定義
3. services: API 呼叫
:::
- **common**
:::info
:bulb: **放置共用切版模板與小組件**
1. layouts: 排版
2. components: 頁面所需之各類小組件
:::
- **core**
:::info
:bulb: **放置各種自訂頁面工具,如自訂燈箱、自訂 Hook、檢核規則、各類轉換公式**
1. enums: 前端頁面所需的列舉
2. hooks: 前端頁面所需自定義鉤子
3. models: 前端頁面所需的列舉映射
4. router
- guards: 卡控路由之守衛
- path: 全站路由列表、名稱轉換(會員足跡)
- service: 處理動態路由之工具
- types: 定義動態路由之相關參數
5. services
- commonService: 共用工具
- cookieService: 操作 universal-cookie 之 Cookie
- dialogService: 提示視窗
- storageService: 針對 localStorage、sessionStorage、cookieService 操作
:::
- **features**
:::info
:bulb: **放置產品/專案功能頁,透過前端路由規則映射並掛載**
1. Activity:最新消息、熱門活動
2. Home:主首頁
3. Member:會員中心
4. Insure:各險種之投保流程
5. Service:各項服務頁面
:::
- **store**
:::info
:bulb: **放置 redux 函式庫於架構內協作的程式碼、狀態、界面定義等,如 action、reducer、saga、store(可對照 features 結構,以利維護與開發)**
1. activity: 存放最新消息、熱門活動等資料
2. home: 存放主首頁資料
3. member: 存放會員資料
4. insure: 存放投保流程資料
5. service: 存放服務資料
6. system/ui/...等(不屬於 features 範疇內可視需求建構)
:::
### 三、建立目錄 src/assets
- **css**: 各頁面與組件編譯後之樣式
- **img**: 頁面所需圖片
- **scss**: 各頁面與組件所引用的 Sass/SCSS 檔案
### 四、建立目錄 src/environments
編譯環境設定,如 SIT、UAT、PROD 等
- **sit 環境檔**: environment.development.ts
- **uat/prod 環境檔**: environment.production.ts
### 五、測試套件錯誤
- 若發生 **「Environment key "jest/globals" is unknown」** 錯誤,則需安裝測試套件,安裝指令如下:
:::info
npm i eslint-plugin-jest -D
:::
- 設定檔 **eslint.config.mjs** 加入設定:
```
{
"plugins": ["jest"],
"env": {
"jest/globals": true
},
}
```
- 經測試,若是 Nodejs v18 環境下執行 npm start 不會發生此錯誤
### 六、其他注意事項
- tsconfig.json 編譯選項 (compilerOptions) 需加上 baseUrl 設定作為編譯的根目錄

- 需調整 public/index.html 內的 id 需與 index.tsx 內一致,下面以 insure-app 作為識別 id
檔案 **public/index.html**

檔案 **index.tsx**

- 若於安裝過程中發生套件版本衝突,可用指令 **\-\-legacy-peer-deps**,範例如下:
:::info
npm i connected-react-router@6.9.3 **\-\-legacy-peer-deps**
:::