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

How to use Sentry Babel Transformer (react annotations) with other React Native transformers? #4459

Open
ybentz opened this issue Jan 16, 2025 · 2 comments

Comments

@ybentz
Copy link

ybentz commented Jan 16, 2025

What React Native libraries do you use?

Expo (mobile only), Expo Application Services (EAS), Hermes, Expo Router

Are you using sentry.io or on-premise?

sentry.io (SaS)

@sentry/react-native SDK Version

5.33.2

How does your development environment look like?

OS: macOS 15.1
CPU: (10) arm64 Apple M1 Pro
Node: 20.11.0
Yarn: 1.22.22
CocoaPods: 1.15.2
Expo SDK: 51.0.36
react-native: 0.74.5
react: 18.2.0
hermesEnabled: true
newArchEnabled: false

Sentry.init()

const routingInstrumentation = Sentry.reactNavigationIntegration()
Sentry.init({
  dsn: sentryDsn,
  debug: false,
  integrations: [
    Sentry.reactNativeTracingIntegration({
      routingInstrumentation,
    }),
    extraErrorDataIntegration({ depth: 10 }),
  ],
})

Steps to Reproduce

I'm trying to get the React Component Names feature to work for my Expo app. I've followed the simple instruction to do so but I did not see any difference in the test error events.

I originally tried that a few months ago when the feature was relatively new. I recently decided to give it another shot and noticed that in the docs for enabling the feature you now explicitly mention that:

If you are Expo user using const config = getSentryExpoConfig(__dirname) make sure the config.transformer.babelTransformerPath set by the getSentryExpoConfig is not overwritten.

So I checked and we're indeed overwriting the babelTransformerPath because that's part of the installation steps for the popular react-native-svg-transformer package.
I looked around and the most recommended solution I found for combining transformers is to write a custom one. An example can be found here, which specifically mentions react-native-svg-transformer. The problem I'm having with this approach is that currently it doesn't seem like consumers of the Sentry SDK have access to the Sentry Babel transformer so I can't call it as a fallback if the current file is not an SVG.

After looking at the source code for this SDK I tried a couple of things that I thought may work. The code snippets below are my attempts at implementing a custom transformer (call it custom-transformer.js) and then passing the path to it as the value of config.transformer.babelTransformerPath in my metro config like babelTransformerPath: require.resolve("./custom-transformer").

The code below loads the app fine but does not apply the React component names feature because the config.transformer.babelTransformerPath points to /node_modules/@expo/metro-config/build/babel-transformer.js and not the Sentry transformer.

const svgTransformer = require("react-native-svg-transformer/expo")
const { getSentryExpoConfig } = require("@sentry/react-native/metro")

module.exports.transform = function ({ src, filename, options }) {
  const config = getSentryExpoConfig(__dirname, {
    annotateReactComponents: true,
  })
  const transformer = require(config.transformer?.babelTransformerPath)
  if (filename.endsWith(".svg")) {
    return svgTransformer.transform({ src, filename, options })
  } else {
    return transformer.transform({ src, filename, options })
  }
}

I also tried this code below but it throws an error that transformer.transform is not a function:

const svgTransformer = require("react-native-svg-transformer/expo")
const { getSentryExpoConfig } = require("@sentry/react-native/metro")

module.exports.transform = function ({ src, filename, options }) {
  const config = getSentryExpoConfig(__dirname, {
    annotateReactComponents: true,
  })
  const { transformer } = config
  if (filename.endsWith(".svg")) {
    return svgTransformer.transform({ src, filename, options })
  } else {
    return transformer.transform({ src, filename, options })
  }
}

I verified that this is the only issue with enabling the feature by completely removing the usage of SVG transformer from the code which broke my icons but my test Sentry event did show the component names as expected.


I think ideally the Sentry SDK will expose the transformer to make this possible, just like other popular transformers such as:

  • react-native-svg-transformer
  • react-native-sass-transformer
  • react-native-obfuscating-transformer

Since the above libs all require changing the default metro transformer I can't imagine we're the only ones that encountered this issue trying to combine one of the above libs with Sentry so I think the community will all benefit from this change and instructions for how to implement it should probably be added to the feature's docs.

Thank you!

Expected Result

React Component Names feature should work

Actual Result

It does not

@krystofwoldrich
Copy link
Member

Hi @ybentz,
thank you for the details and the suggestions. We will update our docs to include a custom transformer example.


The Sentry Transformer wraps any transformer present in the config. To use the Sentry Transformer with react-native-svg-transformer and other libraries, change the transformer in the config before Sentry wraps the transformer.

You can do this in Expo applications by overwriting the getDefaultConfig option.

const { getDefaultConfig } = require('@expo/metro-config');
const { getSentryExpoConfig } = require('@sentry/react-native/metro');

const config = getSentryExpoConfig(__dirname, {
  getDefaultConfig: (projectRoot, options) => {
    const config = getDefaultConfig(projectRoot, options);
    const { transformer, resolver } = config;

    config.transformer = {
      ...transformer,
      babelTransformerPath: require.resolve('react-native-svg-transformer/expo'),
    };
    return config;
  },
  annotateReactComponents: true,
});

//...

I will leave this open as a feature request to expose the Sentry Transformer.

@krystofwoldrich krystofwoldrich changed the title React Component Names doesn't work How to use Sentry Babel Transformer (react annotations) with other React Native transformers? Jan 24, 2025
@krystofwoldrich krystofwoldrich self-assigned this Jan 24, 2025
@krystofwoldrich krystofwoldrich moved this from Needs Discussion to Todo in Mobile & Cross Platform SDK Jan 24, 2025
@ybentz
Copy link
Author

ybentz commented Jan 27, 2025

@krystofwoldrich thanks! I just tried this out and everything seems to be working as intended (only ran a very quick sanity test so far though).

As a side note to anyone else that may land here, you'll want to add the rest of the config that's required for the alternative transformer according to the relevant docs to the example above (e.g. overriding the resolver in addition to transformer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Status: Todo
Development

No branches or pull requests

2 participants