21
votes

I created an app using react native and I am trying to generate the apk. After doing everthing in the doc of http://facebook.github.io/react-native/docs/signed-apk-android.html#content. An error occured and it says Could not read script react-native\react.gradle' as it does not exist.

Here is the error

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\User\Desktop\Aaa\android\app\build.gradle' line: 68

* What went wrong:
A problem occurred evaluating project ':app'.
> Could not read script 'C



*   // override which node gets called and with what additional arguments
*   nodeExecutableAndArgs: ["node"],
*
*   // supply additional arguments to the packager
*   extraPackagerArgs: []
* ]
*/

apply from: "../../node_modules/react-native/react.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
6
Can you paste out your gradle config at android/app/build.gradle? - max23_
everything @max23_? - orange
Probably from line 60 till line 70? (since it is complaining at line 68) - max23_
posted the error sir - orange

6 Answers

34
votes

Go to the project's root folder and run npm install and it will generate the necessary files, including react.gradle

If you don't have node.js, you can download it from here: https://nodejs.org/en/download/

6
votes

you can do npm install

and and all the problems are over.

0
votes

React.gradle file add this file to react modules and then run your project it will solve your problem. this is official react-native/react.gradle

Let me know if any error occur.


/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import org.apache.tools.ant.taskdefs.condition.Os

def config = project.hasProperty("react") ? project.react : [:];

def detectEntryFile(config) {
    if (System.getenv('ENTRY_FILE')) {
        return System.getenv('ENTRY_FILE')
    } else if (config.entryFile) {
        return config.entryFile
    } else if ((new File("${projectDir}/../../index.android.js")).exists()) {
        return "index.android.js"
    }

    return "index.js";
}

def cliPath = config.cliPath ?: "node_modules/react-native/cli.js"
def composeSourceMapsPath = config.composeSourceMapsPath ?: "node_modules/react-native/scripts/compose-source-maps.js"
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
def entryFile = detectEntryFile(config)
def bundleCommand = config.bundleCommand ?: "bundle"
def reactRoot = file(config.root ?: "../../")
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;
def enableVmCleanup = config.enableVmCleanup == null ? true : config.enableVmCleanup
def hermesCommand = config.hermesCommand ?: "../../node_modules/hermes-engine/%OS-BIN%/hermes"

def reactNativeDevServerPort() {
    def value = project.getProperties().get("reactNativeDevServerPort")
    return value != null ? value : "8081"
}

def reactNativeInspectorProxyPort() {
    def value = project.getProperties().get("reactNativeInspectorProxyPort")
    return value != null ? value : reactNativeDevServerPort()
}

def getHermesOSBin() {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) return "win64-bin";
    if (Os.isFamily(Os.FAMILY_MAC)) return "osx-bin";
    if (Os.isOs(null, "linux", "amd64", null)) return "linux64-bin";
    throw new Exception("OS not recognized. Please set project.ext.react.hermesCommand " +
                        "to the path of a working Hermes compiler.");
}

// Make sure not to inspect the Hermes config unless we need it,
// to avoid breaking any JSC-only setups.
def getHermesCommand = {
    // If the project specifies a Hermes command, don't second guess it.
    if (!hermesCommand.contains("%OS-BIN%")) {
        return hermesCommand
    }

    // Execution on Windows fails with / as separator
    return hermesCommand
            .replaceAll("%OS-BIN%", getHermesOSBin())
            .replace('/' as char, File.separatorChar);
}

// Set enableHermesForVariant to a function to configure per variant,
// or set `enableHermes` to True/False to set all of them
def enableHermesForVariant = config.enableHermesForVariant ?: {
    def variant -> config.enableHermes ?: false
}

android {
    buildTypes.all {
        resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
        resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
    }
}

