React Native 0.63.5升级后hermes-engine依赖缺失求助
React Native 0.63.5升级后Hermes依赖找不到的构建错误
问题背景
原本使用RN 0.63.4,因版本不匹配问题参考官方指引升级到0.63.5,同时将android/app/build.gradle中的com.facebook.react:react-native:+改为com.facebook.react:react-native:0.63.+,现在出现构建失败。
错误详情
- 执行命令
./gradlew clean build --refresh-dependencies --no-build-cache时,报错无法确定:app:lintVitalReleaseStaging任务的依赖,原因是找不到com.facebook.react:hermes-engine:0.63.+的匹配版本 - Android Studio中显示搜索本地及远程仓库均未找到对应版本,仅能找到不匹配的0.71.0-rc.0
相关配置代码
android/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext { buildToolsVersion = "29.0.2" minSdkVersion = 21 compileSdkVersion = 31 targetSdkVersion = 30 kotlinVersion = '1.5.31' } repositories { google() jcenter() } dependencies { classpath('com.android.tools.build:gradle:4.2.1') classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { mavenLocal() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url("$rootDir/../node_modules/react-native/android") } maven { url "$rootDir/../node_modules/expo-camera/android/maven" } maven { // Android JSC is installed from npm url("$rootDir/../node_modules/jsc-android/dist") } maven { // Android JSC is installed from npm url "$rootDir/../node_modules/jsc-android/dist" } maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' } maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' } google() jcenter() maven { url 'https://www.jitpack.io' } } }
android/app/build.gradle
apply plugin: "com.android.application" apply from: '../../node_modules/react-native-unimodules/gradle.groovy' import com.android.build.OutputFile project.ext.react = [ enableHermes: true, deleteDebugFilesForVariant: { true } ] def useIntlJsc = false apply from: "../../node_modules/react-native/react.gradle" apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" /** * Set this to true to create two separate APKs instead of one: * - An APK that only works on ARM devices * - An APK that only works on x86 devices * The advantage is the size of the APK is reduced by about 4MB. * Upload all the APKs to the Play Store and people will download * the correct one based on the CPU architecture of their device. */ def enableSeparateBuildPerCPUArchitecture = false /** * Run Proguard to shrink the Java bytecode in release builds. */ def enableProguardInReleaseBuilds = false /** * The preferred build flavor of JavaScriptCore. * * For example, to use the international variant, you can use: * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` * * The international variant includes ICU i18n library and necessary data * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that * give correct results when using with locales other than en-US. Note that * this variant is about 6MiB larger per architecture than default. */ def jscFlavor = 'org.webkit:android-jsc:+' /** * Whether to enable the Hermes VM. * * This should be set on project.ext.react and mirrored here. If it is not set * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode * and the benefits of using Hermes will therefore be sharply reduced. */ def enableHermes = project.ext.react.get("enableHermes", true); android { packagingOptions { pickFirst '**/libc++_shared.so' pickFirst '**/libfbjni.so' pickFirst '**/libjsc.so' pickFirst '**/libgnustl_shared.so' //pickFirst 'lib/armeabi-v7a/libreanimated.so' } compileSdkVersion rootProject.ext.compileSdkVersion ndkVersion '23.1.7779620' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { applicationId "...." minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 11 versionName "2.3" // missingDimensionStrategy 'react-native-camera', 'general' } splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } } signingConfigs { debug { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' } release { storeFile file(MYAPP_UPLOAD_STORE_FILE) storePassword MYAPP_UPLOAD_STORE_PASSWORD keyAlias MYAPP_UPLOAD_KEY_ALIAS keyPassword MYAPP_UPLOAD_KEY_PASSWORD } } buildTypes { debug { signingConfig signingConfigs.debug resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_DEBUG } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_PRODUCTION } releaseStaging { initWith release resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_STAGING matchingFallbacks = ['release'] } } // applicationVariants are e.g. debug, release applicationVariants.all { variant -> variant.outputs.each { output -> // For each separate APK per architecture, set a unique version code as described here: // https://developer.android.com/studio/build/configure-apk-splits.html def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = versionCodes.get(abi) * 1048576 + defaultConfig.versionCode } } } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:0.63.+" // From node_modules if (useIntlJsc) { implementation 'org.webkit:android-jsc-intl:+' } else { implementation 'org.webkit:android-jsc:+' } implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' } debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' exclude group:'com.squareup.okhttp3', module:'okhttp' } debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' } if (enableHermes) { implementation("com.facebook.react:hermes-engine:+") { exclude group:'com.facebook.fbjni' } //def hermesPath = "../../node_modules/hermes-engine/android/"; //debugImplementation files(hermesPath + "hermes-debug.aar") //releaseImplementation files(hermesPath + "hermes-release.aar") //releaseStagingImplementation files(hermesPath + "hermes-release.aar") } else { implementation jscFlavor } implementation project(':@react-native-voice_voice') addUnimodulesDependencies() } // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { from configurations.compile into 'libs' } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
解决方案
1. 锁定Hermes引擎版本到与RN匹配的0.63.5
在android/app/build.gradle的Hermes依赖块中,把+改成固定版本0.63.5:
if (enableHermes) { implementation("com.facebook.react:hermes-engine:0.63.5") { exclude group:'com.facebook.fbjni' } }
2. 优先使用本地npm安装的Hermes包
如果远程仓库找不到对应版本,直接使用本地node_modules中的Hermes文件,取消注释相关代码:
if (enableHermes) { // implementation("com.facebook.react:hermes-engine:+") { // exclude group:'com.facebook.fbjni' // } def hermesPath = "../../node_modules/hermes-engine/android/"; debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") releaseStagingImplementation files(hermesPath + "hermes-release.aar") }
3. 调整maven仓库顺序
在android/build.gradle的allprojects.repositories中,把本地node_modules的RN仓库放在最前面,避免优先从远程仓库拉取错误版本:
allprojects { repositories { mavenLocal() maven { url("$rootDir/../node_modules/react-native/android") } // 其他仓库依次放在后面 maven { url "$rootDir/../node_modules/expo-camera/android/maven" } maven { url "$rootDir/../node_modules/jsc-android/dist" } maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' } maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' } google() jcenter() maven { url 'https://www.jitpack.io' } } }
4. 清理缓存后重新构建
执行以下命令彻底清理缓存,再重新构建:
./gradlew clean rm -rf ~/.gradle/caches ./gradlew build --refresh-dependencies
内容的提问来源于stack exchange,提问作者SuJi Gyeon
相关产品推荐
相关产品推荐

