Expo SDK 47アップグレード
以下の記事を参考にして、このアプリのExpo SDKを47にアップグレードしました。 主な変更点とこのアプリで実施したアップグレード手順を紹介します。
なお、このアプリでは使用していないため、EASやClassic Buildに関する内容は記載しません。
Expo SDK 47の主な変更
React Native 0.70.8 and React 18.1.0
より多くのReact NativeアプリでNew Architectureをサポートしやすくなりました。New Architectureに関する新しいドキュメントも公開されています。
また、このバージョンに含まれるHermesではInternationalization APIsもサポートされています。
詳細は、以下のリンク先を参照してください。
Fabricの実験的サポート
Expo SDK 47でFabricをサポートしている画面ライブラリは以下の3つです。
まだサポートされていない画面ライブラリは以下になります。
上記以外のExpoライブラリは全てNew Architectureと互換性があることを期待できます。
ただし、Managed workflowのアプリにはFabricを有効にする機能がまだありません(Config Pluginsを使用して有効化できますが、推奨されていません)。
Expo Go for iOSのHermesサポート
HermesがExpo Go for iOSで利用できるようになりました。
また、Hermes inspectorをExpo Goや開発ビルドの開発メニューから直接開けるようになりました。これは、Flipperで利用できるデバッガーと同じもので、Flipper SDKやFlipper desktop app使用時のオーバーヘッドなしで利用できます。
なお、Expo SDK 48ではHermesがデフォルトで有効になります。
Config Plugins
expo
パッケージから、@expo/config-plugins
、@expo/config
を再エクスポートするようになりました。
expo
パッケージからインポートすることにより、使用しているExpo SDKのバージョンに依存したConfig Pluginsを使用できます。
そのため、Expo SDK 47からは@
なしのexpo/config-plugins
、expo/config
を使用することが推奨されます。
// Expo SDK 46
import {ConfigPlugin, withPlugins} from '@expo/config-plugins';
import {Platform} from '@expo/config';
// Expo SDK 47
import {ConfigPlugin, withPlugins} from 'expo/config-plugins';
import {Platform} from 'expo/config';
Expoがサポートするライブラリや機能
ライブラリの更新
Expoが管理しているライブラリの内、メジャーバージョンアップなど大きなリリースがあったものを記載します。
- Expo Module API 1.0
- Expo Module APIの最初の安定バージョンがリリースされ、Native Moduleの開発が容易になります(C++のコードを記載することなくFabricに対応できるなど)。
- Expo Router ベータ版
- ファイルシステムベースでルーティング可能なナビゲーションライブラリです。
- React Native Maps(0.31.1 → 1.3.2)
- Apple MapsやGoogle Mapsを表示するライブラリです。変更内容の詳細は、React Native Maps CHANGELOGを参照してください。
非推奨となるライブラリ
以下のライブラリが非推奨となりました。
- expo-firebase-*
- expo-firebase-analytics、またはexpo-firebase-recaptchaを使用している場合、React Native Firebaseに移行することをお勧めします。詳細はMigrating from Expo Firebase to React Native Firebaseガイドを参照してください。
Classic Buildsのサポート終了
Classic Buildsのサポートは終了しました。EAS Buildへの移行はMigrating from "expo build"を参照してください。
app.json
の非推奨となっていた項目の削除
以下の項目がapp.json
から削除されました。
- useNextNotificationsApi
- android.googleSignIn
- ios.merchantId
- ios.googleSignIn
- ios.splash.xib
iOSの最小サポート対象バージョンが13.0に変更
iOSのサポート対象バージョンが13.0以降になりました。
アクティブなデバイスにおける現在のiOSのバージョン分布は、Appleが公開しているApp Storeのデータで確認できます。
Expo SDK 44のサポート終了
Expo SDK 44がサポート対象外になりました。Expo SDK 44を使用している場合は、Expo SDK 45以降にアップグレードする必要があります。
このアプリで実施したアップグレードの手順
このアプリでは、以下の作業を上から順に実施してExpo SDK 47にアップグレードしました。
- Xcode 14にアップグレード
- 開発・CIに使用しているツールのバージョンを更新
npm i -g expo-cli
を実行して、Expo CLIのバージョンを最新化expo-cli upgrade
を実行して、Expo SDKをアップグレード- 既存のパッチファイルの更新
- expo-cli upgradeで更新されるパッケージに依存するパッケージの更新
node_modules
、package-lock.json
を削除して、npm i
を実行- Config Pluginsのimportを
expo/config-plugin
に変更 npm run prebuild
を実行してネイティブプロジェクトの再生成- expo-template-blank-typescriptの更新履歴を確認
- expo-template-bare-minimumの更新履歴を確認
- React Native Upgrade Helperを参照して、React Nativeの更新を確認
- このアプリで必要な対応は、expo-template-bare-minimumの更新で対応されていました。
- Expoの更新履歴を確認
- 一部このアプリで必要な対応がありました。TSCのエラー対応を参照してください。
- React Nativeの更新履歴を確認
- このアプリで必要な対応はありませんでした
- TSCのエラー対応
- 自動テストの修正
- 自動テストのスナップショット更新(
npm run test -- -u
)のみ対応しました
- 自動テストのスナップショット更新(
- 手動管理しているライセンスの更新
アップグレードを実施したPull Requestはこちらです。
開発・CIに使用しているツールのバージョンを更新
Expo SDK 47のアップグレードとは関係ありませんが、このタイミングで開発に使用しているツールのバージョンを更新しました。
Tool | from | to |
---|---|---|
Node.js | 16.18.0 | 18.15.0 |
Java | zulu-11.58.23 | zulu-11.62.17 |
Node.jsの18系へのアップグレードに伴い、npmのバージョンも9系にアップグレードしています。npmの9系では、lockfileVersionに3
が使用されます。
また、CIに使用しているツールのバージョンも更新しました。
Tool | from | to |
---|---|---|
Node.js | 16.18.0 | 18.15.0 |
Xcode | 14.0.1 | 14.2 |
既存のパッチファイルの更新
このアプリでは、patch-packageを使用して、以下のライブラリにパッチファイルを適用していました。パッチ内容の詳細は、こちらを参照してください。
- @expo/config-plugins
- @react-native-community/cli-platform-ios
- expo-splash-screen
- react-native-reanimated
- react-native-elements
react-native-reanimated
に適用していたパッチは、以下のPRで修正されたためパッチフィルを削除しました。
@react-native-community/cli-platform-ios
とexpo-splash-screen
は、Expo SDKのアップグレードに伴いバージョンが上がりました。しかし、適用していたパッチファイルはまだ必要な対応だったため、パッチファイルは削除せずに各ライブラリのバージョンに合わせてファイル名をリネームしました。
上記以外のライブラリに関しては、バージョンが変わらなかったため変更はありません。
expo-cli upgradeで更新されるパッケージに依存するパッケージの更新
Expo SDKのアップグレードに伴い、jest-expo
のバージョンが上がりました。アップグレードされたjest-expo
はreact-test-renderer
の18.1.x
に依存しています。
そのため、このアプリでも依存ライブラリとして追加している@testing-library/react-native
のバージョンを18.1.0
にアップグレードしました。
Config Pluginsのimportをexpo/config-plugin
に変更
Expo SDK 47の主な変更 - Config Pluginsに記載した通り、expo
パッケージから、@expo/config-plugins
、@expo/config
を再エクスポートするようになりました。
それに伴い、このアプリでインポートしている@expo/config-plugins
をexpo/config-plugins
に変更しました。なお、このアプリでは、@expo/config
を使用していません。
// 変更前
import {ConfigPlugin, withPlugins} from '@expo/config-plugins';
// 変更後
import {ConfigPlugin, withPlugins} from 'expo/config-plugins';
expo-template-blank-typescriptの更新履歴を確認
expo-template-blank-typescriptの更新履歴を確認しました。
expo-cli upgrade
で更新される依存ライブラリのアップグレードが主な変更だっため、このアプリで特別な対応は必要ありませんでした。
expo-template-bare-minimumの更新履歴を確認
expo-template-bare-minimumの更新履歴を確認しました。
このアプリではConfig Pluginsに対応したので、expo-template-bare-minimum
の更新に伴う個別の対応は基本的に必要ありません。
ただし、このアプリで作成しているConfig Pluginsによる変更と、expo-template-bare-minimum
の更新に伴う変更が競合した場合は、個別に対応する必要があります。
そのため、上記内容を観点にexpo-template-bare-minimum
を確認しましたが、個別に対応する必要はありませんでした。
TSCのエラー対応
@react-native-datetimepicker/datetimepicker
の以下のPRで型定義が変更されました。
iOSの場合は、date
が削除されています。
その影響で、このアプリのDateTimePicker.ios.test.tsxでTSCエラーが発生しました。
src/bases/ui/picker/DateTimePicker.ios.test.tsx:155:29
- error TS2339: Property 'date' does not exist on type 'Readonly<Readonly<ViewProps & BaseOptions & { maximumDate?: Date | undefined; minimumDate?: Date | undefined; }> & { locale?: string | undefined; ... 7 more ...; disabled?: boolean | undefined; }>'.
155 expect(pickerItemsProps.date).toBe(selectedValue.getTime());
@react-native-datetimepicker/datetimepicker
では、選択された値を取得するためにonChangeを利用します。
そのため、直接date
を参照する必要はないのですが、このアプリでは自動テスト時にdate
を参照して選択した値を検証していました。
date
は外部に非公開となりましたが、@react-native-datetimepicker/datetimepicker
の内部では、date
をネイティブモジュールに渡しています。
自動テスト時の検証としては有効だと考え、以下のように@ts-ignore
を追加してTSCエラーを回避しました。
// ↓の対応で型定義からdateは削除されましたが、react-native-datetimepickerの内部ではdateを使用しているようなので、selectedValueとdateを比較します
// https://github.com/react-native-datetimepicker/datetimepicker/pull/671
// https://github.com/react-native-datetimepicker/datetimepicker/blob/v6.5.2/src/datetimepicker.ios.js#L97
// @ts-ignore
expect(pickerItemsProps.date).toBe(selectedValue.getTime());
手動管理しているライセンスの更新
このアプリでは、使用しているライブラリのライセンス一覧を出力するスクリプトを用意しています。詳細は、こちらを参照してください。
その中で、ライセンス情報が不足しており補完したい、あるいは、開発時のみ使用するため除外したいライブラリとバージョンをmanaged-license.jsで管理しています。
今回のExpo SDKアップグレードでは、managed-license.js
で管理しているMetroのパッケージが更新されたため、アップグレード後のバージョンに併せてライセンス情報を更新しました。