React Native Duplicate resources
Asked Answered
O

9

17

After upgrading to React Native 0.57 i am facing an issue when genrating APK in react-native-router-flux.when executing the .\gradlew assembleRelease i get below error :-

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeReleaseResources'.
> [drawable-mdpi-v4/node_modules_reactnativerouterflux_images_back_chevron] 
R:\Workings\lisecapps\androidrepo\test-react- 
native\venutest\android\app\src\main\res\drawable- 
mdpi\node_modules_reactnativerouterflux_images_back_chevron.png      
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_back_chevron] 
R:\Workings\lisecapps\androidrepo\test-react- 
emirnative\venutest\android\app\build\generated\res\react\release\drawable- 
mdpi-v4\node_modules_reactnativerouterflux_images_back_chevron.png: Error: 
Duplicate resources
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_menu_burger] 
R:\Workings\lisecapps\androidrepo\test-react-nat 
ive\venutest\android\app\src\main\res\drawable- 
mdpi\node_modules_reactnativerouterflux_images_menu_burger.png        
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_menu_burger] 
R:\Workings\lisecapps\androidrepo\test-react- 
native\venutest\android\app\build\generated\res\react\release\drawable-mdpi- 
v4\node_modules_reactnativerouterflux_images_menu_burger.png: Error: 
Duplicate resources

I tried the following to resolve but still same error :-

  • Tried to create script as said in the first answer here to avoid duplicate copying of asset images.
  • Deleted the whole app/build folder
Oriente answered 23/9, 2018 at 9:32 Comment(3)
Same issue. How did you get past it?Cubature
Solution: https://mcmap.net/q/103300/-react-native-0-57-1-android-duplicate-resourcesLandwehr
I tried the solution but it did not worked for me as I am using react-native 0.61.1. Please help.Skindive
C
5

You need remove generated resources/drawable and generate again.

rm -rf android/app/src/main/res/drawable-*
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

And compile android again react-native run-android

Carditis answered 2/10, 2018 at 13:47 Comment(2)
Had same error. Tried this one. No luck. Exactly same error as before.Cubature
This one did it for me ... I had previously done react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res to resolve another issue that turned out to be something else. I think that was the cause of the Duplicate Assets error.Scholem
B
5

