Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Setting --sourcemap-output in extraPackagerArgs in project.ext.react breaks bundling #32239

Closed
taltrui opened this issue Sep 21, 2021 · 9 comments
Labels
Resolution: PR Submitted A pull request with a fix has been provided. Tech: Hermes Hermes Engine: https://hermesengine.dev/

Comments

@taltrui
Copy link

taltrui commented Sep 21, 2021

Please provide all the information requested. Issues that do not follow this format are likely to stall.

Description

Adding --sourcemap-output flag to project.ext.react config in android/app/build.gradle breaks bundling (with bundleRelease for example) when Hermes is enabled.

This doesn't happen when Hermes is disabled.

Tested on Windows 10 and macOS Big Sur.

React Native version:

Device info

System:
OS: Windows 10 10.0.19043
CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
Memory: 5.41 GB / 15.95 GB
Binaries:
Node: 14.17.3 - ~\AppData\Local\Temp\yarn--1632189645387-0.8024281640590405\node.CMD
Yarn: 1.22.4 - ~\AppData\Local\Temp\yarn--1632189645387-0.8024281640590405\yarn.CMD
npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD
Watchman: 20200816.222424.0 - C:\Users\tomas\AppData\Local\watchman\bin\watchman.EXE
SDKs:
Android SDK:
API Levels: 23, 25, 28, 29, 30
Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2
System Images: android-19 | Google APIs Intel x86 Atom, android-23 | Google APIs ARM EABI v7a, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-25 | Google APIs Intel x86 Atom_64, android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom
Android NDK: Not Found
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
AllowAllTrustedApps: Enabled
Versions: 10.0.17763.0
IDEs:
Android Studio: Version 4.1.0.0 AI-201.8743.12.41.7042882
Visual Studio: 15.9.28307.1274 (Visual Studio Community 2017)
Languages:
Java: 15.0.2 - C:\Program Files\AdoptOpenJDK\jdk-15.0.2.7-hotspot\bin\javac.EXE
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.65.1 => 0.65.1
react-native-windows: Not Found
npmGlobalPackages:
react-native: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Create a new project with npx react-native init
  2. Enable Hermes in app/build.gradle
  3. Add extraPackagerArgs: ["--sourcemap-output", "$rootDir/sourcemap.android.js"] to project.ext.react
  4. run cd android && ./gradlew bundleRelease

Expected Results

AAB is created successfully and sourcemap is created in android/sourcemap.android.js

Snack, code example, screenshot, or link to a repository:

I think it doesn't make much sense to create a repo since you can reproduce this with the minimum project created by react-native cli.

Just in case, sourcemap is created successfully in the desired path, but react-native seems to have hardcoded the path:

info start relativating source map
info finished relativating
info Writing bundle output to:, C:\Users\tomas\Workspace\SourcemapBugRepro\android\app\build\generated\assets\react\release\index.android.bundle
info Writing sourcemap output to:, C:\Users\tomas\Workspace\SourcemapBugRepro\android/sourcemap.android.js
info Done writing bundle output
info Done writing sourcemap output
info Copying 1 asset files
info Done copying assets

...

Error: ENOENT: no such file or directory, open 'C:\Users\tomas\Workspace\SourcemapBugRepro\android\app\build\intermediates\sourcemaps\react\release\index.android.bundle.packager.map'
    at Object.openSync (fs.js:498:3)
    at Object.readFileSync (fs.js:394:35)
    at Object.<anonymous> (C:\Users\tomas\Workspace\SourcemapBugRepro\node_modules\react-native\scripts\compose-source-maps.js:33:43)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47 {
  errno: -4058,
  syscall: 'open',
  code: 'ENOENT',
  path: 'C:\\Users\\tomas\\Workspace\\SourcemapBugRepro\\android\\app\\build\\intermediates\\sourcemaps\\react\\release\\index.android.bundle.packager.map'

It seems the culprit of this is react.gradle Hermes bundling:

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

As you can see here --sourcemap-output", enableHermes ? jsPackagerSourceMapFile : jsOutputSourceMapFile, jsPackagerSourcemapFile is used as default, but can be overridden by *extraArgs.

This isn't a problem per se, but later we see:

if (enableHermes) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    commandLine("cmd", "/c", *nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, 
    jsCompilerSourceMapFile, "-o", jsOutputSourceMapFile)
} else {
   commandLine(*nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, jsCompilerSourceMapFile, "-o", 
   jsOutputSourceMapFile)
  }
} 

Here jsPackagerSourceMapFile is used as the only option which is "hardcoded" as: def jsPackagerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.packager.map").

With this:

// app/build.gradle

project.ext.react = [
    enableHermes: true,  // clean and rebuild if changing,
    sourcemapOutput: "$rootDir/sourcemap.android.js"
]
// react.gradle

