一個專案在自己手上如火如荼地進行開發時,會感覺自己對這包 code 的裡外內容無所不知、無所不曉。但是 ⋯⋯
在熱戀期結束後的某一天,你收到一張票,要給這個半年間都不聞不問的老相好加上一點新功能。現在這包 code 陌生的彷彿農曆新年才會見到的遠房親戚。
你甚至需要認真思考十分鐘,才能確定這個新功能該跟誰拿資料、又該寫在哪個元件裡比較好。
上面是有點誇張。不過就算你天生記憶力過人,總是會有請假、或是經歷「總之就是需要其他人來看你 code」的時刻。
此時一份好的 README 可以幫助所有人更快理解這個專案——這就是今天的主題:來介紹一下個人通常會在 README 提供哪些內容。
以下是個人撰寫 README 時常用的大綱:
# 專案名稱
## 簡介
## 快速啟動
## 資料夾結構
## 基礎設施
## (選填)系統架構、設計模式
## 腳本詳細說明
## 其他
在此寫下專案的大名。
⋯⋯ 還有比專案名更適合放在 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 我熟得很」「這件事情我不可能會忘記」)。
不過當時間久了、或是整包專案即將易手維護的話,如果有一份指南來告訴下一位維護者(或是半年後的你)整個專案的結構、以及可能有哪些坑需要注意的話——個人覺得這份文件還是值得投資一點時間來撰寫的 ρ(・ω・、)
本文同步發佈於普通文組 2.0