Bunでパッチを当てるためにpatch-packageを動かす方法
Turborepo + Bun + ElysiaJS + Nextのモノレポ構成を試していたらパッチが必要になる場面に出くわしたので、その対処法を共有します!
色々試してみた結果、patch-package
でpatch-package
自体をパッチして、呼び出されるパッケージマネージャーをyarn
からbun
に書き換えると、うまく動作することがわかりました。(yarn
なしのローカル環境、GitHub Actions、Vercelで動作確認済みです!)
手順
1. BunでYarnのロックファイルを生成するように設定する
bun install --yarn
のように--yarn
フラグを指定するか、以下の行をbunfig.toml
に追加して、yarn.lock
ファイルを生成するようにします。
これは、現在patch-package
がBunのバイナリロックファイル形式をサポートしていないため必要です。(https://github.com/ds300/patch-package/issues/489 参照)
[install.lockfile]
print = "yarn" # bun.lockbと並行して非Bunロックファイルを生成するかどうか
[!WARNING]
依存関係を更新するたびにYarn v1のロックファイルを生成する必要があるため、個人的には後者のオプションをおすすめします。
patch-package
をインストールする
2. patch-package
を開発依存関係に追加します。
bun add -D patch-package
patch-package
のソースファイルを手動で変更する
3. node_modules/patch-package/dist/makePatch.js
を開き、yarn
を呼び出しているspawnSafe_1.spawnSafeSync
を探して、以下のdiffのようにbun
に置き換えます。
diff --git a/node_modules/patch-package/dist/makePatch.js b/node_modules/patch-package/dist/makePatch.js
index d8d0925..874284a 100644
--- a/node_modules/patch-package/dist/makePatch.js
+++ b/node_modules/patch-package/dist/makePatch.js
@@ -120,7 +120,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
try {
// try first without ignoring scripts in case they are required
// this works in 99.99% of cases
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install"], {
cwd: tmpRepoNpmRoot,
logStdErrOnError: false,
});
@@ -128,7 +128,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
} catch (e) {
// try again while ignoring scripts in case the script depends on
// an implicit context which we haven't reproduced
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines", "--ignore-scripts"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install", "--ignore-scripts"], {
cwd: tmpRepoNpmRoot,
});
}
[!NOTE]
現在、Bunはpackage.json
のengines
フィールドをサポートしていないため、--ignore-engines
フラグを削除しても問題ありません。(https://github.com/oven-sh/bun/issues/5846 参照)
patches/
に保存する
4. 作成したパッチを以下のコマンドを実行して、パッチファイルを作成します。
bun patch-package patch-package
これで、patches/patch-package+8.0.0.patch
が作成されるはずです。
package.json
にpostinstall
スクリプトを追加する
5. patch-package
のドキュメントに記載されているように、以下のスクリプトをpackage.json
に追加します。
{
"name": "reoiam-dev",
"version": "0.0.0",
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"postinstall": "patch-package"
}
}
6. 目的のパッケージにパッチを適用する
bun patch-package your-package-name
また、git clean -dfX && bun i
を実行して、正常に動作していることを確認してください。
これがお役に立てば幸いです!👀
例となるコミット:
Discussion