Skip to content

React Native Androidビルド失敗問題(0.71.0-rc.0関連)

問題概説

2022年11月上旬から、React NativeプロジェクトでAndroidビルドが突然失敗するケースが多数報告されました。この問題の特徴は以下の通りです:

  • コード変更なしで突然ビルドが失敗する
  • エラー内容は様々だが、主な共通点はReact Nativeバージョン0.71.0-rc.0への誤った依存
  • 典型的なエラーメッセージ例:
log
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.gradleimplementation 'com.facebook.react:react-native:+'という依存指定があり、ここで+は「最新バージョン」を意味します。

解決方法

方法1: exclusiveContentを使用した解決(推奨)

プロジェクトのandroid/build.gradleファイルに専用の依存解決ルールを追加します:

groovy
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など)
        // ...
    }
}

メカニズム解説

この設定により:

  1. com.facebook.reactグループ関連の依存は専用ルールの対象に
  2. 指定されたMavenリポジトリ(node_modules内)のみから取得
  3. 外部リポジトリ(Maven Centralなど)からの取得をブロック

修正後に実行するクリーンコマンド:

bash
cd android
./gradlew clean

方法2: 明示的なバージョン固定

exclusiveContentがサポートされない古いGradle環境向けの方法:

groovy
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バージョンを取得:

javascript
const version = require('react-native/package.json').version;

方法3: React Nativeのパッチバージョンへアップグレード

React Nativeチームが対策済みバージョンをリリースしています。該当バージョンにアップグレードするのが根本的な解決策です:

元のバージョン修正バージョン
0.63.x0.63.3
0.64.x0.64.3
0.65.x0.65.2
0.66.x0.66.5
0.67.x0.67.5
0.68.x0.68.6
0.69.x0.69.8
0.70.x0.70.6

アップグレードコマンド例:

bash
npm install react-native@0.68.6

技術的背景と原因詳細

なぜ問題が発生するか?

多くのサードパーティライブラリの構成:

groovy
repositories {
    maven {
        url "$rootDir/../node_modules/react-native/android"
    }
    google()
    mavenCentral()  // ここに0.71.0-rc.0が登場
}

dependencies {
    implementation 'com.facebook.react:react-native:+'  // 「最新」を指定
}
  1. 0.71.0-rc.0公開前:node_modules内のバージョンが「最新」
  2. 0.71.0-rc.0公開後:Maven Centralのバージョンが「最新」に
  3. 結果:利用中のRNバージョンと0.71.0-rc.0が競合

Kotlinバージョン不一致が派生する理由

React Nativeのバージョン差異がKotlinのバージョン不一致を引き起こすケース:

log
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設定改善例:

groovy
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ディレクトリで以下のクリーン操作を必ず実施してください:

bash
./gradlew clean

正式なアップデート情報や詳細な技術的な議論は、React NativeのGitHub Issuesで確認可能です: