本文介绍了React Native构建错误:文本不能为null或为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Jenkins版本给了我以下错误:

My Jenkins build has given me the following error:

13:18:22 FAILURE: Build failed with an exception.
13:18:22
13:18:22 * Where:
13:18:22 Script '/Users/abcd/Jenkins/Jenkins-Workspaces/ABCD/ABCDL/node_modules/@react-native-community/cli-platform-android/native_modules.gradle' line: 190
13:18:22
13:18:22 * What went wrong:
13:18:22 A problem occurred evaluating settings 'AppName'.
13:18:22 > Text must not be null or empty
13:18:22

似乎问题出在@react-native-community/cli-platform节点模块,但请阅读以下已关闭的问题: https://github.com/facebook/react-native/issues/25479

It seems the problem is with the @react-native-community/cli-platform node module, but reading over this closed issue:https://github.com/facebook/react-native/issues/25479

我不清楚这个提议和最终的解决方案到底是什么.

its unclear to me what exactly is the proposed and final solution to this.

有一个关于此本地问题的更简单修补程序的建议: https://github.com/facebook/react-native/issues/25822

There is a recommendation on a fix that is more straightforward in this react-native issue:https://github.com/facebook/react-native/issues/25822

但是我的错误不是抱怨那条线.

but my error is not complaining about that line.

就安装@react-native-community/cli而言,我相信我已经将其保存在package-lock.json文件中:

As far as installing @react-native-community/cli I believe I already have it inside my package-lock.json file:

