はじめに
業務でreact-native-pdfを使用した際、AndroidではPDFが正常に表示されるのにiOSでは表示されないという問題に遭遇しました。
この記事では、GitHubのissueで共有された解決策であるpatch-packageを使ったパッチ適用方法について解説します。
問題の概要
環境
{
"react-native-pdf": "^6.7.7",
"react-native": "0.80.1",
"react-native-blob-util": "^0.22.2"
}
症状
- Android: PDF表示が正常に動作
- iOS: PDFが表示されない
この問題は、React Native 0.80以降でreact-native-pdfを使用した際に発生することが確認されています。
参考: pdf is not displayed,Android is working fine, but there are problems with iOS #966
解決策: patch-packageを使う
GitHubのissueで@anhnguyen123さんが共有してくれたパッチファイルを適用することで、この問題を解決できます。
1. patch-packageのインストール
まず、patch-packageとpostinstall-postinstallをdevDependenciesとしてインストールします。
# npmの場合
npm install --save-dev patch-package
# yarnの場合
yarn add --dev patch-package postinstall-postinstall
2. package.jsonにpostinstallスクリプトを追加
package.jsonのscriptsセクションに、postinstallスクリプトを追加します。
{
"scripts": {
"postinstall": "patch-package"
}
}
このスクリプトにより、npm installまたはyarn installを実行するたびに、自動的にパッチが適用されます。
3. パッチファイルの配置
GitHubのissueからパッチファイルreact-native-pdf+6.7.7.patchをダウンロードし、プロジェクトルートにpatchesディレクトリを作成してそこに配置します。
your-project/
├── patches/
│ └── react-native-pdf+6.7.7.patch
├── package.json
└── ...
4. パッチの適用確認
依存関係を再インストールして、パッチが正しく適用されることを確認します。
# node_modulesを削除して再インストール
rm -rf node_modules
npm install # または yarn install
正常にパッチが適用されると、ターミナルに以下のようなメッセージが表示されます。
patch-package 8.0.0
Applying patches...
react-native-pdf@6.7.7 ✔
5. iOSのクリーンビルド
パッチ適用後は、iOSのビルドキャッシュをクリアしてから再ビルドします。
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
# キャッシュクリア
npx react-native start --reset-cache
# iOSビルド
npx react-native run-ios
# expo
npx expo run:ios
postinstallとは何か
postinstallは、npmのライフサイクルスクリプトの一つで、npm installコマンドの実行後に自動的に実行されるスクリプトです。
npmライフサイクルスクリプトの順序
preinstall → install → postinstall → prepublish → preprepare → prepare → postprepare
postinstallの主な用途
-
パッチの適用 (今回のケース)
patch-packageを使った依存パッケージの修正
-
ビルドステップの実行
- TypeScriptのコンパイル
- ネイティブモジュールのビルド
-
セットアップタスク
- 設定ファイルの生成
- 環境の初期化
postinstall-postinstallパッケージの役割
yarn v1では、postinstallスクリプトがサブディレクトリのパッケージに対して実行されないという制限があります。postinstall-postinstallパッケージは、この問題を回避するためのワークアラウンドです。
参考: patch-package - Why use postinstall-postinstall
react-native-pdfはなぜパッチを当てる必要があるのか
主な理由
- React Nativeのバージョンアップへの追従遅れ
React Nativeは頻繁にアップデートされますが、サードパーティライブラリの対応が追いつかないことがあります。react-native-pdfも例外ではありません。
- iOS/Androidのプラットフォーム固有の問題
ネイティブコードを含むライブラリは、OS固有の問題に遭遇しやすく、特にiOSではビルドシステムやフレームワークの変更により互換性問題が発生します。
- メンテナンス状況
GitHubのissueを見ると、375個のopenなissuesが存在している(issues)
作者のGithubページを見る限り更新が完全に停止しており、更新頻度よりメンテナなどを立ていないようなので
新規プロジェクトなどはForkされたものなり代替パッケージを使ったほうが良さそう。
- 具体的な技術的問題
- React Native 0.78+での表示問題 (#919)
パッチ適用のメリット・デメリット
メリット
- 即座に問題を解決できる
- フォークを作成する必要がない
- チーム全体で同じ修正を共有できる
- 公式の修正を待つ必要がない
デメリット
- ライブラリのバージョンアップ時に再度パッチが必要になる可能性
- 長期的なメンテナンスコスト
- 大規模な変更には不向き
参考: patch-package - npm (When to use postinstall-postinstall)
自分でパッチを作成する方法
GitHubで共有されているパッチが使えない場合や、独自の修正が必要な場合は、自分でパッチを作成できます。
手順
node_modules内のファイルを直接編集
# 例: iOS関連のファイルを修正
vim node_modules/react-native-pdf/ios/RCTPdf.m
- パッチファイルを生成
npx patch-package react-native-pdf
これでpatches/react-native-pdf+6.7.7.patchというファイルが自動生成されます。
- Gitにコミット
git add patches/react-native-pdf+6.7.7.patch
git commit -m "fix: iOSでPDFが表示されない問題を修正"
- チームメンバーへの共有
チームメンバーがnpm installまたはyarn installを実行すると、自動的にパッチが適用されます。
参考: Comprehensive Guide to Patching React Native Packages
まとめ
react-native-pdfのiOS表示問題はpatch-packageで解決できるpostinstallスクリプトを使うことで、チーム全体で自動的にパッチを適用できる- ライブラリのメンテナンス状況によっては、パッチ適用が現実的な解決策となる
- 長期的には公式の修正を待つか、代替ライブラリの検討も視野に入れる