Expo SDK 49アップグレード
以下の記事を参考にして、このアプリのExpo SDKを49にアップグレードしました。 主な変更点とこのアプリで実施したアップグレード手順を紹介します。
- Expo SDK 49. Today we’re announcing the release of… | by Brent Vatne | Exposition
- React Native 0.72 - Symlink Support, Better Errors, and more · React Native
なお、使用される可能性の低いEASとReact Native Webに関する内容は記載しません。
Expo SDK 49の主な変更
React Native v0.72.4
詳細は、以下のリンク先を参照してください。
Reactのバージョンは変更されておらず、依然としてv18.2.0
です。
非推奨となっていた以下のコンポーネントは、React Native v0.72.0
で削除されたことに注意してください。
コミュニティパッケージへの移行が推奨されています。
デバッグ機能の改善
ネットワークデバッグ
アプリがexpo-dev-client
またはExpo Goで実行されるときのネットワークリクエストをJSデバッガーで確認できるようになりました。
React devtoolsとExpo CLIの連携
Shift
+m
を押して「Start React devtools」を選択することで起動できるようになりました。
VS Codeでのデバッグ
Expo Tools Extensionを使用して、VS CodeからアプリのJavaScriptコードを直接デバッグするための実験的なサポートが追加されました。
TypeScript バージョン ^5.1.3
SDK 48までは^4.9.4
が使用されていました。
TypeScript ^5
の詳細は、以下のリンク先を参照してください。
v5.2.2
が使用されないようにするため、^5.1.3
ではなく~5.1.3
指定を推奨します。@typescript-eslint/typescript-estree
(v5
)がv5.1.x
までしかサポートしていません。
const SUPPORTED_TYPESCRIPT_VERSIONS = '>=3.3.1 <5.2.0';
関係するライブラリの依存関係は以下のとおりです。
expo-module-scripts
(v3.0.x
)eslint-config-universe
(v11
)@typescript-eslint
(v5
)
Expoがサポートするライブラリや機能
ライブラリの更新
Expoが管理しているライブラリの内、メジャーバージョンアップなど大きなリリースがあったものを記載します。
- expo-router
v2.0
- sentry-expo
v7.0
- @react-native-community/datetimepicker
v7
- react-native-reanimated
v3
- Reanimated API
v1
のサポートが削除されました。v2
とは互換性があります - 参考:Announcing Reanimated 3. Reanimated 3 release candidate is out…
- Reanimated API
- expo-blur
- デフォルトで静的レンダリング時にぼかしが有効になりました
- expo-face-detector
- Expo Goでの
expo-face-detector
のサポートが削除されましたが、これまでと同様に、Expo Goの外部でライブラリを引き続き使用できます
- Expo Goでの
- expo-gl
- ReanimatedワークレットからGLViewを使用するには、明示的なプロパティ
enableExperimentalWorkletSupport
が必要になりました - 参考:Pull Request #22613 · expo/expo
- ReanimatedワークレットからGLViewを使用するには、明示的なプロパティ
詳細やその他の変更は、以下のリンク先を参照してください。
Expo Module APIの改善
ローカル モジュールが導入されました。 これにより、ライブラリを作成したり、アプリのネイティブ プロジェクトを管理したりせずに、アプリ内でネイティブ コードを作成できるようになります。 SDK 49のプロジェクトで以下のコマンドを実行することで試すことができます。
npx create-expo-module --local
さらに、コンポーネント参照にネイティブの非同期関数を追加できるようになりました。 同期関数はJavaScriptValue、JavaScriptObject、JavaScriptFunctionなどのJS型の引数を受け取ることができるようになりました。
詳細は、JavaScript valuesを参照してください。
(iOSシミュレータ)AppleシリコンによるExpo Goのネイティブ実行サポート
TestFlightビルドを使用して、シミュレータを使用せずにAppleシリコンMac上でExpo Goを直接実行もできます。 ただし、UIの問題がいくつかあるようで、修正が行われています。
Appleシリコン上でネイティブ実行の詳細は、以下のリンク先を参照してください。
開発ビルドフラグ(--dev-client
)の削除
npx expo start --dev-client
の--dev-client
フラグは必要なくなりました。
expo-dev-client
パッケージがプロジェクトにインストールされている場合、デフォルトで開発ビルドがターゲットになります。
キーボードショートカットs
(switch)を使用して、開発ビルドとExpo Goターゲットを切り替えることができます。
これにより、QRコードが指すURLと、キーボードショートカットa
(Android)とi
(iOS)で起動するURLが変更されます。
expo export:embed
Bundle React Native code and images
ビルドフェーズの@react-native-community/cli
バンドルコマンドが置き換わりました。
これにより、カスタムエントリポイントのサポートを追加できるようになりました。
package.json
のmain
を変更して、任意のソースファイルを指すようにできます。
Expo Routerを使用していない場合は、新しいエントリファイルでregisterRootComponentを使用する必要があります。
Expo CLIによるMetro環境変数のサポート
React Nativeエコシステムの既存のアプローチには、変数を更新するためにBabelキャッシュをクリアする必要があるなどの問題がありました。
新しいアプローチでは、プロセスをExpo Metro構成に統合し、JavaScriptエコシステムで一般的な規則に従って環境変数名の接頭辞にPUBLIC
を含めて、これらの問題が解決されます。
SDK 49では、EXPO_PUBLIC_
プレフィックスを付けて.env
や.env.local
などのファイルで変数を定義でき、それらが使用される場合はアプリのJavaScriptに組み込まれます。
詳細は、以下のリンク先を参照してください。
パッケージバージョン検証の選択的オプトアウト
環境によっては、Expoが推奨するバージョンとは異なるパッケージのバージョンを使用したい場合があります。
package.json
のexpo.install.exclude
のキーがサポートされるようになり、expo start
などで行われる検証から除外するパッケージを指定できるようになります。
詳細は、以下のリンク先を参照してください。
scheme (app config)
以前は、追加のschemeを設定するにはConfig Pluginsを使用する必要がありました。 文字列の配列または文字列を使用できるようになりました。
scheme: ['myapp', 'fb1234'],
// or
scheme: 'myapp',
New Architecture/Fabricのサポート
expo-dev-client
でFabricが実験的にサポートされました。
npx create-expo-app@latest -e with-new-arch
で試すことができます。
これにより、新しいアーキテクチャをサポートしていないモジュールはexpo-updates
のみになりました。
Android Expo Modules
Gradle 8を使用するようになりました。
マイグレーションする方法については、以下のリンク先を参照してください。
Expo CLI
すべてのプロジェクトでデフォルトのポート19000ではなく8081を使用するようになりました。
JSCのリモートデバッグ無効化(Expo Goおよびexpo-dev-client
)
JSCリモートデバッグは、Hermesによるデバッグに比べて特にうまく機能することはなく、時間の経過とともに信頼性が低くなってしまいました。
詳細については、以下のReact Nativeへのプル リクエストを参照してください。 これは次のReact Nativeリリースに含まれる予定です。
Expo Constants
Constants.manifest
が非推奨になりました。代わりに、Constants.expoConfig
を使用してください。
詳細は、以下のリンク先を参照してください。
expo-auth-session
expo-auth-sessionのuseProxy
とAuthSession.startAsync
が削除されました。
認証プロバイダーがカスタムschemeにリダイレクトしない問題を回避するために認証プロキシを使用していた場合は、Expo Goから開発ビルドに切り替え、ネイティブSDKの使用が推奨されています。
android:usesCleartextTraffic
システムのデフォルト値を使用するようになりました。
デバッグ ビルドでは明示的にtrue
が設定されますが、他のビルドタイプ(例:リリースビルド)では指定されていません。
つまり、API 27以下ではデフォルトでtrue
、API 28以降ではデフォルトでfalse
になります。
セキュリティで保護されていないエンドポイントへのネットワークリクエストが存在する場合は、expo-build-propertiesを使用してtrue
にする必要があります。
iOS用アイコンの簡素化
Xcode 14以降では自動的にサイズ変更される単一の1024x1024
画像を使用してアプリアイコンを簡素化できます。
そのため、Expoではprebuild時に1024x1024
画像のみを生成するようになりました。
- Xcode 14 Release Notes | Apple Developer Documentation
- feat(prebuild): Generate universal 1024x1024 iOS icon only. by EvanBacon · Pull Request #22833 · expo/expo
Expo SDK 46のサポート終了
Expo SDK 46がサポート対象外になりました。Expo SDK 46を使用している場合は、Expo SDK 47以降にアップグレードする必要があります。
なお、次のリリースではExpo SDK47と48のサポートが終了する見込みのようです。
このアプリで実施したアップグレードの手順
このアプリでは、Expo SDK 48 から 49 にアップグレードする方法を参考に、以下の作業を実施してExpo SDK 49にアップグレードしました。
npm install expo@^49.0.0
を実行して、Expo SDKをアップグレードnpx expo install --fix
を実行して、Expoが管理するライブラリのアップグレード- TypeScript
v5.2.x
ではなくv5.1.x
を使用するためnpm install typescript@~5.1.3
を追加で実行(参考)
- TypeScript
- 既存パッチファイルの更新
jest-expo
のアップグレード- プロジェクトの依存関係に問題がないか確認
- TSCエラーへの対応
- テストコードの修正
- 警告ログへの対応
npm run prebuild
を実行してネイティブプロジェクトの再生成- ビルドエラーの修正
- renovate除外設定更新
- 使用しなくなった
androidx.swiperefreshlayout:swiperefreshlayout
を削除
- 使用しなくなった
- Config Plugins
withAndroidRemoveUsesClearTextTrafficForRelease
を削除 - Proguardルールの更新
- Expoの更新履歴確認と対応
- React Nativeの更新履歴確認と対応
expo-template-blank-typescript
の更新履歴確認と対応expo-template-bare-minimum
の更新履歴確認と対応- React Native Upgrade Helperを参照して、React Nativeの更新を確認
- このアプリで必要な対応は、
expo-template-bare-minimum
の更新で対応されていました
- このアプリで必要な対応は、
- 手動管理しているライセンスの更新
アップグレードを実施したPull Requestはws-4020/mobile-app-crib-notes#1221です。
既存パッチファイルの更新
このアプリでは、patch-packageを使用して、以下のライブラリにパッチファイルを適用していました。 パッチ内容の詳細は、こちらを参照してください。
react-native
@expo/config-plugins
expo-splash-screen
react-native-elements
react-native
に適用していたパッチは、以下のPRで修正されたためパッチフィルを削除しました。
@expo/config-plugins
とexpo-splash-screen
は、Expo SDKのアップグレードに伴いバージョンが上がりました。しかし、適用していたパッチファイルはまだ必要な対応だったため、パッチファイルは削除せずに各ライブラリのバージョンに合わせてファイル名をリネームしました。
react-native-elements
に関しては、バージョンが変わらなかったため変更はありません。
jest-expo
のアップグレード
jest-expo
だけはnpx expo install --fix
でバージョンが上がらなかったので、手動で^49.0.0
に変更しました。
参考: Expo SDK 48アップグレード #jest-expoのアップグレード
プロジェクトの依存関係に問題がないか確認
npx expo-doctor@latest
を実行したところ、以下の実行結果のように@expo/config-plugins
バージョンの問題が検知されました。
✔ Check Expo config for common issues
✖ Check package.json for common issues
✔ Check dependencies for packages that should not be installed directly
✔ Check npm/ yarn versions
✔ Check for common project setup issues
✔ Check Expo config (app.json/ app.config.js) schema
✔ Check for legacy global CLI installed locally
✔ Check that packages match versions required by installed Expo SDK
✔ Check that native modules do not use incompatible support packages
✖ Check that native modules use compatible support package versions for installed Expo SDK
Detailed check results:
Expected package @expo/config-plugins@~7.2.2
Found invalid:
@expo/config-plugins@5.0.4
@expo/config-plugins@5.0.4
(for more info, run: npm why @expo/config-plugins)
Advice: Upgrade dependencies that are using the invalid package versions.
The following scripts in package.json conflict with the contents of node_modules/.bin: orval.
One or more checks failed, indicating possible issues with the project
しかし、前回実施したExpo48への更新から変わらず@react-native-firebase
の更新が必要であるため保留としました。
$ npm ls @expo/config-plugins
santoku-app@1.0.0 /path/to/mobile-app-crib-notes/example-app/SantokuApp
├── @expo/config-plugins@7.2.5
├─┬ @react-native-firebase/app@16.4.6
│ └── @expo/config-plugins@5.0.4
├─┬ @react-native-firebase/crashlytics@16.4.6
│ └── @expo/config-plugins@5.0.4
├─┬ expo-splash-screen@0.20.5
│ └─┬ @expo/prebuild-config@6.2.6
│ └── @expo/config-plugins@7.2.5 deduped
└─┬ expo@49.0.8
├─┬ @expo/cli@0.10.11
│ └── @expo/config-plugins@7.2.5 deduped
├── @expo/config-plugins@7.2.5 deduped
└─┬ @expo/config@8.1.2
└── @expo/config-plugins@7.2.5 deduped
TSCエラーへの対応
npm run lint:tsc
でTypeScriptの型をチェックしました。
DimensionValueの厳密化
react-native
のv0.72.0
ではDimensionの型定義が厳密になりました。
-width?: number | string | undefined;
+width?: DimensionValue | undefined;
export type DimensionValue =
| number
| 'auto'
| `${number}%`
| Animated.AnimatedNode
| null;
style定義の型推論で${number}%
ではなくstring
として認識されてしまう問題が起きたので、as const
を追加しました。
case FaderPosition.TOP:
return {
containerStyle: {...staticStyles.containerTop, height: size},
- imageStyle: {height: size, width: '100%'},
+ imageStyle: {height: size, width: '100%'} as const,
imageSource: gradientTopImage,
};
WebView.onScrollの型定義変更
react-native-webview
のFabric対応でonScroll
の型定義が変更されました。
-onScroll?: (event: WebViewScrollEvent) => void;
+onScroll?: ComponentProps<typeof NativeWebViewComponent>['onScroll'];
これは整理すると以下になります。
-onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
+onScroll?: (event: NativeSyntheticEvent<ScrollEvent>) => void | Promise<void>;
onScroll
の型不一致エラーになったので、以下のように対応しました。
- const handleScroll = useCallback(
- (event: WebViewScrollEvent) => {
+ const handleScroll = useCallback<Exclude<WebViewProps['onScroll'], undefined>>(
+ async event => {
if (isUriChanged && event.nativeEvent.contentOffset.y > 0) {
FunctionComponentの型定義の変更
React.FC
(FunctionComponent
)の返り値の型定義がReactElement
からReactNode
に変更されました。
interface FunctionComponent<P = {}> {
- (props: P, context?: any): ReactElement<any, any> | null;
+ (props: P, context?: any): ReactNode;
type ReactNode =
| ReactElement
| string
| number
| Iterable<ReactNode>
// 略
FlatList
のrenderItem
はReactNode
ではなくReactElement
を要求しているため、型不一致エラーとなりました。
そこで、renderItem
に渡す関数にはReact.FC
を使用しないように変更しました。
return <FlatList data={items} renderItem={AppInfoListItem} keyExtractor={keyExtractor} testID={testID} />;
renderItem: ListRenderItem<ItemT> | null | undefined;
export type ListRenderItem<ItemT> = (
info: ListRenderItemInfo<ItemT>,
) => React.ReactElement | null;
-export const AppInfoListItem: React.FC<AppInfoListItemProps> = ({item}) => {
+export const AppInfoListItem = ({item}: AppInfoListItemProps) => {
テストコードの修正
react-native-reanimated
v3
対応
react-native-reanimated
v3
でディレクトリ構造が変わりました。
それに合わせてimportや型定義ファイルを変更しました。
-react-native-reanimated/lib/reanimated2/
+react-native-reanimated/lib/module/reanimated2/
また、setUpTests()
のimportが短縮できるようになっていたので変更しました。
// https://docs.swmansion.com/react-native-reanimated/docs/guides/testing
-require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests();
+require('react-native-reanimated').setUpTests();
react-native
Dimensionsのmock失敗への対応
Dimensions
がES moduleに変更されました。
-module.exports = Dimensions;
+export default Dimensions;
get Dimensions(): Dimensions {
- return require('./Libraries/Utilities/Dimensions');
+ return require('./Libraries/Utilities/Dimensions').default;
},
そのため、mockする際は__esModule: true
を指定するように変更しました。
jest.doMock('react-native/Libraries/Utilities/Dimensions', () => ({
- get: jest.fn().mockReturnValue({width: 400, height: 1000}),
- set: jest.fn(),
- addEventListener: jest.fn().mockReturnValue({remove: jest.fn()}),
+ __esModule: true,
+ default: {
+ get: jest.fn().mockReturnValue({width: 400, height: 1000}),
+ set: jest.fn(),
+ addEventListener: jest.fn().mockReturnValue({remove: jest.fn()}),
+ },
}));
jest.advanceTimersByTime
をact
でラップ
以下の警告が出るようになっていたため、act
でラップするように変更しました。
- Warning: An update to ForwardRef inside a test was not wrapped in act(...).
- When testing, code that causes React state updates should be wrapped into act(...):
it('SnackbarComponent表示中にpropsでhideを指定した場合、SnackbarComponentが消えることを確認', async () => {
render(<SnackbarComponent message="テストメッセージ" />);
- jest.advanceTimersByTime(FADE_IN_DURATION);
+ await act(() => {
+ jest.advanceTimersByTime(FADE_IN_DURATION);
+ });
expect(screen.queryByText('テストメッセージ')).not.toBeNull();
Constants.manifest
がdeprecatedになったことへの対応
Expo SDK 49の主な変更 - Expoがサポートするライブラリや機能 - Expo Constantsに記載した通り、Constants.manifest
が非推奨になりました。
jest-mock
でもmockする際にスプレッド構文を使用してアクセスすると警告ログが出力されるようになっています。
そのため、スプレッド構文ではなくProxyを使用して上書きするようにしています。
import ExpoConstants from 'expo-constants';
-export const Constants: typeof ExpoConstants = {
- ...ExpoConstants,
+import {wrapProperty} from '../utils/wrapProperty';
+
+export const Constants = wrapProperty(ExpoConstants, {
expoConfig: {
name: 'SantokuApp',
slug: 'santokuApp',
@@ -16,6 +17,6 @@ export const Constants: typeof ExpoConstants = {
mswEnabled: false,
},
},
-};
+});
function hasOwnProperty<T, K extends PropertyKey>(obj: T, propertyKey: K): obj is T & Record<K, unknown> {
return Object.prototype.hasOwnProperty.call(obj, propertyKey);
}
/**
* `{...original, [key]: value}`だとgetterにdeprecated警告ログが存在する場合警告ログが出てしまう問題対策
*/
export function wrapProperty<T extends object>(original: T, propertyObj: object): T {
return new Proxy(original, {
get(target, name, ...rest) {
if (hasOwnProperty(propertyObj, name)) {
return propertyObj[name];
}
return Reflect.get(target, name, ...rest);
},
});
}
アニメーション中のAnimatedStyleの僅かな変化への対応
アニメーション中のtranslateY
の値が以前と僅かに異なっていました。
値が以前と同じことが必須ではなく差分も小さいため、理由の調査はせず、テストコードを更新しました。
@@ -53,7 +53,7 @@ describe('PickerContainer only with required props', () => {
await act(() => {
jest.advanceTimersByTime(DEFAULT_SLIDE_IN_DURATION / 2);
});
- expect(animatedView).toHaveAnimatedStyle({transform: [{translateY: 75}]});
+ expect(animatedView).toHaveAnimatedStyle({transform: [{translateY: 74.00333333333333}]});
expect(sut).toMatchSnapshot('Animating (slide in)');
// アニメーションが完了すると`transform`が設定値に到達していること
@@ -82,7 +82,7 @@ describe('PickerContainer only with required props', () => {
await act(() => {
jest.advanceTimersByTime(DEFAULT_SLIDE_OUT_DURATION / 2);
});
- expect(animatedView).toHaveAnimatedStyle({transform: [{translateY: 75}]});
+ expect(animatedView).toHaveAnimatedStyle({transform: [{translateY: 76.00333333333333}]});
expect(sut).toMatchSnapshot('Animating (slide out)');
// アニメーションが完了するとコンポーネントが消えること
slideOutDurationテストの時間指定が厳密すぎるとテストが失敗する問題の修正
今まではアニメーション終了1ms前のタイミングでアニメーション終了のcallbackが呼ばれないことを期待したテストをしていましたが、callbackが呼ばれるようになっていました。 1msは小さすぎ、誤差の影響と考えられるため10msに変更しました。
@@ -146,14 +146,14 @@ describe('PickerContainer with all props', () => {
sut.update(<PickerContainer isVisible={false} afterSlideOut={afterSlideOut} slideOutDuration={100} />);
await startAnimation();
- // slideOutDurationで指定した時間の1msc前ではafterSlideOutは実行されない
+ // slideOutDurationで指定した時間の10msc前ではafterSlideOutは実行されない
await act(() => {
- jest.advanceTimersByTime(99);
+ jest.advanceTimersByTime(90);
});
expect(afterSlideOut).not.toHaveBeenCalled();
// slideOutDurationで指定した時間経過後は、afterSlideOutが実行される
await act(() => {
- jest.advanceTimersByTime(1);
+ jest.advanceTimersByTime(10);
});
expect(afterSlideOut).toHaveBeenCalled();
});
keyExtractorの呼び出しが増えたことによって失敗するようになったテストの修正
react-native
のFlatList
のkeyExtractor
の呼び出しが増えていました。
2回目にindex=1が呼ばれるのは内部実装に依存していたため、toHaveBeenNthCalledWith
の替わりにtoHaveBeenCalledWith
を使用するようにしました。
expect(flatListProps.contentContainerStyle).toEqual({paddingVertical: 120});
expect(flatListProps.snapToInterval).toBe(60);
- expect(keyExtractor).toHaveBeenNthCalledWith(
- 1,
+ // `value: '1'` だけ2回呼ばれるのでtoHaveBeenNthCalledWithを使用しない
+ expect(keyExtractor).toHaveBeenCalledWith(
{value: '1', label: 'test1', key: 'key1', color: 'red', fontFamily: 'Roboto'},
0,
);
- expect(keyExtractor).toHaveBeenNthCalledWith(
- 2,
+ expect(keyExtractor).toHaveBeenCalledWith(
{value: '2', label: 'test2', color: 'yellow', fontFamily: 'SFProText'},
1,
);
警告ログへの対応
typescript-eslintを現在のTypeScriptバージョンに対応したバージョンへ更新
以下のライブラリがTypeScript~5.1.3
をサポートしていなかったため、バージョンアップしました。
- @typescript-eslint/eslint-plugin
- @typescript-eslint/parser
WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.
You may find that it works just fine, or you may not.
SUPPORTED TYPESCRIPT VERSIONS: >=3.3.1 <5.1.0
YOUR TYPESCRIPT VERSION: 5.1.6
Please only submit bug reports when using the officially supported version.
npm update @typescript-eslint/eslint-plugin @typescript-eslint/parser
JSX namespaceが非推奨になったことへの対応
以下のcommitでJSX
namespaceがReact
namespaceの下に移動され、JSX
は非推奨となりました。
これに対応するためJSX.Element
をReact.JSX.Element
に変更しました。
type SelectPickerItemsTypes<ItemT> = {
selectedValue?: React.Key | ItemT;
- children?: JSX.Element | JSX.Element[];
+ children?: React.JSX.Element | React.JSX.Element[];
items: Item<ItemT>[];
itemHeight: number;
initialScrollIndexの範囲外警告への対応
react-native
v0.72.0
からFlatList
(VirtualizedList
)のinitialScrollIndex
に-1
(負の値)を指定すると警告ログがでるようになりました。
initialScrollIndex "-1" is not valid (list has 0 items)
これは、items
が空かselectedValue
が不正でitems
に含まれてないというレアケースでしか問題になりません。
しかし、テストケースにitems=[]
が存在するため、以下のように-1
のときはnull
にする対応をしました。
@@ -120,7 +120,7 @@ <AnimatedFlatList
renderItem={renderItem}
decelerationRate={DECELERATION_RATE}
getItemLayout={getItemLayout}
- initialScrollIndex={selectedIndex}
+ initialScrollIndex={selectedIndex !== -1 ? selectedIndex : null}
centerContent
testID={flatListTestID}
/>
ビルドエラーの修正
app.notifee:core
を見つけられない問題の対応
npm run android
を実行すると以下のエラーが出ました。
Could not find any matches for app.notifee:core:+ as no versions of app.notifee:core are available.
ワークアラウンドとして、expo-build-properties
プラグインのandroid.extraMavenRepos[]
を追加する必要がありました。
@@ -94,6 +94,10 @@
-keep public class com.horcrux.svg.** {*;}
`,
enableProguardInReleaseBuilds: true,
+ extraMavenRepos: [
+ // notifee Expo49対応: https://github.com/invertase/notifee/issues/808
+ '$rootDir/../../../node_modules/@notifee/react-native/android/libs',
+ ],
},
ios: {
参考Issueは以下です(2023/09時点で未解決)。
Config PluginswithAndroidRemoveUsesClearTextTrafficForRelease
を削除
今までは暗号化してないhttp通信を禁止するために、android:usesCleartextTraffic
を削除するConfig Pluginsを作成し使用していました。
しかし、Expo SDK 49の主な変更 - Expoがサポートするライブラリや機能 - android:usesCleartextTrafficに記載した通り、Expo側で対応されました。 そのため、このConfig Pluginsは不要になったので削除しました。
Proguardルールの更新
各ルールが現在も必要か、コメントのリンク先の更新などが無いかを確認しました。
react-native-svg
用ルールの削除
react-native-svg
v13.7.0
からライブラリ側で自動的にルールを含めるようになりました。
そのため、app.config.js
でexpo-build-properties
プラグインのandroid.extraProguardRules
でルールを追加する必要はなくなったので削除しました。
-keep class expo.modules.ExpoModulesPackageList { *; }
-
-# https://github.com/software-mansion/react-native-svg#problems-with-proguard
--keep public class com.horcrux.svg.** {*;}
`,
enableProguardInReleaseBuilds: true,
Expoの更新履歴確認と対応
ExpoのCHANGELOGを参照して、Expo SDKとExpoが管理するライブラリの更新内容を確認しました。
ここまでの対応以外に追加で必要なものはありませんでした。
React Nativeの更新履歴確認と対応
React NativeのCHANGELOGを参照して、React Nativeの更新内容を確認しました。
ここまでの対応以外に追加で必要なものはありませんでした。
expo-template-blank-typescript
の更新履歴確認と対応
expo-template-blank-typescript
の更新履歴を確認しました。
npm install expo@^49.0.0
、npx expo install --fix
で更新される依存ライブラリのアップグレードが主な変更でした。そのため、このアプリで特別な対応は必要ありませんでした。
expo-template-bare-minimum
の更新履歴確認と対応
このアプリではConfig Pluginsに対応しているので、expo-template-bare-minimum
の更新に伴う個別の対応は基本的に必要ありません。
ただし、以下の場合は個別に対応する必要があるため、この観点に絞ってexpo-template-bare-minimum
の更新履歴を確認しました。
- このアプリで作成しているConfig Pluginsによる変更と、
expo-template-bare-minimum
の更新に伴う変更が競合した場合 - Prebuild時に生成・更新されないファイル
android/
,ios/
以外のファイル(.gitignore
など)
.gitignore
の更新
expo-template-bare-minimum
の以下のコミットで、.gitignore
が更新されていました。
大きな変更は、重複の削除でした。
つまり、Android, Xcode関連ファイルは android/
, ios/
の .gitignore
に記載されているため削除されました。
このアプリにもこの変更を取り込みました。
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-project.xcworkspace
-
-# Android/IntelliJ
-#
-build/
-.idea
-.gradle
-local.properties
-*.iml
-*.hprof
このアプリでは、prebuild時のファイルコピー処理に不具合があり、prebuild/
ディレクトリの一部ファイルがignoreされなくなりました。
不具合はandroid/
,ios/
ディレクトリの.gitignore
がprebuild/
ディレクトリにコピーされないもので、以下のPull Requestで対処しました。
手動管理しているライセンスの更新
このアプリでは、使用しているライブラリのライセンス一覧を出力するスクリプトを用意しています。詳細は、こちらを参照してください。
managed-license.js
の更新
ライセンス情報が不足しており補完したい、あるいは、開発時のみ使用するため除外したいライブラリとバージョンをmanaged-license.jsで管理しています。
ライセンス情報が不足しているライブラリなどは、以下のコマンドを実行することで確認できます。
node .script/check-licenses.js
実行した結果、いくつかのライブラリのライセンス情報を更新する必要があったので以下を実施しました。
- 使用ライブラリの名前更新
- 使用ライブラリのバージョン更新
- 使用ライブラリのライセンスファイルURL更新
- 新規ライブラリ情報の追加
- 使用しなくなったライブラリ情報の削除
新規ライセンスへの対応
このアプリでは、アプリに使用しても問題ないライセンスを管理してチェックできるようにしています。
今回のExpo SDKアップグレードでは、Mozilla Public License 2.0(MPL-2.0
)のライブラリが増えました。
MPL-2.0
は準コピーレフト型ライセンスであり、該当ライブラリ以外のソースコードの公開義務が発生しないため、使用可としました。
そのライセンス名(MPL-2.0
)をcheck-licenses.jsのlicenseWhitelist
に追加しています。