捨棄 create-react-app 之餘還架了個 astro blog 昭告天下:寫文件

一個專案在自己手上如火如荼地進行開發時,會感覺自己對這包 code 的裡外內容無所不知、無所不曉。但是 ⋯⋯

在熱戀期結束後的某一天,你收到一張票,要給這個半年間都不聞不問的老相好加上一點新功能。現在這包 code 陌生的彷彿農曆新年才會見到的遠房親戚。

你甚至需要認真思考十分鐘,才能確定這個新功能該跟誰拿資料、又該寫在哪個元件裡比較好。

cat loading meme

上面是有點誇張。不過就算你天生記憶力過人,總是會有請假、或是經歷「總之就是需要其他人來看你 code」的時刻。

此時一份好的 README 可以幫助所有人更快理解這個專案——這就是今天的主題:來介紹一下個人通常會在 README 提供哪些內容。

本文

以下是個人撰寫 README 時常用的大綱:

# 專案名稱

## 簡介

## 快速啟動

## 資料夾結構

## 基礎設施

## (選填)系統架構、設計模式

## 腳本詳細說明

## 其他

專案名稱

在此寫下專案的大名。

say my name

⋯⋯ 還有比專案名更適合放在 h1 的內容嗎?

簡介

通常會在這裡寫一些「就算之前對這個專案一無所知,看到這一行也會有點基本概念」的東西。不需要在這裡長篇大論,詳細說明可以安排在 README 下方慢慢補充。

比如 Normal Reader 2.0 是查理的技術部落格專案 或是 Artemis 是(產品X)的帳號權限管理專案

快速啟動

在這裡說明可以馬上啟動專案的終端指令,比如以下:

nvm use
make i
cp .env.example .env
make start

如果需要對指令追加補充說明,個人通常會將這些內容放到「腳本詳細說明」區塊。

資料夾結構

個人認為繼「快速啟動」後,能夠最快讓「對這包 code 完全沒概念的人」進入狀況的說明欄位。

第 4 天的專案結構為例,個人通常會搭配以下說明:

.
├── README.md               # 專案的說明檔
├── config                  # 專案啟動、打包用的 webpack 設定檔
├── doc                     # 內容較長的專案說明,會從 README 切分至此資料夾
├── package.json            # 專案的 package 設定檔
├── public                  # 放置靜態檔案,包含 index.html 與 favicon 等內容
├── script                  # 放置專案的啟動、打包腳本
├── src
   ├── api                 # 收納於 React app 內使用的 api 設定與路由
   ├── asset               # 收納於 React app 內使用的靜態資源
   ├── component           # 收納 React app 使用到的元件
   ├── AppEntryPoint   # 最終掛載到 src/index.tsx 的主元件
   ├── Common          # 收納一般的 react 元件,若該元件有更強烈的 Layer/Layout/Page 特徵,請將之歸納到合適的資料夾
   ├── Layer           # 處理商業邏輯的元件層,這類元件可能不會有外觀
   ├── Layout          # 處理排版的元件,這類元件通常不會包含太多邏輯計算內容
   └── Page            # 根據路由來切分的大元件,如果可以,請將其內容合理地分拆為子元件
   ├── env.d.ts            # 有需要時,請在此宣告或覆蓋全域 TypeScript 定義
   ├── hook                # 收納各類 react custom hook
   ├── index.tsx           # 整個 React app 的主入口
   ├── model               # 收納 React app 中的純資料、以及搭配 React redux 用的資料實例
   ├── reducer             # 收納 React app 的 React redux reducer 相關內容
   ├── style               # 收納 React app 的樣式設定
   └── tool                # 收納在 React app 使用的通用功能
├── tool                    # 放置整個專案通用的小工具
├── tsconfig.json           # 專案的 TypeScript 設定檔
└── yarn.lock               # 執行套件安裝時,說明套件間依賴性的文件

以上說明能作為地圖,讓一個初次接觸這個專案對於「該去哪裡找什麼」有點概念。

比起從 ./src/index.tsx 慢慢翻、或是透過 class name 來反查元件,了解(且遵守)「分類的原則」比較能維持專案的程式碼品質。

基礎設施

個人習慣在此區塊說明啟動專案的基本要求。內容可能如下:

- Node.js: `lts/gallium`
- Package Manager: `yarn`

系統架構或設計模式

在專案規模逐漸擴增後,整包 code 可能會發展為「使用 event driven 的風格來實作」或「採用 singleton 的方式來實作邏輯」。除了提示新加入的維護者如何理解專案內容外,也可做為開發時的軟性規範。

腳本詳細說明

在啟動腳本多的專案(比如含有啟動、測試、資料匯入、打包、報表輸出、部署等等功能完全不同;且可能額外搭配 command line flag 操作的指令),個人傾向在 README 中花一點篇幅介紹各類指令的操作方式。比如:

# 執行單元測試
make test

# 透過 option 將終端指令轉交給 jest,比如以下 make test option=-u 效力等同 yarn jest -u
make test option=-u

如果你真的好好寫了一篇 README,甚至可以把向你請教指令用法的問題丟回去給發問的人。

其他

如果你發現 README 開始長到沒有人想看完它,可以考慮將比較詳細的說明內容搬移到 ./doc 資料夾,並在 README 留下目錄以及問題關鍵字,讓未來有需要的人(很有可能是你自己)能夠查看是否有說明文、或是解決辦法。

總結

寫文件的確不太有趣、也非常消耗腦力。開發(手感正熱)的當下大概也感受不到文件能幫到什麼忙(「這包 code 我熟得很」「這件事情我不可能會忘記」)。

不過當時間久了、或是整包專案即將易手維護的話,如果有一份指南來告訴下一位維護者(或是半年後的你)整個專案的結構、以及可能有哪些坑需要注意的話——個人覺得這份文件還是值得投資一點時間來撰寫的 ρ(・ω・、)