"react-native": {
      "version": "0.60.4",
      "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.60.4.tgz",
      "integrity": "sha512-WE41lbGQjnzM9srIFtMDtMJkQAvk95iZwuFvAxl68s80bkYa7Ou9sGFHpeYIV6cY8yHtheCSo5q6YMxhdfkdOw==",
      "requires": {
        "@babel/runtime": "^7.0.0",
        "@react-native-community/cli": "^2.0.1",
        "@react-native-community/cli-platform-android": "^2.0.1",
        "@react-native-community/cli-platform-ios": "^2.0.1",

其他人提到了有关app/build.gradle的内容,这是我的相关部分:

Others mentioned something about app/build.gradle, here is the relevant part of mine:

// 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)

提及也是由android/settings.gradle组成的,这是我的:

Mention was also made of android/settings.gradle, this one is mine:

rootProject.name = 'NFIBEngage'
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':appcenter-crashes'
project(':appcenter-crashes').projectDir = new File(rootProject.projectDir, '../node_modules/appcenter-crashes/android')
include ':appcenter-analytics'
project(':appcenter-analytics').projectDir = new File(rootProject.projectDir, '../node_modules/appcenter-analytics/android')
include ':appcenter'
project(':appcenter').projectDir = new File(rootProject.projectDir, '../node_modules/appcenter/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'

根据我在这里收集的信息:

From what I have gathered here:

https://react -native-community.github.io/upgrade-helper/?from=0.53.3&to=0.60.4

以上文件正确.

那么这里到底有什么问题,我该如何解决?

So what exactly is wrong here and how do I fix it?

node_modules/@react-native-community/cli-platform-android/native_modules.gradle line 190而言,这是

def json = new JsonSlurper().parseText(reactNativeConfigOutput)

问题可能出在我如何编写index.js文件上:

Could the problem be with how I wrote index.js file:

/**
 * @format
 */

import { AppRegistry } from "react-native";
// old config code
import KeyboardManager from "react-native-keyboard-manager";
// old config code ^^^
import NFIBEngage from "./App";
import { name as appName } from "./app.json";

// old config code
import { Sentry } from "react-native-sentry";

Sentry.config(
  "https://[email protected]/123456677"
).install();

KeyboardManager.setToolbarPreviousNextButtonEnable(true);
// old config code ^^^

AppRegistry.registerComponent("NFIBEngage", () => NFIBEngage);

AppRegistry.registerComponent()书写正确吗?

我在本地运行Jenkins脚本,我相信这里就是这个脚本:

I ran the Jenkins script locally, which I believe is this script right here:

import fs from "fs-extra";
import eachSeries from "async/eachSeries";
import { exec } from "child_process";
import { androidDirectory } from "../../app.json";
import { resolveFromRoot, distDir, createLogger } from "../build";

const logger = createLogger("android");

const APK_PATTERN = /release\.apk$/i;

function copyArtifactsToDist() {
  logger.logHeader("Copying APK to Dist", { repeatChar: "=" });
  const baseDir = `${androidDirectory}/app/build/outputs/apk`;

  const allFlavs = ["dev", "qa", "ua", "prod"];
  const branchName = process.env.GitVersion_BranchName || "";
  const buildFlavour = branchName.startsWith("release/") ? allFlavs : ["dev"];
  const envs = {
    dev: "INT",
    qa: "QA",
    ua: "UA",
    prod: ""
  };

  buildFlavour
    .map(env => {
      const apkOutputDir = resolveFromRoot(`${baseDir}/${env}/release`);
      return {
        apkOutputDir,
        env
      };
    })
    .forEach(({ apkOutputDir, env }) => {
      const src = `${apkOutputDir}/app-${env}-release.apk`;
      //prettier-ignore
      const binaryName = env === 'prod' ? 'ENGAL.apk' : `ENGAL-${envs[env]}.apk`;
      const dest = `${distDir}/${binaryName}`;
      fs.copy(src, dest, (err: Error) => {
        if (err) {
          logger.error(err);
        }
      });
    });
}

function run() {
  logger.logHeader("Starting Android Builds", { repeatChar: "#" });
  const flavours = [
    {
      endpoint: "dv",
      flavour: "Dev",
      appcenterKey: "<hashKeys>"
    },
    {
      endpoint: "qa",
      flavour: "Qa",
      appcenterKey: "<hashKeys>"
    },
    {
      endpoint: "ua",
      flavour: "Ua",
      appcenterKey: "<hashKeys>"
    },
    {
      endpoint: "prod",
      flavour: "Prod",
      appcenterKey: "<hashKeys>"
    }
  ];

  const versionCode = process.env.Build || 1;
  const release = process.env.GitVersion_MajorMinorPatch || "1.0.0";
  const fullAppVersion = `${release}-${versionCode}`;

  const devFlav = flavours.find(f => f.flavour.toLocaleLowerCase() === "dev");

  const branchName = process.env.GitVersion_BranchName || "";
  const buildFlavour = branchName.startsWith("release/") ? flavours : [devFlav];

  eachSeries(
    buildFlavour,
    (f, callback) => {
      //prettier-ignore
      logger.logHeader(
        `starting gradle assemble${f.flavour}Release with flag - versionName=${fullAppVersion} -PversionCode=${versionCode}`,
        {repeatChar: '-'}
      );

      const engaInfo = `ENGAGE_VERSION=${fullAppVersion}`;
      const engaEndpoint = `ENGAGE_ENDPOINT=${f.endpoint}`;
      const engaCenter = `APPCENTER_KEY=${f.appcenterKey}`;
      const engaPlatform = "APPCENTER_PLATFORM=android";
      //prettier-ignore
      const prepare = `${engaEndpoint} ${engaCenter} ${engaInfo} ${engaPlatform} npm run setup`;
      const cd = `cd ${androidDirectory}`;
      //prettier-ignore
      const releaseCmd = `./gradlew assemble${f.flavour}Release -PversionName=${fullAppVersion} -PversionCode=${versionCode} && cd ..`;

      exec(`${prepare} && ${cd} && ${releaseCmd}`, err => {
        if (err) {
          return callback(err);
        }

        logger.logHeader(`${f.flavour} Android Build Successful!`, {
          repeatChar: "#"
        });
        logger.close();
        callback(null);
      });
    },
    error => {
      if (error) {
        logger.logHeader("Android Builds Failed!", {
          repeatChar: "#"
        });
        logger.error(error);
        logger.close();
      }
      copyArtifactsToDist();
    }
  );
}

run();

通过npm run build在本地出现此错误:

via npm run build and locally I got this error:

FAILURE: Build failed with an exception.

* What went wrong:
Task 'assembleDevRelease' not found in root project 'AppName'. Some candidates are: 'assembleRelease'.

这些相关的错误吗?任何有过React Native构建经验的人吗?

Are these related errors? Anyone experienced with React Native builds?

按照建议,我在android/app/build.gradle文件中查找了productFlavors,并发现它们之间确实不存在:

As suggested, I looked into my android/app/build.gradle file for productFlavors and noticed that indeed they were missing between here:

buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

    // 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) * 123456 + defaultConfig.versionCode
            }

        }
    }

