bun --filter
使用 --filter 標誌在 monorepo 中按模式選擇包
--filter(或 -F)標誌按模式選擇 monorepo 中的包。模式可以是包名稱 glob、./path glob、{dir} 目錄選擇器或 ... 相依關係。
該標誌可與 bun run、bun install、bun add、bun remove、bun update、bun outdated、bun prune 和 bun pm licenses 一起使用。對於套件管理器命令,請將標誌放在子命令之後(bun install --filter api),因為 bun --filter <pattern> <word> 會將 <word> 作為指令碼執行。
匹配
包名 --filter <pattern>
名稱模式根據 package.json 中的 name 欄位選擇包。例如,如果有包 pkg-a、pkg-b 和 other,可以使用 * 匹配所有包,使用 pkg* 僅匹配 pkg-a 和 pkg-b,也可以使用包的完整名稱匹配指定包。
包路徑 --filter ./<glob>
路徑模式以 ./ 開頭,並選擇目錄中匹配該模式的所有包。例如,要匹配 packages 子目錄中的所有包,請使用 --filter './packages/**'。要匹配 packages/foo 中的包,請使用 --filter ./packages/foo。
名稱模式匹配完整的包名稱(core 不會匹配 @acme/core;請使用 @acme/*),並且 * 不會跨越 /。路徑模式必須匹配工作區目錄本身:./packages 不會選擇任何內容,./packages/* 會選擇其中的每個直接工作區。
目錄 --filter '{<dir>}'
大括號中的目錄會選擇該目錄中或其任意下級目錄中的所有工作區,目錄路徑相對於當前目錄解析。--filter '{packages}' 會選擇 packages/ 下的所有內容;--filter '{.}' 會選擇當前目錄的工作區及其下的所有內容。
相依關係 --filter 'foo...'
在模式後新增 ...,還會選擇通過工作區相依關係關聯的工作區:
| 模式 | 選擇 |
|---|---|
foo... | foo 及其直接或傳遞相依的工作區 |
foo^... | foo 直接或傳遞相依的工作區,不包括 foo 本身 |
...foo | foo 及直接或傳遞相依於它的工作區 |
...^foo | 直接或傳遞相依於 foo 的工作區,不包括 foo 本身 |
foo 可以是名稱 glob 或目錄選擇器(...{./packages/api})。要排除內容,請將 ! 放在最前面:--filter '!...foo'。
bun install --filter 'web...'
bun add zod --filter '...^ui'
bun outdated --filter '{./packages/apps}'
bun install 和 bun outdated
預設情況下,bun install 會為 monorepo 中的每個包安裝相依。要為特定包安裝相依,請使用 --filter。
多個 --filter 標誌會組合使用:選擇所有與正向模式匹配的內容,再排除與 ! 模式匹配的內容。沒有匹配任何內容的模式會列印警告。對於 bun add、bun remove、bun update、bun prune 和 bun pm licenses,如果完全沒有選擇工作區,則會報錯。
對於 ./packages 下包含工作區 pkg-a、pkg-b 和 pkg-c 的 monorepo:
# 安裝除 `pkg-c` 以外所有工作區的相依
bun install --filter '!pkg-c'
# 安裝 `./packages` 目錄下的包(`pkg-a`、`pkg-b`、`pkg-c`)的相依
bun install --filter './packages/*'
# 與上面相同,但排除根目錄 package.json
bun install --filter '!./' --filter './packages/*'
同樣,bun outdated 會顯示 monorepo 中所有包的過期相依,而 --filter 會將命令限制為其中的部分包:
# 顯示名稱以 `pkg-` 開頭的工作區的過期相依
bun outdated --filter 'pkg-*'
# 僅顯示根目錄 package.json 的過期相依
bun outdated --filter './'
請參閱 bun install 和 bun outdated。
使用 --filter 執行指令碼
使用 --filter 標誌可以一次在多個包中執行指令碼:
bun --filter <pattern> <script>
假設你有一個包含兩個包的 monorepo:packages/api 和 packages/frontend,它們都有一個用於啟動本地開發伺服器的 dev 指令碼。通常,你需要開啟兩個終端標籤頁,分別切換到每個包的目錄,然後執行 bun dev:
cd packages/api
bun dev
# 在另一個終端
cd packages/frontend
bun dev
使用 --filter,你可以同時在這兩個包中執行 dev 指令碼:
bun --filter '*' dev
兩個指令碼會並行執行,終端 UI 會顯示它們各自的輸出:
其他模式形式的用法相同:
# build web and everything it depends on, in dependency order
bun --filter 'web...' build
# test the packages that depend on ui
bun --filter '...^ui' test
# run dev in every package under packages/apps
bun --filter '{./packages/apps}' dev
# lint every package except docs
bun --filter '*' --filter '!docs' lint
只有 ./path 模式可以選擇沒有 name 的 package.json。如果選中的包都沒有該指令碼,bun run 會以錯誤退出(傳入 --if-present 則會以 0 退出)。
在工作區中執行指令碼
過濾器遵循你的工作區設定:如果你的 package.json 指定了哪些包屬於工作區,--filter 只會匹配這些包。在工作區中,--filter 還可以執行位於工作區任意位置的包中的指令碼:
# 包結構
# src/foo
# src/bar
# 在 src/bar 中:執行 src/foo 的 myscript,無需切換目錄!
bun run --filter foo myscript
並行和順序模式
結合 --filter 或 --workspaces 與 --parallel 或 --sequential,可以跨工作區包執行指令碼,並帶有 Foreman 風格的字首輸出:
# 並行執行所有匹配包的 "build"
bun run --parallel --filter '*' build
# 順序執行所有工作區包的 "build"
bun run --sequential --workspaces build
# 在所有包中執行符合萬用字元的指令碼
bun run --parallel --filter '*' "build:*"
# 即使某個包的指令碼失敗,也繼續執行其他指令碼
bun run --parallel --no-exit-on-error --filter '*' test
# 在所有包中執行多個指令碼
bun run --parallel --filter '*' build lint
Bun 會在每行輸出前加上包名和指令碼名(pkg-a:build | ...)。如果沒有使用 --filter/--workspaces,則只會加上指令碼名作為字首(build | ...)。如果某個包的 package.json 沒有 name 欄位,Bun 會改用相對於工作區根目錄的路徑。
將 --if-present 與 --workspaces 一起使用,可以跳過沒有指定指令碼的包,而不報錯。
相依順序
Bun 會在執行指令碼時遵循包的相依順序。假設你有一個包 foo,它相依於工作區中的另一個包 bar,並且兩者都有一個 build 指令碼。當你執行 bun --filter '*' build 時,只有在 bar 完成後,foo 才會開始執行。