diff --git a/CHANGELOG.md b/CHANGELOG.md index 9970aef2a3..b7950ea28a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ ## Unreleased +### Features + +- Add `withSentryExpoSerializers` for easy configurable `metro.config.js` ([#3454](https://github.com/getsentry/sentry-react-native/pull/3454)) + + ```js + const { getDefaultConfig } = require('expo/metro-config'); + const { withSentryExpoSerializers } = require("@sentry/react-native/metro"); + + const config = getDefaultConfig(__dirname); + module.exports = withSentryExpoSerializers(config); + ``` + + Note that this will remove any existing `customSerializer`. Guide for advanced setups [can be found here](https://docs.sentry.io/platforms/react-native/manual-setup/metro). + ### Fixes - Expo SDK minimum version is 49 ([#3453](https://github.com/getsentry/sentry-react-native/pull/3453)) diff --git a/package.json b/package.json index 6288f1358d..1f4a95ec79 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ }, "devDependencies": { "@babel/core": "^7.23.5", + "@expo/metro-config": "^0.10.7", "@sentry-internal/eslint-config-sdk": "7.81.1", "@sentry-internal/eslint-plugin-sdk": "7.81.1", "@sentry-internal/typescript": "7.80.0", diff --git a/src/js/tools/sentryMetroSerializer.ts b/src/js/tools/sentryMetroSerializer.ts index 747440b579..a3875680a4 100644 --- a/src/js/tools/sentryMetroSerializer.ts +++ b/src/js/tools/sentryMetroSerializer.ts @@ -1,5 +1,6 @@ import * as crypto from 'crypto'; -import type { MixedOutput, Module } from 'metro'; +import type { MetroConfig, MixedOutput, Module } from 'metro'; +import { mergeConfig } from 'metro'; import * as countLines from 'metro/src/lib/countLines'; import type { Bundle, MetroSerializer, MetroSerializerOutput, SerializedBundle, VirtualJSOutput } from './utils'; @@ -14,6 +15,37 @@ const PRELUDE_MODULE_PATH = '__prelude__'; const SOURCE_MAP_COMMENT = '//# sourceMappingURL='; const DEBUG_ID_COMMENT = '//# debugId='; +/** + * This function will overwrite any existing custom serializer with default Expo and Sentry serializers. + * + * To use custom serializers, use `createSentryMetroSerializer(customSerializer)` instead. + */ +export function withSentryExpoSerializers(config: MetroConfig): MetroConfig { + const { withExpoSerializers } = loadExpoSerializersModule(); + + const sentryConfig = { + serializer: { + customSerializer: createSentryMetroSerializer(), + }, + } as MetroConfig; + + const finalConfig = mergeConfig(config, sentryConfig); + return withExpoSerializers(finalConfig); +} + +function loadExpoSerializersModule(): { + withExpoSerializers: (config: MetroConfig) => MetroConfig; +} { + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require('@expo/metro-config/build/serializer/withExpoSerializers'); + } catch (e) { + throw new Error( + 'Unable to load `withExpoSerializers` from `@expo/metro-config`. Make sure you have Expo installed.', + ); + } +} + /** * Creates a Metro serializer that adds Debug ID module to the plain bundle. * The Debug ID module is a virtual module that provides a debug ID in runtime. diff --git a/yarn.lock b/yarn.lock index 525c96c18e..42c8d8557b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2461,7 +2461,7 @@ json5 "^2.2.2" write-file-atomic "^2.3.0" -"@expo/metro-config@~0.10.0": +"@expo/metro-config@^0.10.7", "@expo/metro-config@~0.10.0": version "0.10.7" resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.10.7.tgz#d1b91baffcb7feb52fc7e2e122450bfc5d01e7c1" integrity sha512-uACymEiyX0447hI4unt+2cemLQkTZXKvTev936NhtsgVnql45EP0V0pzmo/0H0WlHaAGXgvOBZJl8wFqcJ3CbQ==