所以我这样添加了它:

buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

    productFlavors {
      dev {
        resValue "string", "app_name", getAppName("INT")
        resValue "string", "link_launcher", getLauncher("dv")
        applicationIdSuffix ".dv"
        manifestPlaceholders = [onesignal_app_id: "<hash_id>",
                                onesignal_google_project_number: "123456789"]
      }
      qa {
        resValue "string", "app_name", getAppName("QA")
        resValue "string", "link_launcher", getLauncher("qa")
        applicationIdSuffix ".qa"
        manifestPlaceholders = [onesignal_app_id: "<hash_id>",
                                onesignal_google_project_number: "123456789"]
      }
      ua {
        resValue "string", "app_name", getAppName("UA")
        resValue "string", "link_launcher", getLauncher("ua")
        applicationIdSuffix ".ua"
        manifestPlaceholders = [onesignal_app_id: "<hash_id>",
                                onesignal_google_project_number: "123456789"]
      }
      prod {
        resValue "string", "app_name", getAppName()
        resValue "string", "link_launcher", getLauncher()
        manifestPlaceholders = [onesignal_app_id: "<hash_id>",
                                onesignal_google_project_number: "601125149914"]
      }
    }

    // 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
            }

        }
    }

buildTypes看起来与原始旧版buildTypes有所不同,所以我不确定是否可以,但是无论如何我还是再次在本地运行了npm run build并收到了此错误:

The buildTypes is looking a bit different than the original legacy buildTypes so I am not sure if thats okay, but at any rate I then ran npm run build again locally and got this error:

* Where:
Build file '/Users/danale/Projects/NFIBEngage/android/app/build.gradle' line: 168

* What went wrong:
A problem occurred evaluating project ':app'.
> Could not find method getAppName() for arguments [INT] on ProductFlavor_Decorated{name=dev, dimension=null, minSdkVersion=null, targetSdkVersion=null, renderscriptTargetApi=null, renderscriptSupportModeEnabled=null, renderscriptSupportModeBlasEnabled=null, renderscriptNdkModeEnabled=null, versionCode=null, versionName=null, applicationId=null, testApplicationId=null, testInstrumentationRunner=null, testInstrumentationRunnerArguments={}, testHandleProfiling=null, testFunctionalTest=null, signingConfig=null, resConfig=null, mBuildConfigFields={}, mResValues={}, mProguardFiles=[], mConsumerProguardFiles=[], mManifestPlaceholders={}, mWearAppUnbundled=null} of type com.android.build.gradle.internal.dsl.ProductFlavor.

我能够通过添加缺少的方法来解决本地错误,如下所示:

I was able to resolve the local error by adding the missing methods like so:

def appName = "Engage";

/**
 * Get the version name from command line param
 *
 * @return int If the param -PversionName is present then return int value or -1
 */
def getAppName = { env ->
  return (env ? appName + " ("+ env + ")" : appName);
}

/**
 * Get the version name from command line param
 *
 * @return int If the param -PversionName is present then return int value or -1
 */
