Skip to content

Conversation

@marco-saia-datadog
Copy link
Member

@marco-saia-datadog marco-saia-datadog commented Apr 23, 2025

Overview

This PR introduces a Metro configuration that automates the generation of unique Debug IDs for RN bundles. The main objective is to enable more consistent unminification of stack traces on the backend.

What's included

  • Automatic Debug ID Generation:
    Each bundle is assigned a unique Debug ID at build time.

  • Runtime Debug ID Injection:
    A code snippet is injected into the bundle, exposing the Debug ID at runtime so it can be attached to the RUM Error Context as _dd.debug_id.

  • Bundle Debug ID Comment:
    The Debug ID is added as a comment at the end of the bundle file:
    //# debugId=[DEBUG-ID]

  • Source Map Injection:
    The Debug ID is added as a top-level debugId property in the generated sourcemaps.

  • Runtime Debug ID injection in Expo:
    Introduced Expo config with getDatadogExpoConfig to inject the Debug ID code snippet for runtime consumption.

Usage in Metro Config

Vanilla React Native

const { getDefaultConfig } = require('@react-native/metro-config');
const { withDatadogMetroConfig } = require('@datadog/mobile-react-native/metro');

module.exports = withDatadogMetroConfig(getDefaultConfig(__dirname));

Expo

const { getDatadogExpoConfig } = require('@datadog/mobile-react-native/metro');

const config = getDatadogExpoConfig(__dirname);

module.exports = config;

Additional Notes

  • The process is skipped when hot reloading is enabled
  • If the //# sourceMappingURL=... comment is found in the bundle, the debugId comment will be inserted right before it
  • getDatadogExpoConfig accepts custom options, and the default Expo config can be overriden

PR Checklist

  • Feature or bugfix MUST have appropriate tests
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)
  • If this PR is auto-generated, please make sure also to manually update the code related to the change

@marco-saia-datadog marco-saia-datadog force-pushed the marcosaia/RUM-8382/metro-plugin branch from 4719737 to 5ec48f6 Compare April 23, 2025 07:49
@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Apr 23, 2025

Datadog Report

Branch report: marcosaia/RUM-8382/metro-plugin
Commit report: 9e6523c
Test service: dd-sdk-reactnative

✅ 0 Failed, 680 Passed, 1 Skipped, 5.53s Total Time

