🩹

yarn patch(v3)の使い方

2023/01/11に公開

導入しているnpmのライブラリのコードに何かしらのパッチの修正などを当てたい場合にライブラリをforkなどを行ってパッチを当てたことなどはないでしょうか?

yarn(v3)ではコマンドを打つだけでパッケージの内容にパッチを当てることができます。

今回はyarn(v3)に備わっているnode_modulesに入っているパッケージにパッチを当てる機能のyarn patchの使い方について紹介します。

https://yarnpkg.com/cli/patch

はじめに

アプリ内において、画像の切り抜き機能を実装するにあたって既に他の用途で導入済みであったreact-native-crop-pickerに実装されている切り抜きの機能を使うことにしました。

https://github.com/ivpusic/react-native-image-crop-picker

画像切り抜き時に cancel chooseという項目があります。

変更前の画像

他の画面では日本語を使用しているのでこの部分もキャンセル 選択 という日本語に変更する必要がありました。

yarn patchの使い方

patchを当てたいパッケージを指定する必要があります

今回はreact-native-image-crop-picker のパッケージ名を指定してyarn patchを行います

yarn patch react-native-image-crop-picker

上記のコマンドを行うと以下の内容が出力されます

➤ YN0000: Package react-native-image-crop-picker@npm:0.37.2 got extracted with success!
➤ YN0000: You can now edit the following folder: /private/var/****
➤ YN0000: Once you are done run yarn patch-commit -s /private/var/*** and Yarn will store a patchfile based on your changes.

VSCode上ではCommand(Mac) or Control(Windows) を押しながら /private/var/**** のクリックするとpatchを当てたいパッケージの内容が別ウィンドウで表示されます

今回では画像のクロッピングを行う画面のコードを日本語化するために以下のように変更しました


-  @"cropperCancelText": @"Cancel",
   @"cropperChooseText": @"Choose",
+  @"cropperCancelText": @"キャンセル",
   @"cropperChooseText": @"選択",

patchの内容をcommitをするときに最初に出力されていたyarn patch-commit -s のコマンドを元のウィンドウのターミナルで実行します

yarn patch-commit -s /private/var/***

実行すると差分として.patchのファイルとpatchが当てられたpackage.jsonのresolutionsフィールドへと出力されます
resolutionsフィールドに指定されたパッケージは依存パッケージのバージョンを固定できます。
https://numb86-tech.hatenablog.com/entry/2020/05/26/170627

"react-native-image-crop-picker@0.37.2": "patch:react-native-image-crop-picker@npm:0.37.2#.yarn/patches/react-native-image-crop-picker-npm-0.37.2-3e7e85f166.patch"

.patch

diff --git a/ios/src/ImageCropPicker.m b/ios/src/ImageCropPicker.m
index e308329a0f38b3dc66fc3e0d6a38d9e8f0644b5e..007bad23b31846238ac1a7cbba90110eb2e284b8 100644
--- a/ios/src/ImageCropPicker.m
+++ b/ios/src/ImageCropPicker.m
@@ -70,8 +70,8 @@ RCT_EXPORT_MODULE();
             @"showsSelectedCount": @YES,
             @"forceJpg": @NO,
             @"sortOrder": @"none",
-            @"cropperCancelText": @"Cancel",
-            @"cropperChooseText": @"Choose",
+            @"cropperCancelText": @"キャンセル",
+            @"cropperChooseText": @"選択",
             @"cropperRotateButtonsHidden": @NO
         };
         self.compression = [[Compression alloc] init];

package.json

"es-check@7.0.1": "patch:es-check@npm:7.0.1#.yarn/patches/es-check-npm-7.0.1-e91dd1c337.patch",
"react-native-image-crop-picker@0.38.1": "patch:react-native-image-crop-picker@npm:0.38.1#.yarn/patches/react-native-image-crop-picker-npm-0.38.1-ff481c25da.patch"

パッケージのバージョンの注意点

https://docs.npmjs.com/about-semantic-versioning
注意すべき点としてnpm installyarn addでnpmのライブラリを導入した際にpackage.jsonのdependenciesdevDependenciesに出力されるパッケージのバージョンの表記でメジャーバージョン内でのバージョンアップを許容する場合にはデフォルトでバージョンの左側に^1.1.5 (チルダ)がつけられている場合や
マイナーバージョンのアップデートのみを許容する場合には~1.1.2(キャレット) などの記号がついている場合があります

この時resolutionsフィールドに出力されているパッチを当てたパッケージのバージョンは上記の様に0.38.1単体を指定しているので導入されているパッケージのバージョンに
"react-native-image-crop-picker": "^0.38.1", の様に^~ が含まれていてresolutionsフィールドに表記されているバージョンとpatchを当てたpackage.jsonのバージョンが完全に一致していない場合はpatchの内容が適用されないので注意が必要です。
今回の場合ではresolutionに出力されている"0.38.1"のバージョンにdependencies側のパッケージのバージョンを揃えました。

react-native-image-crop-picker: 0.38.1

今回ではObjective-Cのコードだったのでパッチのコードの適用にyarn install とXcode上でのアプリの再ビルドが必要でした。

JavaScriptやTypeScriptのファイルであればyarn installを行うだけでパッチの適用ができます。

一連の変更とコマンドを行うことで以下のようにテキストが変更されました。

変更前の画像

まとめ

yarn patchを使おうとした時に調べていると、あまり日本語での事例がなかったので今回この記事を書きました。

yarn v3の導入が必須という少しハードルはありますがぜひ使ってみてください。

Discussion