def getLauncher = { env ->
    return (env ? "engage-" + env + ".nfib.org" : "engage.nfib.org");
}

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    flavorDimensions "default"

    defaultConfig {
        applicationId "com.nfib.engage"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
    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'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

    productFlavors {
      dev {
        dimension 'default'
        resValue "string", "app_name", getAppName("INT")
        resValue "string", "link_launcher", getLauncher("dv")
        applicationIdSuffix ".dv"
        manifestPlaceholders = [onesignal_app_id: "b78285eb-f1ec-46f3-9ad0-c7efe691a401",
                                onesignal_google_project_number: "584236827312"]
      }
      qa {
        dimension 'default'
        resValue "string", "app_name", getAppName("QA")
        resValue "string", "link_launcher", getLauncher("qa")
        applicationIdSuffix ".qa"
        manifestPlaceholders = [onesignal_app_id: "e4280f5e-62ec-41a4-bd86-f5b94e471a36",
                                onesignal_google_project_number: "162802054510"]
      }
      ua {
        dimension 'default'
        resValue "string", "app_name", getAppName("UA")
        resValue "string", "link_launcher", getLauncher("ua")
        applicationIdSuffix ".ua"
        manifestPlaceholders = [onesignal_app_id: "2ffd8dc0-9c6b-4035-999d-fc694194725a",
                                onesignal_google_project_number: "594905904045"]
      }
      prod {
        dimension 'default'
        resValue "string", "app_name", getAppName()
        resValue "string", "link_launcher", getLauncher()
        manifestPlaceholders = [onesignal_app_id: "82dcb42f-1d35-4b79-bc28-2d1d02dbda36",
                                onesignal_google_project_number: "601125149914"]
      }
    }

不幸的是,我在詹金斯(Jenkins)中仍然遇到相同的错误.

Unfortunately, I continue to get the same error in Jenkins.

推荐答案

要使构建正常运行,需要进行一些更改,内容来自注释:

Some of the changes to get the build working, from comments:

在package.json中,您的cli版本位于^2.0.1,而2.0.1确实是您从github.com/facebook/react-native/issues/25479链接到的问题的cli版本您验证了node_modules/@react-native-community/cli-platform-android/native_modules.gradle中类似于def command = "../node_modules/.bin/react-native config"的行(来自github.com/facebook/react-native/issues/…)是正确的吗?您还应该确保cli的安装版本为> = 2.0.2.

From your package.json, your cli version is at ^2.0.1 and 2.0.1 is indeed the version of the cli that had the issue you linked to from github.com/facebook/react-native/issues/25479 Have you verified that the line similar to def command = "../node_modules/.bin/react-native config" (from github.com/facebook/react-native/issues/…) in your node_modules/@react-native-community/cli-platform-android/native_modules.gradle is correct? You should also ensure your installed version of the cli is >= 2.0.2.

确保将android/app/build.gradle中的buildTypesproductFlavors定义设置为包括要在jenkins工作中尝试构建的所有不同变体.看起来您具有devqauaprod的风味.请查看gradle文档developer.android.com/studio/build/build-variants#build-types了解更多信息.

Make sure your buildTypes and productFlavors definitions in android/app/build.gradle are set up to include all the different variants you are trying to build in your jenkins job. Looks like you have flavors for dev, qa, ua and prod. Check out the gradle docs developer.android.com/studio/build/build-variants#build-types for more info.

好像您在build.gradle中缺少getAppName函数. ext.getAppName = {suffix = '' -> 'MyAppName' + suffix}之类的东西.快速浏览build.gradle似乎需要另一个名为getLauncher的文件,该文件将为使用link_launcher的内容返回适当的字符串.

Looks like you're missing a getAppName function in your build.gradle. Something like ext.getAppName = {suffix = '' -> 'MyAppName' + suffix}. A quick scan of your build.gradle looks like you need another called getLauncher which returns an appropriate string for whatever you use link_launcher for.

这篇关于React Native构建错误:文本不能为null或为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 04:31