寫一個使用 Rushjs 的起手式,包含設定與安裝
Rush 是一種管理大型存儲庫的工具,尤其適用於處理有多個互相依賴的專案的情況。它是由微軟開發的,並且在開源社區中被廣泛使用。
Rush 的主要功能包括:
- 專案之間的依賴關係管理:Rush 可以幫助你管理在同一個存儲庫中的多個專案之間的依賴關係。這包括確保依賴的版本一致,以及在建構或測試時按照依賴的順序來處理專案。
- 提供一致的開發環境:Rush 可以確保所有的開發者都在同一個版本的 Node.js 和 package manager(如 npm 或 pnpm)下工作,這可以避免因為環境差異而產生的問題。
- 效率:Rush 可以並行地處理多個專案的建構和測試,並且可以只處理那些自從上次成功的建構或測試後有過變更的專案。這可以大幅提升效率,尤其是在大型的存儲庫中。
- 策略:Rush 允許你定義更新和發布的策略。例如,你可以設定某些專案在每次變更後都要發布新版本,或者只有在主要變更時才發布新版本。
Rush 是一種專門為了處理大型的、有多個互相依賴的專案的存儲庫而設計的工具,如果你正在處理這種情況,那麼 Rush 可能會對你有所幫助。
npm install -g @microsoft/rush
cd my-repo //進入專案
rush init //初始化
rush.json
:這是 Rush 的主要設定文件,你可以在這裡設定 Rush 的主要運作方式,例如設定專案的路徑、選擇使用的套件管理工具等。.gitattributes
:如果你使用 Git 作為版本控制系統,這個文件可以告訴 Git 哪些文件(例如 shrinkwrap 文件)不應該被合併。如果你不使用 Git,可以刪除這個文件。.gitignore
:這個文件告訴 Git 哪些文件或資料夾不應該被追蹤。這通常用於排除像是暫存檔、建置輸出或者敏感資訊等。如果你不使用 Git,可以刪除這個文件。.travis.yml
:如果你使用 Travis CI 這個持續整合服務,你可以在這個文件中設定 Travis CI 的運作方式,例如在每次有人對你的專案提出 pull request 時,自動運行 Rush。如果你不使用 Travis CI,可以刪除這個文件。common/config/rush/.npmrc
:這個文件讓 Rush 知道你要使用哪個套件源,無論你使用的是 PNPM、NPM 還是 Yarn。common/config/rush/command-line.json
:這個文件讓你可以自訂 Rush 的命令行指令或參數,讓你能夠更靈活地使用 Rush。(後面有機會會介紹到,如果沒有斷更了話…)common/config/rush/common-versions.json
:這個文件讓你可以指定專案中使用的 NPM 套件的版本,這會影響到 Rush 倉庫中的所有專案。common/config/rush/pnpmfile.js
:如果你使用 PNPM,這個文件可以幫助你解決 package.json 中的依賴問題。如果你不使用 PNPM,可以刪除這個文件。common/config/rush/version-policies.json
:這個文件讓你可以定義發布的設定,例如版本號的規則等。補充一點,.gitattributes
和 .gitignore
都是 Git 的設定文件,但是它們的用途和功能是不同的。總的來說,.gitignore
是用來控制哪些文件應該被 Git 追蹤,而 .gitattributes
是用來控制 Git 如何處理追蹤的文件。
.gitignore
:這個文件的主要用途是告訴 Git 哪些文件或目錄應該被忽略,不應該被追蹤。這通常包括像是編譯產生的二進位文件、日誌文件、個人設定文件或者敏感資訊等。當你在 Git 中新增文件時,.gitignore
中列出的文件或目錄會被自動忽略。.gitattributes
:這個文件的主要用途是設定特定的 Git 屬性到你的專案中的文件或目錄上。這些屬性可以影響 Git 如何處理這些文件或目錄。例如,你可以設定某些文件在合併時應該如何處理,或者設定某些文件的行尾字符如何被儲存等。.gitattributes
提供了相當細緻的控制,讓你可以根據需要來調整 Git 的行為。舉個例子,一個 Node.js 專案中 .gitignore
和 .gitattributes
的範例:
在一個 Node.js 專案中,可能會有以下的 .gitignore
設定:
# 忽略 node_modules 目錄,因為這些都是可以透過 npm install 重新安裝的
node_modules/
# 忽略任何 .env 檔案,因為這些可能包含敏感的環境變數
.env
# 忽略編譯產生的資料夾
dist/
# 忽略 IDE 或編輯器的設定檔
.idea/
.vscode/
*.sublime-project
*.sublime-workspace
# 忽略作業系統生成的檔案
.DS_Store
Thumbs.db
在同一個 Node.js 專案中,可能會有以下的 .gitattributes
設定:
# 確保 Git 輸出的 diff 是人類可讀的
*.diff linguist-vendored
# 將所有的 .js 和 .jsx 檔案視為 LF (換行) 結尾,即使在 Windows 上
*.js eol=lf
*.jsx eol=lf
# 對 minified 的 JavaScript 檔案進行二進位 diff,因為這些檔案的 diff 通常沒有太多的意義
*.min.js diff=binary
在這個例子中,.gitignore
被用來忽略那些不需要加入版本控制的檔案,例如 node_modules
、編譯輸出的 dist
目錄、敏感的 .env
檔案、IDE 的設定檔,以及作業系統生成的檔案。而 .gitattributes
則是用來控制 Git 如何處理特定的檔案。例如,它可以確保所有的 JavaScript 檔案都使用 LF 作為行結尾,即使在 Windows 上,也可以對 minified 的 JavaScript 檔案進行二進位 diff,因為這些檔案的 diff 通常沒有太多的意義。
筆者的習慣是會先建立兩個資料夾,分別為 libraries
和 apps
,將共用的 packages 放在 libraries
裡,而 web 跟 server 就會放在 apps
裡
因為加入 rush 後,套件管理工具會改由 rush 跟 pnpm 接手,所以官網建議將舊專案下的相關文件刪除。(注意!不是刪除根目錄的喔)
例如筆者加入了一個 apps/admin-web 的專案
cd apps/admin-web再來很重要的,要去跟目錄下的
rm -f shrinkwrap.yaml npm-shrinkwrap.json package-lock.json yarn.lock .npmrc .gitattributes .gitignore
rush.json
登記該專案"projects": [接著下命令,來安裝全部專案的依賴套件(pnpm會用魔法處理幽靈依賴、版本衝突…等等一系列可怕的問題)
{
"packageName": "admin-web",
"projectFolder": "apps/admin-web",
"tags": [
"apps"
]
},
{
"packageName": "pos-web",
"projectFolder": "apps/pos-web",
"tags": [
"apps"
]
},
{
"packageName": "api-server",
"projectFolder": "apps/api-server",
"tags": [
"apps"
]
},
{
"packageName": "@bgm/api-contract",
"projectFolder": "libraries/api-contract",
"tags": [
"packages"
]
},
{
"packageName": "@bgm/api-type",
"projectFolder": "libraries/api-type",
"tags": [
"packages"
]
},
{
"packageName": "@bgm/api-dto",
"projectFolder": "libraries/api-dto",
"tags": [
"packages"
]
}
]
rush update
這裡要注意 rush.json
中 packageName 要跟 package.json
中的 name 要一樣,不然會出錯,例如 rush.json
的 packageName 是 admin-web,那 apps/admin-web 的 package.json
中的 name 就要叫 admin-web (看起來像廢話,但筆者在這裡踩過坑...)
rush update
這個命令,rush cli 會去找每個專案的 package.json 把全部專案的依賴套件都檢查一遍,如果需要安裝才會安裝。vite.config.ts
的 server.fs.allow 要設定成 ['../../'] ,可以參考官網(https://vitejs.dev/config/server-options#server-fs-allow)這就是用 monorepo 最核心的地方了,這樣要跨專案開發就方便許多,尤其是單人開發有兩種方式:
cd apps/admin-web
rush add --package @bgm/api-contract
"dependencies": {注意改完 package 的內容,要記得 build 才可以在其他 package 裡面引入喔!
...
"@bgm/api-contract": "workspace:*"
...
}
可以參考官網(https://rushjs.io/zh-cn/pages/advanced/watch_mode/) 的watch 模式,就不用手動按了喔~
補充一個,如果要下載外部的套件,也可以用以上的方法。
隨筆就先到這裡啦~如果有興趣筆者在整理成一系列文章
參考資料:https://rushjs.io/zh-cn/pages/maintainer/setup_new_repo/https://rushjs.io/zh-cn/pages/maintainer/add_to_repo/https://rushjs.io/zh-cn/pages/developer/modifying_package_json/