あらまし
- React Nativeのv0.71.0-rc0が2022/11/4に公開されたよ
- 上記リリースによって他のバージョンのReact Nativeで開発を行っていた場合に、androidのビルドエラーが発生するようになったよ
- React Native公式で事象と対処方法についてissueを記載してくれているので、この記事では関連知識とissueの解説をしていくよ
前提
React Nativeとは
- この記事とか読んでもらうとわかりやすい。
- ざっくりいうとReactみたいな書き方でほぼほぼワンソースでandroidもiOSのアプリも作成できるすんばらしいフレームワーク。
Node.js, npmとは
- Node.jsがなんたるかについては、この記事がわかりやすく教えてくれる。(以下抜粋)
JavaScriptをブラウザではなくPythonやRubyなどと同じようにターミナル上で動かすことができるようにするための実行環境のこと
Reactのような大規模なアプリケーションを開発するとなると、様々なパッケージが必要になり、そのパッケージたちが特定のバージョンで依存しあっています。Node.jsはそのパッケージのインストールと整合性の管理を解決するために必要であり、npm(Node Package Manager)がその解決を担っています。
- つまりこんな感じ
- Node.js:JavaScriptの実行環境
- npm:開発に必要なパッケージのバージョン管理
Mavenセントラルレポジトリとは
- 正確な内容は、このサイトを見てもらえればだが、ざっくりいうとJavaで利用できるOSSが置かれてる場所、そんなイメージで良いかと。
JARなどの成果物やJavadocをライブラリを整理してまとめておく場所のことを、Mavenリポジトリと呼びます。
(セントラルリポジトリとは)Mavenがデフォルトで利用するリポジトリです。たくさんのライブラリが公開されています。
本題
事象
- v0.70以下のすべてのバージョンのReact Nativeを使用しているアプリでandroid用アプリのビルドを行う際に以下のようなメッセージが表示されるようになった。
Error: Command failed: gradlew.bat app:installDebug -PreactNativeDevServerPort=8081
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'My Project'.
Could not determine the dependencies of null.
Could not resolve all task dependencies for configuration ':classpath'.
> Could not resolve com.facebook.react:react-native:+.
Required by:
project :
> No matching variant of com.facebook.react:react-native:0.71.0-rc.0 was found.
The consumer was configured to find a runtime of a library compatible with Java 11,
packaged as a jar, and its dependencies declared externally, as well
as attribute 'org.gradle.plugin.api-version' with value '7.3.3' but:
対応方針
v0.63以上
- 各バージョンに応じたhotfixがリリースされているので、react-nativeのバージョンをアップデート
v0.63未満
-
android/buld.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 {
// Remove this override in 0.65+, as a proper fix is included in react-native itself.
force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
}
}
原因
- 従来のReact Nativeテンプレートに含まれている
build.gradle
では、Androidアプリに関するライブラリに対する依存性として以下のような記載がある。(参考:v0.70.5)
implementation "com.facebook.react:react-native:+" // From node_modules
-
この
+
を使った記法はGradle Dynamic versions
と呼ばれており、すべてのレポジトリの中から最新バージョンを取得するような動きとなる。 -
v71.0がリリースされるまでは以下のような流れで正しいバージョンのReact Nativeが参照されていた。
-
npm install
の際に、package.json
に記載されたバージョンのreact-nativeがダウンロードされ、node_modules/react-native/android
に格納される - androidアプリビルド時に上記の
node_modules/react-native/android
配下のReact Nativeを参照
-
-
一方で、v0.71からはリリース戦略が変更され、NPMパッケージではなく、Mavenセントラルにリリースされるようになった。
-
上記の2の段階で、
node_modules/react-native/android
には正しいバージョンのreact-nativeが格納されているにもかかわらず、より新しいバージョンのreact-nativeがMavenセントラルに存在するようになってしまったため、そちらが参照されてしまいビルドエラーになってしまった。
所感
-
Gradle Dynamic versions
でNPMの最新版のreact-nativeがダウンロードされなかったのはなぜだろう?npm install
を使わないとNPMからダウンロードできないのかな?とかモヤモヤは残っていますが、とりあえずこんなことが起きたんだなぁというのはなんとなく理解できました。 - ざっくり理解なので細かいところ間違っていたら優しく教えてください。。。