afterEvaluate {
    def isAndroidLibrary = plugins.hasPlugin("com.android.library")
    def variants = isAndroidLibrary ? android.libraryVariants : android.applicationVariants
    variants.all { def variant ->
        // Create variant and target names
        def targetName = variant.name.capitalize()
        def targetPath = variant.dirName

        // React js bundle directories
        def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}")
        def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")

        def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
        def jsSourceMapsDir = file("$buildDir/generated/sourcemaps/react/${targetPath}")
        def jsIntermediateSourceMapsDir = file("$buildDir/intermediates/sourcemaps/react/${targetPath}")
        def jsPackagerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.packager.map")
        def jsCompilerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.compiler.map")
        def jsOutputSourceMapFile = file("$jsSourceMapsDir/${bundleAssetName}.map")

        // Additional node and packager commandline arguments
        def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
        def extraPackagerArgs = config.extraPackagerArgs ?: []
        def npx = Os.isFamily(Os.FAMILY_WINDOWS) ? "npx.cmd" : "npx"

        def execCommand = []

        if (config.cliPath || config.nodeExecutableAndArgs) {
            if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                execCommand.addAll(["cmd", "/c", *nodeExecutableAndArgs, cliPath])
            } else {
                execCommand.addAll([*nodeExecutableAndArgs, cliPath])
            }
        } else {
            execCommand.addAll([npx, "react-native"])
        }

        def enableHermes = enableHermesForVariant(variant)

        def currentBundleTask = tasks.create(
            name: "bundle${targetName}JsAndAssets",
            type: Exec) {
            group = "react"
            description = "bundle JS and assets for ${targetName}."

            // Create dirs if they are not there (e.g. the "clean" task just ran)
            doFirst {
                jsBundleDir.deleteDir()
                jsBundleDir.mkdirs()
                resourcesDir.deleteDir()
                resourcesDir.mkdirs()
                jsIntermediateSourceMapsDir.deleteDir()
                jsIntermediateSourceMapsDir.mkdirs()
                jsSourceMapsDir.deleteDir()
                jsSourceMapsDir.mkdirs()
            }

            // Set up inputs and outputs so gradle can cache the result
            inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
            outputs.dir(jsBundleDir)
            outputs.dir(resourcesDir)

            // Set up the call to the react-native cli
            workingDir(reactRoot)

            // Set up dev mode
            def devEnabled = !(config."devDisabledIn${targetName}"
                || targetName.toLowerCase().contains("release"))

            def extraArgs = extraPackagerArgs;

            if (bundleConfig) {
                extraArgs = extraArgs.clone()
                extraArgs.add("--config");
                extraArgs.add(bundleConfig);
            }

            commandLine(*execCommand, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
                "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir,
                "--sourcemap-output", enableHermes ? jsPackagerSourceMapFile : jsOutputSourceMapFile, *extraArgs)


            if (enableHermes) {
                doLast {
                    def hermesFlags;
                    def hbcTempFile = file("${jsBundleFile}.hbc")
                    exec {
                        if (targetName.toLowerCase().contains("release")) {
                            // Can't use ?: since that will also substitute valid empty lists
                            hermesFlags = config.hermesFlagsRelease
                            if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"]
                        } else {
                            hermesFlags = config.hermesFlagsDebug
                            if (hermesFlags == null) hermesFlags = []
                        }

                        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                            commandLine("cmd", "/c", getHermesCommand(), "-emit-binary", "-out", hbcTempFile, jsBundleFile, *hermesFlags)
                        } else {
                            commandLine(getHermesCommand(), "-emit-binary", "-out", hbcTempFile, jsBundleFile, *hermesFlags)
                        }
                    }
                    ant.move(
                        file: hbcTempFile,
                        toFile: jsBundleFile
                    );
                    if (hermesFlags.contains("-output-source-map")) {
                        ant.move(
                            // Hermes will generate a source map with this exact name
                            file: "${jsBundleFile}.hbc.map",
                            tofile: jsCompilerSourceMapFile
                        );
                        exec {
                            // TODO: set task dependencies for caching

                            // Set up the call to the compose-source-maps script
                            workingDir(reactRoot)
                            if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                                commandLine("cmd", "/c", *nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, jsCompilerSourceMapFile, "-o", jsOutputSourceMapFile)
                            } else {
                                commandLine(*nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, jsCompilerSourceMapFile, "-o", jsOutputSourceMapFile)
                            }
                        }
                    }
                }
            }

            enabled config."bundleIn${targetName}" != null
                ? config."bundleIn${targetName}"
                : config."bundleIn${variant.buildType.name.capitalize()}" != null
                    ? config."bundleIn${variant.buildType.name.capitalize()}"
                    : targetName.toLowerCase().contains("release")
        }

        // Expose a minimal interface on the application variant and the task itself:
        variant.ext.bundleJsAndAssets = currentBundleTask
        currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
        currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)

        // registerGeneratedResFolders for Android plugin 3.x
        if (variant.respondsTo("registerGeneratedResFolders")) {
            variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
        } else {
            variant.registerResGeneratingTask(currentBundleTask)
        }
        variant.mergeResourcesProvider.get().dependsOn(currentBundleTask)

        // packageApplication for Android plugin 3.x
        def packageTask = variant.hasProperty("packageApplication")
            ? variant.packageApplicationProvider.get()
            : tasks.findByName("package${targetName}")
        if (variant.hasProperty("packageLibrary")) {
            packageTask = variant.packageLibrary
        }

        // pre bundle build task for Android plugin 3.2+
        def buildPreBundleTask = tasks.findByName("build${targetName}PreBundle")

        def resourcesDirConfigValue = config."resourcesDir${targetName}"
        if (resourcesDirConfigValue) {
            def currentCopyResTask = tasks.create(
                name: "copy${targetName}BundledResources",
                type: Copy) {
                group = "react"
                description = "copy bundled resources into custom location for ${targetName}."

                from(resourcesDir)
                into(file(resourcesDirConfigValue))

                dependsOn(currentBundleTask)

                enabled(currentBundleTask.enabled)
            }

            packageTask.dependsOn(currentCopyResTask)
            if (buildPreBundleTask != null) {
                buildPreBundleTask.dependsOn(currentCopyResTask)
            }
        }

        def currentAssetsCopyTask = tasks.create(
            name: "copy${targetName}BundledJs",
            type: Copy) {
            group = "react"
            description = "copy bundled JS into ${targetName}."

            if (config."jsBundleDir${targetName}") {
                from(jsBundleDir)
                into(file(config."jsBundleDir${targetName}"))
            } else {
                into ("$buildDir/intermediates")
                into ("assets/${targetPath}") {
                    from(jsBundleDir)
                }

                // Workaround for Android Gradle Plugin 3.2+ new asset directory
                into ("merged_assets/${variant.name}/merge${targetName}Assets/out") {
                    from(jsBundleDir)
                }

                // Workaround for Android Gradle Plugin 3.4+ new asset directory
                into ("merged_assets/${variant.name}/out") {
                    from(jsBundleDir)
                }
            }

            // mergeAssets must run first, as it clears the intermediates directory
            dependsOn(variant.mergeAssetsProvider.get())

            enabled(currentBundleTask.enabled)
        }

        packageTask.dependsOn(currentAssetsCopyTask)
        if (buildPreBundleTask != null) {
            buildPreBundleTask.dependsOn(currentAssetsCopyTask)
        }

        // Delete the VM related libraries that this build doesn't need.
        // The application can manage this manually by setting 'enableVmCleanup: false'
        //
        // This should really be done by packaging all Hermes releated libs into
        // two separate HermesDebug and HermesRelease AARs, but until then we'll
        // kludge it by deleting the .so files out of the /transforms/ directory.
        def isRelease = targetName.toLowerCase().contains("release")
        def libDir = "$buildDir/intermediates/transforms/"
        def vmSelectionAction = {
            fileTree(libDir).matching {
                if (enableHermes) {
                    // For Hermes, delete all the libjsc* files
                    include "**/libjsc*.so"

                    if (isRelease) {
                        // Reduce size by deleting the debugger/inspector
                        include '**/libhermes-inspector.so'
                        include '**/libhermes-executor-debug.so'
                    } else {
                        // Release libs take precedence and must be removed
                        // to allow debugging
                        include '**/libhermes-executor-release.so'
                    }
                } else {
                    // For JSC, delete all the libhermes* files
                    include "**/libhermes*.so"
                }
            }.visit { details ->
                def targetVariant = ".*/transforms/[^/]*/${targetPath}/.*"
                def path = details.file.getAbsolutePath().replace(File.separatorChar, '/' as char)
                if (path.matches(targetVariant) && details.file.isFile()) {
                    details.file.delete()
                }
            }
        }

        if (enableVmCleanup) {
            def task = tasks.findByName("package${targetName}")
            task.doFirst(vmSelectionAction)
        }
    }
}
0
votes

Which means there is no node-modules in your project directory. please do yarn install or npm install to create node-modules then run the application in android studio.

0
votes

I realize that this is an old question, but I ran into this issue today and I hope this helps keep someone else from pulling their hair out.

I'm using yarn workspaces which causes node_modules to be installed at the workspace root (one level above where they would normally be.) This isn't a problem for the node/typescript part of the project. However, since gradle also references files inside of node modules, it gets confused and gives up.

So far, I've only run into this on Windows.

0
votes

npm install alone will not do the trick.

You should run for android:

npm i @react-native-community/cli-platform-android

And then:

npm install 

I ran this as admin and problem solved for me.