# Project Management
## NodeJS
#### 透過 NVM 安裝
官網教學:
```bash
# 安裝 nvm (Node 版本管理器)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# 下載並安裝 Node.js (您可能需要重新啟動終端機)
nvm install 20
# 驗證環境中正確的 Node.js 版本
node -v # 應該顯示 `v20.18.0`
# 驗證環境中正確的 npm 版本
npm -v # 應該顯示 `10.8.2`
```
::: danger
如果是原本使用 Homebrew 安裝 NodeJS,請記得在移除 NodeJS 時僅需要移除 NodeJS 本身,切勿把 Homebrew 整個移除!!
:::
#### 版本考量
基於版本一致性與程式執行階段的穩定性考量,需要要求各專案中使用的 NodeJS 版本一致 (容許範圍可再議)。
目前使用版本如下:
- NodeJS Version:20LTS (20.18.0)
- NPM Version:10.8.2 (參考用不強制)
#### 透過 NVM 指定版本
NVM 可透過專案中的 `.nvmrc` 在專案中指定使用特定版本的 NodeJS,因此可用來強制專案中 NodeJS 版本一致。
要讓 `.nvmrc` 可以正常運作,需要在本地的終端機初始化階段 ( `~/.bashrc` , `~/.zshrc` , etc) 中加上一段腳本,根據使用終端機的不同分為以下三個:
- [bash](https://github.com/nvm-sh/nvm?tab=readme-ov-file#bash)
- [zsh](https://github.com/nvm-sh/nvm?tab=readme-ov-file#zsh)
- [fish](https://github.com/nvm-sh/nvm?tab=readme-ov-file#fish)
::: warning
由於版本切換是在終端機初始化階段執行,因此一旦開啟一個終端機,該終端機階段使用的 NodeJS 版本就會固定,並不會隨著 `.nvmrc` 變更,直到關閉或是使用 `source ~/.bashrc` 重新初始化。
:::
## 套件管理
#### PNPM
主要使用 PNPM 作為專案管理器,並使用 `corepack` 管理專案中 PNPM 版本,目前使用版本 8.15.9。
`corepack` 為 NodeJS 內建工具,主要用於專案中的套件管理器或套件的版本管理。使用方式如下:
啟用 corepack (本地全域):
```bash
corepack enable
```
選用特定版本 (專案內):
```bash
corepack use pnpm@8.15.9
```
`corepack use` 會在 `package.json` 中加入一個 `packageManager` 欄位表示此專案指定的 PNPM 版本:
```json
{
/* ... */
"packageManager": "pnpm@8.15.9+sha512.499434c9..."
}
```
#### 其他
##### .npmrc
::: info
目前會使用 `.npmrc` 設定從 GitLab 下載 NPM 套件時需要的 Token,但由於該設定包含敏感資訊的關係,因此會在 `.gitignore` 中設定**將 `.npmrc` 排除於版控外**。
:::
##### 套件版本
::: info
盡量不使用 `~` 或 `^` 安裝確保版本一致,也讓開發者明確了解所使用的套件版本
:::
## Husky + lint-staged
#### Husky
Husky 可設定 Git Hooks 於各種 Git Life Cycle 執行腳本,目前應用於 Commit 前執行型別檢查、lint、格式化檢查,降低 CI Pipeline 出錯的次數。
安裝 Husky:
```bash
pnpm i -D husky
```
*.husky/pre-commit*
```bash
pnpm exec lint-staged # 需要執行的腳本
```
*package.json*
```json
{
"scripts": {
// 於 pnpm install 後初始化 git hooks 設定
// 並且防止在 CI Pipeline 中執行
"prepare": "[ \"$CI\" != \"true\" ] && husky || true"
}
}
```
::: warning
由於 husky 會需要 `pnpm install` 後才會有效,因此盡量確保在 Commit 前已經執行過 `pnpm install`
:::
#### lint-staged
lint-staged 可用來針對 Git 中被暫存的修改執行特定腳本,並可篩選特定形式的檔案像是只需要針對 .js 或 .ts 檔案執行,就不會對其他不屬於程式碼的檔案執行。
安裝 lint-staged:
```bash
pnpm install -D lint-staged
```
*package.json*
```json
{
/* ... */
"lint-staged": {
"{src,test}/**/*.ts": [ // 針對 src 和 test 中所有 .ts 檔案
"bash -c tsc --noEmit", // 執行型別檢查
"eslint" // 執行 lint
]
}
}
```
::: info
這兩者可搭配並達到在 Commit 前針對這次有異動的檔案執行 eslint、type check 等動作,降低 GitLab CI 的出錯率。
:::
## Prettier
*.prettierrc*
```json
{
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf"
}
```
## ESLint
統一的 ESLint 設定會存放於特定存放庫 (目前為 <https://gitlab.aservice.com.tw/hepiuscare/common/eslint-config>) 中並發布成 NPM 套件,再於其他專案透過以下方式安裝使用:
```bash
pnpm install -D @his/eslint-config
```
*eslint.config.mjs*
```javascript
import hisEslintConfig from '@his/eslint-config';
export default [...hisEslintConfig];
```
::: info
對於不同專案像是 TypeScript、Angular、NestJS 會有各自的衍伸設定的情況,可將所有設定統一存放於一個存放庫中再讓各專案取用。
目前只有一個版本的設定且尚未完善,後續再透過各位的協助完善此設定
:::