由于React Native v0.71.0的影响,无法在Android中进行构建

概述

    • React Nativeのv0.71.0-rc0が2022/11/4に公開されたよ

 

    • 上記リリースによって他のバージョンのReact Nativeで開発を行っていた場合に、androidのビルドエラーが発生するようになったよ

 

    • React Native公式で事象と対処方法についてissueを記載してくれているので、この記事では関連知識とissueの解説をしていくよ

公式のissue

假设

React Native 是什么

この記事とか読んでもらうとわかりやすい。
ざっくりいうとReactみたいな書き方でほぼほぼワンソースでandroidもiOSのアプリも作成できるすんばらしいフレームワーク。

Node.js是一个基于Chrome V8引擎的JavaScript运行环境,用于开发服务器端应用程序。而npm则是Node.js的包管理器。

    Node.jsがなんたるかについては、この記事がわかりやすく教えてくれる。(以下抜粋)

使JavaScript能够在终端上运行,而不仅仅是在浏览器中,就像Python或Ruby一样,这是一个用于实现的执行环境。

要开发像React这样的大型应用程序,需要许多不同的软件包,这些软件包彼此之间有着特定的版本依赖关系。Node.js是必不可少的,它解决了软件包的安装和版本管理问题,而npm(Node Package Manager)则负责解决这些问题。

    • つまりこんな感じ

Node.js:JavaScriptの実行環境
npm:開発に必要なパッケージのバージョン管理

Maven中央仓库是什么?

    正確な内容は、このサイトを見てもらえればだが、ざっくりいうとJavaで利用できるOSSが置かれてる場所、そんなイメージで良いかと。

将JAR文件和Javadoc等成果物整理和存放的地方称为Maven仓库。

(中央存储库是) Maven 默认使用的仓库,有许多库被公开。

这个问题 tí)

事件

    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:

应对策略

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からダウンロードできないのかな?とかモヤモヤは残っていますが、とりあえずこんなことが起きたんだなぁというのはなんとなく理解できました。
ざっくり理解なので細かいところ間違っていたら優しく教えてください。。。

bannerAds