## 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> 安裝最新套件: ![image](https://hackmd.io/_uploads/r17GEBywlg.png =70%x) ::: :::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 相依套件的補充 ![image](https://hackmd.io/_uploads/H1nuCelU0.png) ::: success **解法:** **npm i** \-\-save-dev @babel/plugin-proposal-private-property-in-object \-\-legacy-peer-deps ::: ![image](https://hackmd.io/_uploads/rkVoy-g8C.png) - 安裝開發輔助套件 ::: 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(移除後重新安裝),否則會**無法編譯** ![image](https://hackmd.io/_uploads/SyzmfPb8C.png) 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> [ &nbsp;&nbsp;... &nbsp;&nbsp;**"react-app"**, &nbsp;&nbsp;**"standard-react"**, &nbsp;&nbsp;... ], **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> [ &nbsp;&nbsp;... &nbsp;&nbsp;**"react"**, &nbsp;&nbsp;**"react-hooks"**, &nbsp;&nbsp;**"@typescript-eslint"**, &nbsp;&nbsp;**"import"**, &nbsp;&nbsp;... ],<br> 3. **覆寫共用規則** <font color='red'>**"rules":**</font> { &nbsp;&nbsp;**"react/prop-types"**: "off", &nbsp;&nbsp;**"react-hooks/rules-of-hooks"**: "error", &nbsp;&nbsp;**"react-hooks/exhaustive-deps"**: "warn", &nbsp;&nbsp;**"@typescript-eslint/type-annotation-spacing"**: "error", &nbsp;&nbsp;**"@typescript-eslint/no-unused-vars"**: "error", &nbsp;&nbsp;**"import/no-anonymous-default-export"**: "off", &nbsp;&nbsp;**"jsx-quotes"**: [ &nbsp;&nbsp;&nbsp;&nbsp;"error", &nbsp;&nbsp;&nbsp;&nbsp;"prefer-double" &nbsp;&nbsp;], &nbsp;&nbsp;**"semi"**: [ &nbsp;&nbsp;&nbsp;&nbsp;"error", &nbsp;&nbsp;&nbsp;&nbsp;"always" &nbsp;&nbsp;] } 4. 套件列表 ![image](https://hackmd.io/_uploads/HJ0MBdbIC.png) ::: ::: 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 設定作為編譯的根目錄 ![image](https://hackmd.io/_uploads/HyqACxqvxg.png =50%x) - 需調整 public/index.html 內的 id 需與 index.tsx 內一致,下面以 insure-app 作為識別 id 檔案 **public/index.html** ![image](https://hackmd.io/_uploads/rJPJRlqwxl.png) 檔案 **index.tsx** ![image](https://hackmd.io/_uploads/HJ3KaeqPle.png =50%x) - 若於安裝過程中發生套件版本衝突,可用指令 **\-\-legacy-peer-deps**,範例如下: :::info npm i connected-react-router@6.9.3 **\-\-legacy-peer-deps** :::