React Native Androidビルド失敗問題(0.71.0-rc.0関連)
問題概説
2022年11月上旬から、React NativeプロジェクトでAndroidビルドが突然失敗するケースが多数報告されました。この問題の特徴は以下の通りです:
- コード変更なしで突然ビルドが失敗する
- エラー内容は様々だが、主な共通点はReact Nativeバージョン
0.71.0-rc.0
への誤った依存 - 典型的なエラーメッセージ例:
FAILURE: Build failed with an exception.
* Where:
Build file '/node_modules/react-native-month-year-picker/android/build.gradle' line: 115
* What went wrong:
Could not resolve all files for configuration ':react-native-month-year-picker:implementation'.
> Could not resolve com.facebook.react:react-native:+.
> Cannot choose between the following variants:
- debugVariantDefaultRuntimePublication
- releaseVariantDefaultRuntimePublication
問題の本質
React Nativeチームが0.71.0-rc.0
をMavenリポジトリに公開したことで、一部のサードパーティライブラリが誤ってこのバージョンを取得しようとすることが原因です。多くのライブラリのbuild.gradle
でimplementation 'com.facebook.react:react-native:+'
という依存指定があり、ここで+
は「最新バージョン」を意味します。
解決方法
方法1: exclusiveContent
を使用した解決(推奨)
プロジェクトのandroid/build.gradle
ファイルに専用の依存解決ルールを追加します:
allprojects {
repositories {
exclusiveContent {
// com.facebook.reactグループはnode_modulesのみから取得
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url "$rootDir/../node_modules/react-native/android"
}
}
}
// 他のリポジトリ設定(Google、Maven Centralなど)
// ...
}
}
メカニズム解説
この設定により:
com.facebook.react
グループ関連の依存は専用ルールの対象に- 指定されたMavenリポジトリ(node_modules内)のみから取得
- 外部リポジトリ(Maven Centralなど)からの取得をブロック
修正後に実行するクリーンコマンド:
cd android
./gradlew clean
方法2: 明示的なバージョン固定
exclusiveContent
がサポートされない古いGradle環境向けの方法:
def REACT_NATIVE_VERSION = new File(['node', '--print',
"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"
].execute(null, rootDir).text.trim())
allprojects {
configurations.all {
resolutionStrategy {
// react-nativeのバージョンを明示的に固定
force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
}
}
}
REACT_NATIVE_VERSIONの取得方法
このスクリプトで自動的にpackage.json
からReact Nativeバージョンを取得:
const version = require('react-native/package.json').version;
方法3: React Nativeのパッチバージョンへアップグレード
React Nativeチームが対策済みバージョンをリリースしています。該当バージョンにアップグレードするのが根本的な解決策です:
元のバージョン | 修正バージョン |
---|---|
0.63.x | 0.63.3 |
0.64.x | 0.64.3 |
0.65.x | 0.65.2 |
0.66.x | 0.66.5 |
0.67.x | 0.67.5 |
0.68.x | 0.68.6 |
0.69.x | 0.69.8 |
0.70.x | 0.70.6 |
アップグレードコマンド例:
npm install react-native@0.68.6
技術的背景と原因詳細
なぜ問題が発生するか?
多くのサードパーティライブラリの構成:
repositories {
maven {
url "$rootDir/../node_modules/react-native/android"
}
google()
mavenCentral() // ここに0.71.0-rc.0が登場
}
dependencies {
implementation 'com.facebook.react:react-native:+' // 「最新」を指定
}
0.71.0-rc.0
公開前:node_modules
内のバージョンが「最新」0.71.0-rc.0
公開後:Maven Centralのバージョンが「最新」に- 結果:利用中のRNバージョンと0.71.0-rc.0が競合
Kotlinバージョン不一致が派生する理由
React Nativeのバージョン差異がKotlinのバージョン不一致を引き起こすケース:
Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin.
The binary version of its metadata is 1.6.0, expected version is 1.4.1.
これは、React Native 0.68以降でKotlinバージョンが1.6.10にアップグレードされたため、0.71.0-rc.0取得時にKotlinの互換性が崩れるためです。
ベストプラクティス
一時的な対処より恒久的な解決を
- 可能な限りパッチバージョンへのアップグレードを選択
- サードパーティライブラリ開発者は
+
ではなく固定バージョン指定を推奨
一般的なbuild.gradle
設定改善例:
dependencies {
// 代替案1: 固定バージョン指定
implementation 'com.facebook.react:react-native:0.68.6'
// 代替案2: project経由の指定
implementation project(':react-native')
}
根本原因
React NativeのMaven公開プロセスの変更:
まとめ
対策方法 | メリット | 注意点 |
---|---|---|
exclusiveContent の追加 | プロジェクト全体に影響なく修正可能 | Gradleのバージョンに依存 |
バージョン固定 | 古いGradle環境でも動作 | バージョン管理スクリプト必要 |
RNパッチバージョンへのアップグレード | 根本解決 | RNバージョンアップ作業が必要 |
どの解決方法を選ぶ場合も、android
ディレクトリで以下のクリーン操作を必ず実施してください:
./gradlew clean
正式なアップデート情報や詳細な技術的な議論は、React NativeのGitHub Issuesで確認可能です: