初めまして! N Inc. 共同創業者でエンジニアの北方(@Yk_0n)です。
今回は、npm パッケージに安全にパッチを当てることができる patch-package
というツールを紹介したいと思います!
前回の記事をまだご覧になっていない方は、ぜひこちらもご覧ください!
GitHub Actions を使って push だけで npm に公開 & CHANGELOG 更新する仕組みを作ろう!
patch-package とは
patch-package とは、npm パッケージに安全にパッチを当てることができるツールです。弊社でもフロントエンドのパッケージなどのパッチに使用しています!
https://github.com/ds300/patch-package
patch-package を使うメリット
npmパッケージにパッチを当てたいとなった時に、patch-packageを使わない方法としては、
- 手動でpatchを作成し適用する
- forkしてgitからインストールする
の2つがあるかと思います。
まず、1つ目の「手動でpatchを作成し適用する」の方法だと、npmパッケージのバージョンが変化した際に確認が難しくなる、チームでパッチを適用してもらう必要があるなどのデメリットがあります。
2つ目の「forkしてgitからインストールする」では、npmパッケージが公式ではないため、Dependabotなどのアップデート情報を自動取得するのが難しいというデメリットがあります。
これらの方法でデメリットとして挙げた問題については、patch-packageを使用することで解決することができます。
patch-package の使い方
早速ですが、patch-packageの使い方を紹介していきたいと思います。
インストール
まず、以下のコマンドでpatch-packageをインストールします。
npmの場合
npm i patch-package
yarnの場合
yarnの場合、 postinstall-postinstall
というパッケージが必要になります。
これは、yarn特有の yarn add
や yarn remove
時に postinstall
が呼び出されない動作を修正するためです。
yarn add patch-package postinstall-postinstall
いずれの場合も、フロントエンドなどでプロダクションの環境ではnpmパッケージにパッチを当てる必要がない場合は devDependencies
でも問題ありません。
インストールが完了したら、 package.json
の scripts
に以下を追加します。
"scripts": {
"postinstall": "patch-package"
}
postinstall
で patch-package
を呼び出すことで、インストールされるたびに、対象のnpmパッケージにパッチを適用してくれます。
npmパッケージの編集
まず、パッチ前のnpmパッケージを、npm
や yarn
を用いて通常通りインストールします。
次に、 node_modules
配下にインストールされた対象のパッケージを編集します。
今回はデモとして、 axios
のパッケージにパッチを当ててみたいと思います。
まずは、axios
のファイルを探すため、 node_modules/axios/package.json
を開いてみると、 index.js
がエントリーポイントであることがわかります。
今回は、エントリーポイントの index.js
に console.log
を追加して書き換えられているか確認することにします。
画像のように、エントリーポイントに console.log("patched!");
を追加してみました。
この状態で、 axios
をインポートすると、以下の画像のように patched!
と表示されます。
このような感じで、 node_modules
配下のオリジナルのnpmパッケージを編集します。
パッチを生成する
npmパッケージを編集したら、以下のコマンドを実行します。
npm run patch-package <パッケージ名>
もしくは
yarn patch-package <パッケージ名>
このコマンドを実行することで、 patch-package
がオリジナルのパッケージとローカルの node_modules
を比較し、patchを自動生成してくれます!
今回は、 axios
のパッチを生成するので yarn patch-package axios
を実行してみます。
成功すると、patches/<npmパッケージ名>+<バージョン>.patch
にパッチが生成されます!
patch-package <npmパッケージ名>
を実行するだけで、サクッとパッチが生成できるのも patch-package
の魅力です!
パッチが適用されるか確認する
生成したパッチがきちんと適用されるか確認してみます。
一度、 以下のコマンドで node_modules
を削除して再度インストールしてみます。
rm -rf node_modules
削除したら npm install
もしくは yarn install
を実行して、通常通り npmパッケージをインストールしてみます。
すると、画像のように、パッチを適用したよ!と表示されるはずです。
この状態で、axios
をインポートすると、先ほどの変更が適用されていることがわかります!
npmのバージョンが変化した場合
パッチを生成したnpmパッケージのバージョンが、パッチ生成時と異なる場合の挙動を検証してみます。
試しに、 先ほど試した axios
のバージョンと異なる [email protected]
をインストールしてみると、以下のように表示されます。
今回は問題なくパッチが適用されたため、警告として表示されています。
このように、バージョンが異なる場合もパッチが適用できる場合は、警告を表示しつつパッチを適用してくれます。
パッチが適用できない場合は、ローカル環境ではデフォルトで正常終了、CI環境では異常終了(exit 1)するようになっているようです。
この挙動は --error-on-fail
オプションで変更が可能です。
まとめ
今回は、 patch-package の紹介と簡単な使い方を紹介しました。この機能のバージョンを使用したいけど、一部分だけバグっているなどの場合に、かなり役立つツールだと思います。
使用しているnpmパッケージにパッチを当てたいな〜という時には、patch-packageの存在を思い出してみてください!