def jsPackagerSourceMapFile = config.sourcemapOutput ?: file("$jsIntermediateSourceMapsDir/${bundleAssetName}.packager.map")

Bundling works just fine but since I'm not an expert in Gradle and bundling and such things I can't really tell if this is a good solution or just a patch.

@taltrui taltrui changed the title [Android] Setting --sourcemap-output flag in project.ext.react breaks bundling [Android] Setting --sourcemap-output in extraPackagerArgs in project.ext.react breaks bundling Sep 21, 2021
@taltrui
Copy link
Author

taltrui commented Sep 21, 2021

In case anyone needs this, until this get fixed (or not), I've made a patch so it can be used with patch-package. Just remember to change .txt to .patch (Github doesn't allow .patch files 🤷 )

react-native+0.65.1.txt

diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle
index 84b1f60..41c764c 100644
--- a/node_modules/react-native/react.gradle
+++ b/node_modules/react-native/react.gradle
@@ -105,7 +105,7 @@ afterEvaluate {
         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 jsPackagerSourceMapFile = config.sourcemapOutput ?: file("$jsIntermediateSourceMapsDir/${bundleAssetName}.packager.map")
         def jsCompilerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.compiler.map")
         def jsOutputSourceMapFile = file("$jsSourceMapsDir/${bundleAssetName}.map")
 

Then you can use sourcemapOutput in app/build.grade:

// app/build.gradle

project.ext.react = [
    enableHermes: true,  // clean and rebuild if changing,
    sourcemapOutput: "$rootDir/sourcemap.android.js"
]

Of course this patch is for 0.65.1 since it's the version I'm using, but since changing sourcemap output path should be broken in older versions as well, this should work as well.

@stale
Copy link

stale bot commented Jan 9, 2022

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jan 9, 2022
@github-actions
Copy link

This issue was closed because it has been stalled for 7 days with no activity.

@cortinico
Copy link
Contributor

Reopening as there is a pending PR #33703

@cortinico cortinico added Resolution: PR Submitted A pull request with a fix has been provided. Tech: Hermes Hermes Engine: https://hermesengine.dev/ and removed Stale There has been a lack of activity on this issue and it may be closed soon. Needs: Triage 🔍 labels May 4, 2022
@cortinico
Copy link
Contributor

sourcemap is created in android/sourcemap.android.js

Asking here as it's relevant also for the linked PR: why do you need to change the sourcemap location @taltrui ?

@facebook facebook unlocked this conversation May 13, 2022
@taltrui
Copy link
Author

taltrui commented May 13, 2022

Hi!,

Since our app has a multi-tenant architecture, multiple kind-of-different apps are built from the same code. When we deploy an app, it's sourcemap is uploaded to Rollbar.

In Hermes the sourcemap output path is: android/app/build/generated/sourcemaps/react/appName/release. The thing is appName could be dev/stage/prod-ClientName so for every client we have 3 "appName", with a few clients this goes up.

So to simplify our deploy flow (we use Fastlane to handle this), specifically the custom-made action to upload the sourcemap to Rollbar, having the sourcemap output to be always the same is really helpfull.

Without Hermes setting --sourcemap-output to extraPackagerArgs does work, so when we updated to Hermes it basically broke our soucemap upload action and then I came up with that "patch" to make it work like it did.

I don't know if there is a better way (or a way at all) to do what I say, but basically that is our use case.

@cortinico
Copy link
Contributor

the custom-made action to upload the sourcemap to Rollbar

Could you link to where this custom made action lives? Ideally the action should be updated to handle multiple source maps and we should not bake this configuration inside RN.

@taltrui
Copy link
Author

taltrui commented Jun 2, 2022

The custom action lives in our repo. It's a really simple ruby fastlane action class that takes a file in a path and uploads it to rollbar with a post request.

The action could handle multiple sourcemaps locations, but it is kind of inconvenient. If you really think changing the sourcemap final location by configuration is something that should be out of the responsibility of RN it's OK and we will adapt to it.

Since without Hermes it was supported (or at least worked with no problems). seemed logical to me it should or atleast could work with Hermes too.

@cortinico
Copy link
Contributor

Since without Hermes it was supported (or at least worked with no problems). seemed logical to me it should or atleast could work with Hermes too.

In theory, yes. Practically speaking, we're trying to limit the amount of configurable parts to expose only what is really necessary (or what is needed by a significant amount of users).

As this can be solved on your action's end, feels like the preferred approach at this stage.
Should we receive more use cases of users needing to do this, we're happy to re-evalute

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: PR Submitted A pull request with a fix has been provided. Tech: Hermes Hermes Engine: https://hermesengine.dev/
Projects
None yet
Development

No branches or pull requests

2 participants