From d572c0ac44499673fc6839591341fabf311468a2 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Tue, 21 Jan 2025 14:26:55 +0100 Subject: [PATCH 1/9] react-native: Simplify react-native source map injection flow --- .../sdk/reactNative/android/app/build.gradle | 10 ++- examples/sdk/reactNative/ios-hermesc.sh | 28 --------- .../sdk/reactNative/ios-sourcemap-upload.sh | 60 ++++++++++++++++++ examples/sdk/reactNative/ios-sourcemaps.sh | 32 ---------- .../ios/reactNative.xcodeproj/project.pbxproj | 2 +- examples/sdk/reactNative/metro.config.js | 21 ++++--- examples/sdk/reactNative/package-lock.json | 29 +++++++++ examples/sdk/reactNative/package.json | 1 + .../android/upload-sourcemaps.gradle | 48 ++++++++++++++ packages/react-native/processSourceMap.js | 62 +++++++++++++++++++ 10 files changed, 223 insertions(+), 70 deletions(-) delete mode 100755 examples/sdk/reactNative/ios-hermesc.sh create mode 100755 examples/sdk/reactNative/ios-sourcemap-upload.sh delete mode 100755 examples/sdk/reactNative/ios-sourcemaps.sh create mode 100644 packages/react-native/android/upload-sourcemaps.gradle create mode 100644 packages/react-native/processSourceMap.js diff --git a/examples/sdk/reactNative/android/app/build.gradle b/examples/sdk/reactNative/android/app/build.gradle index d6a8b43d..2e842111 100644 --- a/examples/sdk/reactNative/android/app/build.gradle +++ b/examples/sdk/reactNative/android/app/build.gradle @@ -1,5 +1,7 @@ apply plugin: "com.android.application" apply plugin: "com.facebook.react" +apply from: "$rootDir/../node_modules/@backtrace/react-native/android/upload-sourcemaps.gradle" + /** * This is the configuration block to customize your React Native Android app. @@ -47,7 +49,7 @@ react { // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" // // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" - // hermesFlags = ["-O", "-output-source-map"] + hermesFlags = ["-O", "-output-source-map"] /* Autolinking */ autolinkLibrariesWithApp() @@ -116,3 +118,9 @@ dependencies { implementation jscFlavor } } + +tasks.matching { + it.name.startsWith("assemble") || it.name.startsWith("build") +}.configureEach { task -> + task.finalizedBy("uploadSourceMapsToBacktrace") +} diff --git a/examples/sdk/reactNative/ios-hermesc.sh b/examples/sdk/reactNative/ios-hermesc.sh deleted file mode 100755 index 7a9c9124..00000000 --- a/examples/sdk/reactNative/ios-hermesc.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -set -e -set -x - -# This script shows how process your application code with source maps and hermesc. By using this script, Backtrace integration can process -# your source code to generate valid source map files. This script does exactly the same what the hermesc script does, with one exception - -# before the native library is generated, this script will process source code and source map to generate output needed in next steps for source map integration. - - -hermes_engine_path="$PODS_ROOT/hermes-engine" -[ -z "$HERMES_CLI_PATH_OVERRIDE" ] && HERMES_CLI_PATH_OVERRIDE="$hermes_engine_path/destroot/bin/hermesc" - -app_bundle_file="${BASH_ARGV[0]}" - -if [[ ! -f "$app_bundle_file" ]]; then - echo "error: File $app_bundle_file does not exist. " >&2 - exit 2 -fi - -# check and assign NODE_BINARY env -source "$REACT_NATIVE_PATH/scripts/node-binary.sh" - -backtrace_js_path="${REACT_NATIVE_PATH}/../.bin/backtrace-js" - -"$NODE_BINARY" "$backtrace_js_path" process --path="$app_bundle_file" - -$HERMES_CLI_PATH_OVERRIDE "$@" diff --git a/examples/sdk/reactNative/ios-sourcemap-upload.sh b/examples/sdk/reactNative/ios-sourcemap-upload.sh new file mode 100755 index 00000000..c3762d1f --- /dev/null +++ b/examples/sdk/reactNative/ios-sourcemap-upload.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Script responsible for preprocessing source maps with debugid and uploading it to Backtrace via backtrace-js. +# Usage: ./ios-sourcemap-upload.sh (Required) Path to the source map file. +# (Required) path to generated backtrace debug id. +# (Required) Path to the .backtracejsrc configuration file. +# +# Adjusting metro configuration is required in order to correctly use debug_id available in the debug_id_file_path. + + +set -e +set -x + +if [ -z "$1" ]; then + echo "Error: Missing path to the source map file." + exit 1 +fi + +source_map_file_path="$1" + +# Check if the file exists +if [ ! -f "$source_map_file_path" ]; then + echo "Error: File '$source_map_file_path' does not exist." + exit 1 +fi + +DEBUG_ID_PATH_ENV="DEBUG_ID_PATH" + +debug_id_file_path=${!DEBUG_ID_PATH_ENV:-${2:-}} + +if [ ! -f "$debug_id_file_path" ]; then + echo "Error: File '$debug_id_file_path' does not exist." + exit 1 +fi + +if [ -z "$3" ]; then + echo "Error: Missing path to the .backtracejsrc file." + exit 1 +fi + +backtrace_configuration_path="$3" + +debug_id=$(<"$debug_id_file_path") + +jq ". += {\"debugId\": \"$debug_id\"}" "$source_map_file_path" > tmp.map && mv tmp.map $source_map_file_path + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# path to react-native module dir relative from this script +backtrace_js_path="${script_dir}/node_modules/.bin/backtrace-js" + +# check and assign NODE_BINARY env +source "$REACT_NATIVE_PATH/scripts/node-binary.sh" + +# run backtrace-js on bundle +"$NODE_BINARY" "$backtrace_js_path" upload \ + -p "$source_map_file_path" \ + --config "$backtrace_configuration_path" diff --git a/examples/sdk/reactNative/ios-sourcemaps.sh b/examples/sdk/reactNative/ios-sourcemaps.sh deleted file mode 100755 index 5ccffdb3..00000000 --- a/examples/sdk/reactNative/ios-sourcemaps.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# This script runs backtrace-js on given path and using given config. -# In this example, backtrace-js will process and upload sourcemaps. -# This should be executed by the iOS build after creating the .jsbundle file. - -set -e -set -x - -script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -config_path=$BACKTRACE_JS_CONFIG -bundle_path=$BACKTRACE_JS_BUNDLE_PATH - -if [[ ! -f "$bundle_path" ]]; then - echo "warn: File $bundle_path does not exist. \ - Try switching to a Release build. \ - Sourcemaps will not be processed." - - exit 0 -fi - -# path to react-native module dir relative from this script -react_native_dir="${script_dir}/node_modules/react-native" -backtrace_js_path="${script_dir}/node_modules/.bin/backtrace-js" - -# check and assign NODE_BINARY env -source "$react_native_dir/scripts/node-binary.sh" - -# run backtrace-js on bundle -"$NODE_BINARY" "$backtrace_js_path" run \ - --config "$config_path" \ - --path "$bundle_path" diff --git a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj index dbaa7e8c..fc4ed7d0 100644 --- a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj +++ b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj @@ -269,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\nset -x\n# destination source map directory\nSOURCE_MAP_DIR=\"$(pwd)/../build\"\nmkdir -p $SOURCE_MAP_DIR\n\nexport SOURCEMAP_FILE=\"$SOURCE_MAP_DIR/main.js.map\";\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n# use hermesc script provided by Backtrace to populate source maps\n# if you dont use hermes support, please skip this step.\nexport HERMES_CLI_PATH=\"$(pwd)/../ios-hermesc.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# copy javascript build output to the build directory\ncp \"$CONFIGURATION_BUILD_DIR/main.jsbundle\" $SOURCE_MAP_DIR \n\nPROCESS_SOURCEMAPS_SCRIPT=\"$(pwd)/../ios-sourcemaps.sh\"\nexport BACKTRACE_JS_CONFIG=\"$(pwd)/../.backtracejsrc\"\nexport BACKTRACE_JS_BUNDLE_PATH=\"$SOURCE_MAP_DIR/main.jsbundle\"\n \n# process source map with javascript code\n/bin/sh -c \"$WITH_ENVIRONMENT $PROCESS_SOURCEMAPS_SCRIPT\"\n"; + shellScript = "set -e\nexport SOURCEMAP_FILE=\"$(pwd)/../main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\nsource_map_upload=\"$(pwd)/../ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$(pwd)/../.backtracejsrc\"\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config\" \n\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/examples/sdk/reactNative/metro.config.js b/examples/sdk/reactNative/metro.config.js index 01b1c1ae..e40af88a 100644 --- a/examples/sdk/reactNative/metro.config.js +++ b/examples/sdk/reactNative/metro.config.js @@ -1,5 +1,6 @@ -const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); +const backtraceSourceMapProcessor = require('@backtrace/react-native/processSourceMap'); /** * Metro configuration @@ -8,12 +9,16 @@ const path = require('path'); * @type {import('metro-config').MetroConfig} */ const config = { - watchFolders: [ - path.resolve('../../../packages/react-native'), - path.resolve('../../../packages/react-native/node_modules'), - path.resolve('../../../node_modules'), - path.resolve('../../../packages/sdk-core'), - ], + watchFolders: [ + path.resolve('../../../packages/react-native'), + path.resolve('../../../packages/react-native/node_modules'), + path.resolve('../../../node_modules'), + path.resolve('../../../packages/sdk-core'), + ], + serializer: { + async customSerializer(entryPoint, preModules, graph, options) { + return backtraceSourceMapProcessor.processSourceMap(entryPoint, preModules, graph, options); + }, + }, }; - module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/examples/sdk/reactNative/package-lock.json b/examples/sdk/reactNative/package-lock.json index a3118123..edb786e8 100644 --- a/examples/sdk/reactNative/package-lock.json +++ b/examples/sdk/reactNative/package-lock.json @@ -17,6 +17,7 @@ "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@backtrace/javascript-cli": "file:../../../tools/cli", + "@backtrace/sourcemap-tools": "file:../../../tools/sourcemap-tools", "@react-native/babel-preset": "0.75.3", "@react-native/eslint-config": "0.75.3", "@react-native/metro-config": "0.75.3", @@ -82,6 +83,7 @@ } }, "../../../tools/cli": { + "name": "@backtrace/javascript-cli", "version": "0.3.2", "dev": true, "license": "MIT", @@ -109,6 +111,29 @@ "node": ">=14" } }, + "../../../tools/sourcemap-tools": { + "name": "@backtrace/sourcemap-tools", + "version": "0.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tar-stream": "^3.1.6" + }, + "devDependencies": { + "@types/decompress": "^4.2.4", + "@types/jest": "^29.5.1", + "@types/tar-stream": "^2.2.2", + "decompress": "^4.2.1", + "jest": "^29.5.0", + "nock": "^13.3.1", + "source-map": "^0.7.4", + "ts-jest": "^29.1.0", + "typescript": "^5.0.4" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "license": "Apache-2.0", @@ -1981,6 +2006,10 @@ "resolved": "../../../packages/react-native", "link": true }, + "node_modules/@backtrace/sourcemap-tools": { + "resolved": "../../../tools/sourcemap-tools", + "link": true + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "dev": true, diff --git a/examples/sdk/reactNative/package.json b/examples/sdk/reactNative/package.json index 52d34df9..8c923703 100644 --- a/examples/sdk/reactNative/package.json +++ b/examples/sdk/reactNative/package.json @@ -18,6 +18,7 @@ "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@backtrace/javascript-cli": "file:../../../tools/cli", + "@backtrace/sourcemap-tools": "file:../../../tools/sourcemap-tools", "@react-native/babel-preset": "0.75.3", "@react-native/eslint-config": "0.75.3", "@react-native/metro-config": "0.75.3", diff --git a/packages/react-native/android/upload-sourcemaps.gradle b/packages/react-native/android/upload-sourcemaps.gradle new file mode 100644 index 00000000..9a758079 --- /dev/null +++ b/packages/react-native/android/upload-sourcemaps.gradle @@ -0,0 +1,48 @@ +import groovy.json.JsonBuilder +import groovy.json.JsonSlurper + + +tasks.register("uploadSourceMapsToBacktrace") { + group = "backtrace" + description = "This task uploads source maps generated by the react-native builder to Backtrace based on the .backtracejsrc file." + + doLast { + // Fetch the build variant (debug or release) + // Default to 'release' if not set + def buildVariant = project.hasProperty("buildVariant") ? project.buildVariant.toLowerCase() : "release" + + def debugIdPathEnv = System.getenv("DEBUG_ID_PATH") + + def debugIdFile = debugIdPathEnv ? file(debugIdPathEnv) : layout.buildDirectory + .dir("intermediates/sourcemaps/react/${buildVariant}/.backtrace-sourcemap-id") + .get() + .asFile + + if (!debugIdFile.exists()) { + println("Backtrace: Cannot find .backtrace-sourcemap-id debug info.") + return + } + + def sourcemapDestinationDirectory = layout.buildDirectory.dir("generated/sourcemaps/react").get().asFile + def mapFiles = fileTree(dir: sourcemapDestinationDirectory, include: '**/*.map').files + def mapFile = mapFiles ? mapFiles.iterator().next() : null + + if (!mapFile) { + println("Backtrace: Cannot find final source map file.") + return + } + + def jsonSlurper = new JsonSlurper() + def mapData = jsonSlurper.parse(mapFile) + mapData.debugId = debugIdFile.text + def jsonBuilder = new JsonBuilder(mapData) + mapFile.text = jsonBuilder.toPrettyString() + + // Execute Backtrace JS CLI to process upload processed source maps + def command = ["npx", "--yes", "@backtrace/javascript-cli", "upload", "-p", mapFile.absolutePath] + exec { + workingDir file("$rootProject.projectDir/..") + commandLine command + } + } +} diff --git a/packages/react-native/processSourceMap.js b/packages/react-native/processSourceMap.js new file mode 100644 index 00000000..b82f83ee --- /dev/null +++ b/packages/react-native/processSourceMap.js @@ -0,0 +1,62 @@ +const bundleToString = require('metro/src/lib/bundleToString'); +const baseJSBundle = require('metro/src/DeltaBundler/Serializers/baseJSBundle'); +const CountingSet = require('metro/src/lib/CountingSet').default; +const fs = require('fs'); +const path = require('path'); +const { DebugIdGenerator, SourceProcessor } = require('@backtrace/sourcemap-tools'); + +const DEBUG_ID_PATH = process.env.DEBUG_ID_PATH; + +/** + * Process metro build with source map support powered by Backtrace. + */ +function processSourceMap(entryPoint, preModules, graph, options) { + const bundle = bundleToString(baseJSBundle(entryPoint, preModules, graph, options)); + + // development build - skip source map upload + if (graph.transformOptions.hot || graph.transformOptions.dev) { + return bundle; + } + + // no source map option set + const sourceMapOutputPathParameter = process.argv.indexOf('--sourcemap-output'); + if (sourceMapOutputPathParameter === -1) { + return bundle; + } + + const sourceMapOutputPath = process.argv[sourceMapOutputPathParameter + 1]; + const backtraceSourceMapId = + DEBUG_ID_PATH ?? path.join(path.dirname(sourceMapOutputPath), '.backtrace-sourcemap-id'); + + const debugIdGenerator = new DebugIdGenerator(); + const sourceProcessor = new SourceProcessor(debugIdGenerator); + const { source, debugId } = sourceProcessor.processSource(bundle.code); + const snippet = debugIdGenerator.generateSourceSnippet(debugId); + + console.debug(`Backtrace: saving debugId ${debugId} to ${backtraceSourceMapId}.`); + fs.writeFileSync(backtraceSourceMapId, debugId); + + const debugIdPrepend = { + dependencies: new Map(), + getSource: () => Buffer.from(snippet), + inverseDependencies: new CountingSet(), + path: '__prelude__', + output: [ + { + type: 'js/script/virtual', + data: { + code: snippet, + lineCount: 1, + map: [], + }, + }, + ], + }; + preModules.unshift(debugIdPrepend); + return { + ...bundle, + code: source, + }; +} + +module.exports = { processSourceMap }; From 8791a47d2a2881c336873b6bae21ab2a9204d6e1 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Tue, 21 Jan 2025 15:10:45 +0100 Subject: [PATCH 2/9] react-native: Flow adjustements & Code review --- examples/sdk/reactNative/ios-sourcemap-upload.sh | 4 ++-- examples/sdk/reactNative/metro.config.js | 4 +--- packages/react-native/android/upload-sourcemaps.gradle | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/sdk/reactNative/ios-sourcemap-upload.sh b/examples/sdk/reactNative/ios-sourcemap-upload.sh index c3762d1f..5d811339 100755 --- a/examples/sdk/reactNative/ios-sourcemap-upload.sh +++ b/examples/sdk/reactNative/ios-sourcemap-upload.sh @@ -1,7 +1,7 @@ #!/bin/bash # Script responsible for preprocessing source maps with debugid and uploading it to Backtrace via backtrace-js. -# Usage: ./ios-sourcemap-upload.sh # Parameters: # (Required) Path to the source map file. # (Required) path to generated backtrace debug id. @@ -44,7 +44,7 @@ backtrace_configuration_path="$3" debug_id=$(<"$debug_id_file_path") -jq ". += {\"debugId\": \"$debug_id\"}" "$source_map_file_path" > tmp.map && mv tmp.map $source_map_file_path +jq ". += {\"debugId\": \"$debug_id\"}" "$source_map_file_path" > "${source_map_file_path}.tmp" && mv "${source_map_file_path}.tmp" $source_map_file_path script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" diff --git a/examples/sdk/reactNative/metro.config.js b/examples/sdk/reactNative/metro.config.js index e40af88a..77361ba5 100644 --- a/examples/sdk/reactNative/metro.config.js +++ b/examples/sdk/reactNative/metro.config.js @@ -16,9 +16,7 @@ const config = { path.resolve('../../../packages/sdk-core'), ], serializer: { - async customSerializer(entryPoint, preModules, graph, options) { - return backtraceSourceMapProcessor.processSourceMap(entryPoint, preModules, graph, options); - }, + customSerializer: backtraceSourceMapProcessor.processSourceMap }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/packages/react-native/android/upload-sourcemaps.gradle b/packages/react-native/android/upload-sourcemaps.gradle index 9a758079..b303588f 100644 --- a/packages/react-native/android/upload-sourcemaps.gradle +++ b/packages/react-native/android/upload-sourcemaps.gradle @@ -19,7 +19,7 @@ tasks.register("uploadSourceMapsToBacktrace") { .asFile if (!debugIdFile.exists()) { - println("Backtrace: Cannot find .backtrace-sourcemap-id debug info.") + println("Backtrace: Cannot find .backtrace-sourcemap-id file. Check if customSerializer has been set to Backtrace serializer in metro.config.js.") return } From 216d734305a0a012b7b1140eb23b0d9e1ddaf1fb Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 10:22:48 +0100 Subject: [PATCH 3/9] react-native: Demo source map description --- examples/sdk/reactNative/README.md | 72 +++++++++++++++++------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/examples/sdk/reactNative/README.md b/examples/sdk/reactNative/README.md index 584989d2..73d8a7a7 100644 --- a/examples/sdk/reactNative/README.md +++ b/examples/sdk/reactNative/README.md @@ -8,53 +8,61 @@ This example app shows features available in the @backtrace/react-native package 2. `npm install`. If you're on iOS, navigate to the `ios` directory and run `pod install` 3. `npm run start` and pick desired platform -#### Source maps +### Source maps + +This example application is integrated with the source map support. Once you change the .backtracejsrc file, source maps will be automatically uploaded to your project. Before executing any step: -- Please update .backtracejsrc file with your symbols submission URL and your sourcemap settings. +> Please update .backtracejsrc file with your symbols submission URL and your sourcemap settings. -On Android: You can verify our example app with the source map support. In order to do that, please use the -android-sourcemap.sh script. +Backtrace is compatible with metro build system. To enable source map support, set a `customSerializer` method in the `metro.config.js` file to the `processSourceMap` function available in `@backtrace/react-native/processSourceMap`. -```bash -./android-sourcemap.sh ./optional-path-to-directory ``` +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); +const backtraceSourceMapProcessor = require('@backtrace/react-native/processSourceMap'); -The script will prepare a release APK version of your React Native application with the sourcemap and Hermes support. -The APK can be found in the ./android/app/build/outputs/apk/release/ directory. +const config = { + serializer: { + customSerializer: backtraceSourceMapProcessor.processSourceMap + }, +}; +module.exports = mergeConfig(getDefaultConfig(__dirname), config); -On iOS: Backtrace simplify the flow needed to upload source maps by instructing hermesc how to generate and prepare -source maps for your application. Without this additional step, react-native will not instruct your application to -support Backtrace source maps. +``` -In order to prepare your application for source maps and automatically upload them to Backtrace, modify your "Build -Phase" with the following code: +Add Backtrace to build automation to ensure every build has source map support. -```bash -set -e +In order to upload source maps to Backtrace, you can: + +**On Android:** -# destination source map directory -SOURCE_MAP_DIR="$(pwd)/../build" -mkdir -p $SOURCE_MAP_DIR +Enable source map support in `app/build.gradle` by uncommenting hermes source map flags. With additional parameters, source maps will be generated. To automatically upload them to Backtrace, you can use the gradle task available the @backtrace/react-native library. -export SOURCEMAP_FILE="$SOURCE_MAP_DIR/main.js.map"; -WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh" -REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh" +`apply from: "$rootDir/../node_modules/@backtrace/react-native/android/upload-sourcemaps.gradle"` -# use hermesc script provided by Backtrace to populate source maps -# if you dont use hermes support, please skip this step. -export HERMES_CLI_PATH="$(pwd)/../ios-hermesc.sh" +Once you import the gradle task, you can simply add it to your flow for any build/assemble tasks. -/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE" +```gradle +tasks.matching { + it.name.startsWith("assemble") || it.name.startsWith("build") +}.configureEach { task -> + task.finalizedBy("uploadSourceMapsToBacktrace") +} +``` -# copy javascript build output to the build directory -cp "$CONFIGURATION_BUILD_DIR/main.jsbundle" $SOURCE_MAP_DIR +**On iOS.** -# process source map with javascript code -npx --yes @backtrace/javascript-cli run --config "$(pwd)/../.backtracejsrc" --path "$SOURCE_MAP_DIR/main.jsbundle" +Modify the code in the `Bundle React Native code and images` step in the `Build Phases` of your xcode project setting. In the end of the script, you can include the code below, to upload source maps directly to Backtrace after generating the applicaiton. -``` +```bash +# enable source map support +export SOURCEMAP_FILE="$(pwd)/../main.jsbundle.map" -Note: this modification copy the output of the javascript build into the build directory created in your application -folder. Please also put ios-hermesc. +... + +# upload source maps to Backtrace +source_map_upload="$(pwd)/../ios-sourcemap-upload.sh" +backtrace_js_config="$(pwd)/../.backtracejsrc" +/bin/sh -c "$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config" +``` From f9df96896cf6ffd98a4822f72aebf54d60e3a95a Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 10:23:44 +0100 Subject: [PATCH 4/9] react-native: Bring standard serialization method, formatting and fix environment variable read --- examples/sdk/reactNative/ios-sourcemap-upload.sh | 2 +- .../sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj | 2 +- examples/sdk/reactNative/metro.config.js | 2 +- packages/react-native/android/upload-sourcemaps.gradle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/sdk/reactNative/ios-sourcemap-upload.sh b/examples/sdk/reactNative/ios-sourcemap-upload.sh index 5d811339..b4519766 100755 --- a/examples/sdk/reactNative/ios-sourcemap-upload.sh +++ b/examples/sdk/reactNative/ios-sourcemap-upload.sh @@ -28,7 +28,7 @@ fi DEBUG_ID_PATH_ENV="DEBUG_ID_PATH" -debug_id_file_path=${!DEBUG_ID_PATH_ENV:-${2:-}} +debug_id_file_path=${DEBUG_ID_PATH_ENV:-${2:-}} if [ ! -f "$debug_id_file_path" ]; then echo "Error: File '$debug_id_file_path' does not exist." diff --git a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj index fc4ed7d0..2e9ed6e3 100644 --- a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj +++ b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj @@ -269,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\nexport SOURCEMAP_FILE=\"$(pwd)/../main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\nsource_map_upload=\"$(pwd)/../ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$(pwd)/../.backtracejsrc\"\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config\" \n\n"; + shellScript = "set -e\n# enable source map support\nexport SOURCEMAP_FILE=\"$(pwd)/../main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# upload source maps to Backtrace\nsource_map_upload=\"$(pwd)/../ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$(pwd)/../.backtracejsrc\"\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config\" \n\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/examples/sdk/reactNative/metro.config.js b/examples/sdk/reactNative/metro.config.js index 77361ba5..2d8fa2a5 100644 --- a/examples/sdk/reactNative/metro.config.js +++ b/examples/sdk/reactNative/metro.config.js @@ -16,7 +16,7 @@ const config = { path.resolve('../../../packages/sdk-core'), ], serializer: { - customSerializer: backtraceSourceMapProcessor.processSourceMap + customSerializer: backtraceSourceMapProcessor.processSourceMap, }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/packages/react-native/android/upload-sourcemaps.gradle b/packages/react-native/android/upload-sourcemaps.gradle index b303588f..bac781f3 100644 --- a/packages/react-native/android/upload-sourcemaps.gradle +++ b/packages/react-native/android/upload-sourcemaps.gradle @@ -36,7 +36,7 @@ tasks.register("uploadSourceMapsToBacktrace") { def mapData = jsonSlurper.parse(mapFile) mapData.debugId = debugIdFile.text def jsonBuilder = new JsonBuilder(mapData) - mapFile.text = jsonBuilder.toPrettyString() + mapFile.text = jsonBuilder.toString() // Execute Backtrace JS CLI to process upload processed source maps def command = ["npx", "--yes", "@backtrace/javascript-cli", "upload", "-p", mapFile.absolutePath] From 15ae2fe73d5e7f2c581e06ee25f0e7c306a182c4 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 11:48:45 +0100 Subject: [PATCH 5/9] react-native: override correctly path to the debug id file in the source map upload script --- examples/sdk/reactNative/ios-sourcemap-upload.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/sdk/reactNative/ios-sourcemap-upload.sh b/examples/sdk/reactNative/ios-sourcemap-upload.sh index b4519766..7a198bb3 100755 --- a/examples/sdk/reactNative/ios-sourcemap-upload.sh +++ b/examples/sdk/reactNative/ios-sourcemap-upload.sh @@ -26,9 +26,7 @@ if [ ! -f "$source_map_file_path" ]; then exit 1 fi -DEBUG_ID_PATH_ENV="DEBUG_ID_PATH" - -debug_id_file_path=${DEBUG_ID_PATH_ENV:-${2:-}} +debug_id_file_path=${DEBUG_ID_PATH:-${2:-}} if [ ! -f "$debug_id_file_path" ]; then echo "Error: File '$debug_id_file_path' does not exist." From 964ff07d0f452a1e52f45b9ed1429bb3d842f325 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 12:47:49 +0100 Subject: [PATCH 6/9] react-native: move upload script to the react-native directory and process source map via node, not via jq --- examples/sdk/reactNative/android-sourcemap.sh | 66 ------------------- .../ios/reactNative.xcodeproj/project.pbxproj | 2 +- .../react-native/addDebugIdToSourceMap.js | 29 ++++++++ .../android/upload-sourcemaps.gradle | 2 +- .../react-native}/ios-sourcemap-upload.sh | 29 +++++--- 5 files changed, 50 insertions(+), 78 deletions(-) delete mode 100755 examples/sdk/reactNative/android-sourcemap.sh create mode 100644 packages/react-native/addDebugIdToSourceMap.js rename {examples/sdk/reactNative => packages/react-native}/ios-sourcemap-upload.sh (65%) diff --git a/examples/sdk/reactNative/android-sourcemap.sh b/examples/sdk/reactNative/android-sourcemap.sh deleted file mode 100755 index e29e428b..00000000 --- a/examples/sdk/reactNative/android-sourcemap.sh +++ /dev/null @@ -1,66 +0,0 @@ -#/bin/bash - -# This script shows how to add source map support to any react-native android application. -# By using it, you can upload source maps to Backtrace and built a release version of the app -# with hermesc support. This script uses .backtracejsrc file available in your react-native directory. -# -# Additional information: This script prepares your bundle for you. In the release build, to prevent "double" application build -# while building final apk/aab, in the build.gradle file, please use `debuggableVariants = ["release"]`. Otherwise -# Gradle and react-native will try to build the application twice and override application version with source map support. - -BUILD_DIR=${1:-build} -BUNDLE_PATH="$BUILD_DIR/index.android.bundle" -SOURCE_MAP_PATH="$BUILD_DIR/index.android.js.map" - -mkdir -p $BUILD_DIR -# build react-native application -npx react-native bundle \ - --platform android \ - --dev false \ - --entry-file index.js \ - --reset-cache \ - --bundle-output $BUNDLE_PATH \ - --sourcemap-output $SOURCE_MAP_PATH \ - --minify false \ - --assets-dest ./android/app/src/main/res/ - - -# add source map identifier to final javascript bundle -npx --yes @backtrace/javascript-cli process --path=$BUNDLE_PATH - -HBC_OUTPUT="$BUILD_DIR/app.hbc" -HBC_MAP_OUTPUT="$HBC_OUTPUT.map" - -# generate react-native executable -./node_modules/react-native/sdks/hermesc/osx-bin/hermesc \ - -emit-binary \ - -max-diagnostic-width=80 \ - -output-source-map \ - -out=$HBC_OUTPUT \ - $BUNDLE_PATH - -# on this stage we have source map for built application via react-native -# and source map for the final executable. Combination of both should generate -# final source map needed to process correctly reports -node ./node_modules/react-native/scripts/compose-source-maps.js \ - $SOURCE_MAP_PATH \ - $HBC_MAP_OUTPUT \ - -o $SOURCE_MAP_PATH - -# upload data to Backtrace -npx --yes @backtrace/javascript-cli run $BUNDLE_PATH - -# prepare android application -mkdir -p ./android/app/src/main/assets -# rename hbc to android.bundle file -mv $HBC_OUTPUT $BUNDLE_PATH - -# prepare android application -mkdir -p ./android/app/build/generated/assets/createBundleReleaseJsAndAssets -cp $BUNDLE_PATH ./android/app/build/generated/assets/createBundleReleaseJsAndAssets/ -mkdir -p ./android/app/build/intermediates/assets/release/ -cp $BUNDLE_PATH ./android/app/build/intermediates/assets/release/ - -cd android -./gradlew assembleRelease -echo "Application build is available under path: ./android/app/build/outputs/apk/release/" \ No newline at end of file diff --git a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj index 2e9ed6e3..3bf3e5d4 100644 --- a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj +++ b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj @@ -269,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n# enable source map support\nexport SOURCEMAP_FILE=\"$(pwd)/../main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# upload source maps to Backtrace\nsource_map_upload=\"$(pwd)/../ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$(pwd)/../.backtracejsrc\"\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config\" \n\n"; + shellScript = "set -e\nproject_directory=\"$(pwd)/..\"\n# enable source map support\nexport SOURCEMAP_FILE=\"$project_directory/main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# upload source maps to Backtrace\nsource_map_upload=\"$project_directory/node_modules/@backtrace/react-native/ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$project_directory/.backtracejsrc\"\n\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config $project_directory\" \n\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/packages/react-native/addDebugIdToSourceMap.js b/packages/react-native/addDebugIdToSourceMap.js new file mode 100644 index 00000000..48de9548 --- /dev/null +++ b/packages/react-native/addDebugIdToSourceMap.js @@ -0,0 +1,29 @@ +#!/bin/bash + +const fs = require('fs'); +const path = require('path'); + +function includeDebugIdInSourceMap(sourceMapPath, debugId) { + if (!fs.existsSync(sourceMapPath)) { + console.error(`Backtrace: source map not found at path ${sourceMapPath}.`); + process.exit(1); + } + + const sourceMapContent = fs.readFileSync(sourceMapPath, 'utf8'); + const sourceMap = JSON.parse(sourceMapContent); + + sourceMap['debugId'] = debugId; + + fs.writeFileSync(sourceMapPath, JSON.stringify(sourceMap), 'utf8'); + console.debug(`Backtrace: Successfully updated source map file ${sourceMapPath} with debug id: ${debugId}`); +} + +const args = process.argv.slice(2); +if (args.length < 2) { + console.error('Usage: node update-json.js '); + process.exit(1); +} + +const sourceMapPath = path.resolve(args[0]); +const debugId = args[1]; +includeDebugIdInSourceMap(sourceMapPath, debugId); diff --git a/packages/react-native/android/upload-sourcemaps.gradle b/packages/react-native/android/upload-sourcemaps.gradle index bac781f3..659584dd 100644 --- a/packages/react-native/android/upload-sourcemaps.gradle +++ b/packages/react-native/android/upload-sourcemaps.gradle @@ -28,7 +28,7 @@ tasks.register("uploadSourceMapsToBacktrace") { def mapFile = mapFiles ? mapFiles.iterator().next() : null if (!mapFile) { - println("Backtrace: Cannot find final source map file.") + println("Backtrace: Cannot find source map file.") return } diff --git a/examples/sdk/reactNative/ios-sourcemap-upload.sh b/packages/react-native/ios-sourcemap-upload.sh similarity index 65% rename from examples/sdk/reactNative/ios-sourcemap-upload.sh rename to packages/react-native/ios-sourcemap-upload.sh index 7a198bb3..3ae49083 100755 --- a/examples/sdk/reactNative/ios-sourcemap-upload.sh +++ b/packages/react-native/ios-sourcemap-upload.sh @@ -1,11 +1,12 @@ #!/bin/bash # Script responsible for preprocessing source maps with debugid and uploading it to Backtrace via backtrace-js. -# Usage: ./ios-sourcemap-upload.sh +# Usage: ./ios-sourcemap-upload.sh # Parameters: -# (Required) Path to the source map file. -# (Required) path to generated backtrace debug id. -# (Required) Path to the .backtracejsrc configuration file. +# (Required) Path to the source map file. +# (Required) Path to generated backtrace debug id. +# (Required) Path to the .backtracejsrc configuration file. +# (Required) Path to the react-native project directory # # Adjusting metro configuration is required in order to correctly use debug_id available in the debug_id_file_path. @@ -38,19 +39,27 @@ if [ -z "$3" ]; then exit 1 fi +if [ -z "$4" ]; then + echo "Error: Missing path to the project directory." + exit 1 +fi + +project_directory_path="$4" + backtrace_configuration_path="$3" +# check and assign NODE_BINARY env +source "$REACT_NATIVE_PATH/scripts/node-binary.sh" debug_id=$(<"$debug_id_file_path") -jq ". += {\"debugId\": \"$debug_id\"}" "$source_map_file_path" > "${source_map_file_path}.tmp" && mv "${source_map_file_path}.tmp" $source_map_file_path - script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# path to react-native module dir relative from this script -backtrace_js_path="${script_dir}/node_modules/.bin/backtrace-js" +"$NODE_BINARY" "$script_dir/addDebugIdToSourceMap.js" \ + "$source_map_file_path" \ + "$debug_id" -# check and assign NODE_BINARY env -source "$REACT_NATIVE_PATH/scripts/node-binary.sh" +# path to react-native module dir relative from this script +backtrace_js_path="${project_directory_path}/node_modules/.bin/backtrace-js" # run backtrace-js on bundle "$NODE_BINARY" "$backtrace_js_path" upload \ From 11abba5ae1279da5a85585920bf67efae95c68c1 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 14:18:09 +0100 Subject: [PATCH 7/9] react-native: use basename of the script Co-authored-by: Sebastian Alex --- packages/react-native/addDebugIdToSourceMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/addDebugIdToSourceMap.js b/packages/react-native/addDebugIdToSourceMap.js index 48de9548..36ec335b 100644 --- a/packages/react-native/addDebugIdToSourceMap.js +++ b/packages/react-native/addDebugIdToSourceMap.js @@ -20,7 +20,7 @@ function includeDebugIdInSourceMap(sourceMapPath, debugId) { const args = process.argv.slice(2); if (args.length < 2) { - console.error('Usage: node update-json.js '); + console.error(`Usage: node ${path.basename(args[1])} `); process.exit(1); } From ee97e7f09145596d11e0882e4a78c83b71fbf7f7 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 14:22:31 +0100 Subject: [PATCH 8/9] react-native: uplaod script- remove shebang from addDebugIdToSourceMap --- packages/react-native/addDebugIdToSourceMap.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native/addDebugIdToSourceMap.js b/packages/react-native/addDebugIdToSourceMap.js index 36ec335b..77f280f3 100644 --- a/packages/react-native/addDebugIdToSourceMap.js +++ b/packages/react-native/addDebugIdToSourceMap.js @@ -1,5 +1,3 @@ -#!/bin/bash - const fs = require('fs'); const path = require('path'); From 4c9c1b0a9999b790af6743f39bee694ff0a9f9d8 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 23 Jan 2025 18:45:20 +0100 Subject: [PATCH 9/9] react-native: move scripts into the script directory and adjust paths to them in readme/xcode --- examples/sdk/reactNative/README.md | 15 +++++++++------ .../ios/reactNative.xcodeproj/project.pbxproj | 2 +- examples/sdk/reactNative/metro.config.js | 2 +- .../{ => scripts}/addDebugIdToSourceMap.js | 0 .../{ => scripts}/ios-sourcemap-upload.sh | 0 .../{ => scripts}/processSourceMap.js | 4 ++-- 6 files changed, 13 insertions(+), 10 deletions(-) rename packages/react-native/{ => scripts}/addDebugIdToSourceMap.js (100%) rename packages/react-native/{ => scripts}/ios-sourcemap-upload.sh (100%) rename packages/react-native/{ => scripts}/processSourceMap.js (92%) diff --git a/examples/sdk/reactNative/README.md b/examples/sdk/reactNative/README.md index 73d8a7a7..d89d82f3 100644 --- a/examples/sdk/reactNative/README.md +++ b/examples/sdk/reactNative/README.md @@ -16,11 +16,11 @@ Before executing any step: > Please update .backtracejsrc file with your symbols submission URL and your sourcemap settings. -Backtrace is compatible with metro build system. To enable source map support, set a `customSerializer` method in the `metro.config.js` file to the `processSourceMap` function available in `@backtrace/react-native/processSourceMap`. +Backtrace is compatible with metro build system. To enable source map support, set a `customSerializer` method in the `metro.config.js` file to the `processSourceMap` function available in `@backtrace/react-native/scripts/processSourceMap`. ``` const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); -const backtraceSourceMapProcessor = require('@backtrace/react-native/processSourceMap'); +const backtraceSourceMapProcessor = require('@backtrace/react-native/scripts/processSourceMap'); const config = { serializer: { @@ -56,13 +56,16 @@ tasks.matching { Modify the code in the `Bundle React Native code and images` step in the `Build Phases` of your xcode project setting. In the end of the script, you can include the code below, to upload source maps directly to Backtrace after generating the applicaiton. ```bash +project_directory="$(pwd)/.." # enable source map support -export SOURCEMAP_FILE="$(pwd)/../main.jsbundle.map" +export SOURCEMAP_FILE="$project_directory/main.jsbundle.map" ... # upload source maps to Backtrace -source_map_upload="$(pwd)/../ios-sourcemap-upload.sh" -backtrace_js_config="$(pwd)/../.backtracejsrc" -/bin/sh -c "$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config" +source_map_upload="$project_directory/node_modules/@backtrace/react-native/scripts/ios-sourcemap-upload.sh" +backtrace_js_config="$project_directory/.backtracejsrc" + +/bin/sh -c "$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config $project_directory" + ``` diff --git a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj index 3bf3e5d4..cfa76c47 100644 --- a/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj +++ b/examples/sdk/reactNative/ios/reactNative.xcodeproj/project.pbxproj @@ -269,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\nproject_directory=\"$(pwd)/..\"\n# enable source map support\nexport SOURCEMAP_FILE=\"$project_directory/main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# upload source maps to Backtrace\nsource_map_upload=\"$project_directory/node_modules/@backtrace/react-native/ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$project_directory/.backtracejsrc\"\n\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config $project_directory\" \n\n"; + shellScript = "set -e\nproject_directory=\"$(pwd)/..\"\n# enable source map support\nexport SOURCEMAP_FILE=\"$project_directory/main.jsbundle.map\"\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n\n# upload source maps to Backtrace\nsource_map_upload=\"$project_directory/node_modules/@backtrace/react-native/scripts/ios-sourcemap-upload.sh\"\nbacktrace_js_config=\"$project_directory/.backtracejsrc\"\n\n/bin/sh -c \"$source_map_upload $SOURCEMAP_FILE $TARGET_BUILD_DIR/.backtrace-sourcemap-id $backtrace_js_config $project_directory\" \n\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/examples/sdk/reactNative/metro.config.js b/examples/sdk/reactNative/metro.config.js index 2d8fa2a5..e4a564eb 100644 --- a/examples/sdk/reactNative/metro.config.js +++ b/examples/sdk/reactNative/metro.config.js @@ -1,6 +1,6 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); -const backtraceSourceMapProcessor = require('@backtrace/react-native/processSourceMap'); +const backtraceSourceMapProcessor = require('@backtrace/react-native/scripts/processSourceMap'); /** * Metro configuration diff --git a/packages/react-native/addDebugIdToSourceMap.js b/packages/react-native/scripts/addDebugIdToSourceMap.js similarity index 100% rename from packages/react-native/addDebugIdToSourceMap.js rename to packages/react-native/scripts/addDebugIdToSourceMap.js diff --git a/packages/react-native/ios-sourcemap-upload.sh b/packages/react-native/scripts/ios-sourcemap-upload.sh similarity index 100% rename from packages/react-native/ios-sourcemap-upload.sh rename to packages/react-native/scripts/ios-sourcemap-upload.sh diff --git a/packages/react-native/processSourceMap.js b/packages/react-native/scripts/processSourceMap.js similarity index 92% rename from packages/react-native/processSourceMap.js rename to packages/react-native/scripts/processSourceMap.js index b82f83ee..ed4e893b 100644 --- a/packages/react-native/processSourceMap.js +++ b/packages/react-native/scripts/processSourceMap.js @@ -10,7 +10,7 @@ const DEBUG_ID_PATH = process.env.DEBUG_ID_PATH; /** * Process metro build with source map support powered by Backtrace. */ -function processSourceMap(entryPoint, preModules, graph, options) { +async function processSourceMap(entryPoint, preModules, graph, options) { const bundle = bundleToString(baseJSBundle(entryPoint, preModules, graph, options)); // development build - skip source map upload @@ -30,7 +30,7 @@ function processSourceMap(entryPoint, preModules, graph, options) { const debugIdGenerator = new DebugIdGenerator(); const sourceProcessor = new SourceProcessor(debugIdGenerator); - const { source, debugId } = sourceProcessor.processSource(bundle.code); + const { source, debugId } = await sourceProcessor.processSource(bundle.code); const snippet = debugIdGenerator.generateSourceSnippet(debugId); console.debug(`Backtrace: saving debugId ${debugId} to ${backtraceSourceMapId}.`);