react.gradle automatically build your javascript and copy any resources imported inside your javascript to the build folder so make sure to NOT call react-native bundle manually and delete any files or folder as src/main/res/drawable-* and src/main/assets/*.bundle and have the following changes into your app/bundle.gradle

project.ext.react = [
  entryFile      : "index.js", // or index.android.js
  bundleInRelease: true,
  bundleInDebug: true
]

apply from: "../../node_modules/react-native/react.gradle"

Note: please notice that some react-native versions have a problem with the local cli.js please make sure to upgrade to a newer version or try adding the following config

 project.ext.react = [
    // ...
    cliPath: "node_modules/react-native/local-cli/cli.js"
 ]
Broida answered 6/1, 2019 at 23:4 Comment(0)
P
2

You can try to clean catch memory and reinstall node modules

watchman watch-del-all
rm -rf node_modules && npm install
rm -fr $TMPDIR/react-*
npm cache clean
npm start -- --reset-cache

It's work for me.

Phytophagous answered 18/12, 2018 at 18:30 Comment(0)
S
1

[0.57] Ugly workaround

If you don't want to rollback the react-native version, you can just rollback the react.gradle to the last working version. That worked for me.

Copy the git code to node_modules/react-native/react.gradle

https://github.com/facebook/react-native/blob/2d9e2f30e17b8e79f2c44ef533ecdd550671304c/react.gradle

If the problem persists, try to remove the if (isAndroidLibrary) on doLast.

Salesmanship answered 2/10, 2018 at 13:41 Comment(0)
F
1

I am using:

"react": "^16.5.2",
"react-native": "0.57.1",

I modified my app's build.gradle like this

ext.react = [
        entryFile: "index.js",
        bundleInRelease       : true,
        resourcesDirRelease   : "src/main/res"
]
apply plugin: 'com.android.application'
import com.android.build.OutputFile

//using custom react gradle here to get around https://mcmap.net/q/103299/-react-native-duplicate-resources
apply from: "../react.gradle"
//apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

and then my custom react.gradle looks like this

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

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

def cliPath = config.cliPath ?: "node_modules/react-native/local-cli/cli.js"
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
def entryFile = config.entryFile ?: "index.android.js"
def bundleCommand = config.bundleCommand ?: "bundle"

// because elvis operator
def elvisFile(thing) {
    return thing ? file(thing) : null;
}

def reactRoot = elvisFile(config.root) ?: file("../../")
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;

void runBefore(String dependentTaskName, Task task) {
    Task dependentTask = tasks.findByPath(dependentTaskName);
    if (dependentTask != null) {
        dependentTask.dependsOn task
    }
}

afterEvaluate {
    def isAndroidLibrary = plugins.hasPlugin("com.android.library")
    // Grab all build types and product flavors
    def buildTypes = android.buildTypes.collect { type -> type.name }
    def productFlavors = android.productFlavors.collect { flavor -> flavor.name }

    // When no product flavors defined, use empty
    if (!productFlavors) productFlavors.add('')

    productFlavors.each { productFlavorName ->
        buildTypes.each { buildTypeName ->
            // Create variant and target names
            def flavorNameCapitalized = "${productFlavorName.capitalize()}"
            def buildNameCapitalized = "${buildTypeName.capitalize()}"
            def targetName = "${flavorNameCapitalized}${buildNameCapitalized}"
            def targetPath = productFlavorName ?
                    "${productFlavorName}/${buildTypeName}" :
                    "${buildTypeName}"

            // React js bundle directories
            def jsBundleDirConfigName = "jsBundleDir${targetName}"
            def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
                    file("$buildDir/intermediates/assets/${targetPath}")

            def resourcesDirConfigName = "resourcesDir${targetName}"
            def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
                    file("$buildDir/intermediates/res/merged/${targetPath}")
            def jsBundleFile = file("$jsBundleDir/$bundleAssetName")

            // Bundle task name for variant
            def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets"

            // Additional node and packager commandline arguments
            def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
            def extraPackagerArgs = config.extraPackagerArgs ?: []

            def currentBundleTask = tasks.create(
                    name: bundleJsAndAssetsTaskName,
                    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.mkdirs()
                    resourcesDir.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);
                }

                if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                    commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
                            "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
                } else {
                    commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
                            "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
                }

                enabled config."bundleIn${targetName}" ||
                        config."bundleIn${buildTypeName.capitalize()}" ?:
                        targetName.toLowerCase().contains("release")

            }

            // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
            currentBundleTask.dependsOn("merge${targetName}Resources")
            currentBundleTask.dependsOn("merge${targetName}Assets")

            runBefore("process${flavorNameCapitalized}Armeabi-v7a${buildNameCapitalized}Resources", currentBundleTask)
            runBefore("process${flavorNameCapitalized}X86${buildNameCapitalized}Resources", currentBundleTask)
            runBefore("processUniversal${targetName}Resources", currentBundleTask)
            runBefore("process${targetName}Resources", currentBundleTask)
            runBefore("dataBindingProcessLayouts${targetName}", currentBundleTask)
        }
    }
}
Forlini answered 3/10, 2018 at 10:54 Comment(3)
What version of React and React Native do you use?Pyromagnetic
"react": "^16.5.2", "react-native": "0.57.1",Forlini
You are a king among men. Thanks!Cronk
M
1

This worked for me:

rm -rf ./android/app/src/main/res/raw

In my project, build failed because there is a duplicated resources in my Android project. This line is necessary to remove duplicated resources.

Mease answered 30/10, 2020 at 12:3 Comment(0)
S
1

It is easy! just delete drawable and raw folder under app/src/main/res

Situs answered 2/12, 2020 at 23:4 Comment(0)
M
1

Try this :

  1. Delete build inside android/app folder
  2. Delete build inside android folder
  3. run rm -rf $HOME/.gradle/caches/
  4. Open build.gradle --> android/app/build.gradle
  5. comment this line

//apply from: "../../node_modules/react-native/react.gradle"

  1. Delete index.android.bundle file from assets folder and re-create using react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

  2. run react-native run-android Or run react-native run-android --variant=release

Mendelevium answered 24/8, 2021 at 20:6 Comment(0)
C
0

There is another way to resolve this issue. For me, just adding below code in my project's android/build.gradle worked:

subprojects {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 27
                buildToolsVersion "27.0.2"
            }
        }
    }
}
Carew answered 3/10, 2018 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.