@marco-saia-datadog marco-saia-datadog force-pushed the marcosaia/RUM-8382/metro-plugin branch 2 times, most recently from 92872e6 to 987afd8 Compare April 29, 2025 13:46
@marco-saia-datadog marco-saia-datadog force-pushed the marcosaia/RUM-8382/metro-plugin branch from 987afd8 to 096e6e8 Compare April 29, 2025 13:53
@marco-saia-datadog marco-saia-datadog marked this pull request as ready for review April 30, 2025 14:25
@marco-saia-datadog marco-saia-datadog requested a review from a team as a code owner April 30, 2025 14:25
@marco-saia-datadog marco-saia-datadog added the Do not merge This PR is not ready to be merged yet label Apr 30, 2025
@marco-saia-datadog marco-saia-datadog force-pushed the marcosaia/RUM-8382/metro-plugin branch from 096e6e8 to 44d684d Compare June 17, 2025 11:50
@marco-saia-datadog marco-saia-datadog force-pushed the marcosaia/RUM-8382/metro-plugin branch from 44d684d to 91bf204 Compare June 17, 2025 11:51
@marco-saia-datadog marco-saia-datadog removed Do not merge This PR is not ready to be merged yet labels Jun 17, 2025
const debugIds = (globalThis as any)._datadogDebugIds;
if (!debugIds || Object.keys(debugIds).length === 0) {
console.warn(
'[Datadog SDK] Debug ID not found. Are you using @datadog/mobile-react-native/metro config?'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps when we have a defined documentation page for this feature we should modify this to point users in the right direction 📖

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks! 👍

sbarrio
sbarrio previously approved these changes Jun 18, 2025
Copy link
Contributor

@sbarrio sbarrio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some minor comments, it looks great 👏

sbarrio
sbarrio previously approved these changes Jun 18, 2025
@marco-saia-datadog
Copy link
Member Author

There is a problem on iOS new architecture caused by the new explicit exports in package.json:

    "exports": {
        ".": {
            "import": "./lib/module/index.js",
            "require": "./lib/commonjs/index.js",
            "types": "./lib/typescript/index.d.ts"
        },
        "./metro": {
            "import": "./lib/module/metro.js",
            "require": "./lib/commonjs/metro.js",
            "types": "./lib/typescript/metro.d.ts"
        }
  }

I have looked into it, and it is caused by how the podfile react_native_pods.rb script looks for the dependencies for codegen:

https://github.com/facebook/react-native/blob/2e10ba945f6f2dca8d8cf1bb0db1d67fd50f2235/packages/react-native/scripts/codegen/generate-artifacts-executor.js#L241

      const configFilePath = require.resolve(
        path.join(dependency, 'package.json'),
        {paths: [projectRoot]},
      );

By adding a debug log we get:

[DD-DEBUG] Error: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package.json' is not defined by <redacted>/dd-sdk-reactnative/example-new-architecture/node_modules/@datadog/mobile-react-native/package.json

I have modified the exports to explicitly include package.json, and the issue seems to be resolved now.

@marco-saia-datadog marco-saia-datadog merged commit 21a5a69 into develop Jun 19, 2025
10 checks passed
@marco-saia-datadog marco-saia-datadog deleted the marcosaia/RUM-8382/metro-plugin branch June 19, 2025 11:59
Comment on lines +41 to +53
"exports": {
".": {
"import": "./lib/module/index.js",
"require": "./lib/commonjs/index.js",
"types": "./lib/typescript/index.d.ts"
},
"./metro": {
"import": "./lib/module/metro.js",
"require": "./lib/commonjs/metro.js",
"types": "./lib/typescript/metro.d.ts"
},
"./package.json": "./package.json"
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marco-saia-datadog I believe this broke jest mock.

    Cannot find module '@datadog/mobile-react-native/jest/mock' from 'src/test/globalMocks.tsx'

    Require stack:
      node_modules/@datadog/mobile-react-navigation/lib/commonjs/rum/instrumentation/DdRumReactNavigationTracking.js
      node_modules/@datadog/mobile-react-navigation/lib/commonjs/index.js
      src/providers/ReactNavigationContainer.tsx
      src/providers/PostHogProvider.tsx
      src/hooks/useIsFeatureEnabled.ts
      src/hooks/useIsDevMode.ts
      src/components/LoanPreview/LoanTinyPreview.tsx
      src/components/LoanPreview/LoanTinyPreview.test.tsx

      166 |
      167 | jest.mock('@datadog/mobile-react-native', () =>
    > 168 |   require('@datadog/mobile-react-native/jest/mock'),
          |   ^
      169 | );
      170 |
      171 | jest.mock('react-native-persona', () => {

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at require (src/test/globalMocks.tsx:168:3)
      at Object.require (node_modules/@datadog/mobile-react-navigation/src/rum/instrumentation/DdRumReactNavigationTracking.tsx:7:1)
      at Object.require (node_modules/@datadog/mobile-react-navigation/src/index.tsx:8:1)
      at Object.require (src/providers/ReactNavigationContainer.tsx:2:1)
      at Object.require (src/providers/PostHogProvider.tsx:6:1)
      at Object.require (src/hooks/useIsFeatureEnabled.ts:4:1)
      at Object.require (src/hooks/useIsDevMode.ts:1:1)
      at Object.require (src/components/LoanPreview/LoanTinyPreview.tsx:7:1)
      at Object.require (src/components/LoanPreview/LoanTinyPreview.test.tsx:7:1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants