Skip to content

Commit 88a0b65

Browse files
fix(expo): Do not try to load native components in Expo Go (#4696)
1 parent e12327b commit 88a0b65

File tree

5 files changed

+36
-3
lines changed

5 files changed

+36
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
### Fixes
3434

3535
- Equalize TTID and TTFD duration when TTFD manual API is called and resolved before auto TTID ([#4680](https://github.com/getsentry/sentry-react-native/pull/4680))
36+
- Avoid loading Sentry native components in Expo Go ([#4696](https://github.com/getsentry/sentry-react-native/pull/4696))
3637

3738
### Changes
3839

packages/core/src/js/replay/CustomMask.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import * as React from 'react';
33
import type { HostComponent, ViewProps } from 'react-native';
44
import { UIManager, View } from 'react-native';
55

6+
import { isExpoGo } from '../utils/environment';
7+
68
const NativeComponentRegistry: {
79
get<T, C extends Record<string, unknown>>(componentName: string, createViewConfig: () => C): HostComponent<T>;
810
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -35,7 +37,7 @@ const UnmaskFallback = (viewProps: ViewProps): React.ReactElement => {
3537
const hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig && UIManager.hasViewManagerConfig(nativeComponentName);
3638

3739
const Mask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {
38-
if (!hasViewManagerConfig(MaskNativeComponentName)) {
40+
if (isExpoGo() || !hasViewManagerConfig(MaskNativeComponentName)) {
3941
logger.warn(`[SentrySessionReplay] Can't load ${MaskNativeComponentName}.`);
4042
return MaskFallback;
4143
}
@@ -48,7 +50,7 @@ const Mask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {
4850
})()
4951

5052
const Unmask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {
51-
if (!hasViewManagerConfig(UnmaskNativeComponentName)) {
53+
if (isExpoGo() || !hasViewManagerConfig(UnmaskNativeComponentName)) {
5254
logger.warn(`[SentrySessionReplay] Can't load ${UnmaskNativeComponentName}.`);
5355
return UnmaskFallback;
5456
}

packages/core/src/js/tracing/timetodisplaynative.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from 'react';
22
import type { HostComponent } from 'react-native';
33
import { UIManager, View } from 'react-native';
44

5+
import { isExpoGo } from '../utils/environment';
56
import { ReactNativeLibraries } from '../utils/rnlibraries';
67
import type { RNSentryOnDrawReporterProps } from './timetodisplaynative.types';
78

@@ -29,7 +30,7 @@ let RNSentryOnDrawReporter: HostComponent<RNSentryOnDrawReporterProps> | typeof
2930
*/
3031
export const getRNSentryOnDrawReporter = (): typeof RNSentryOnDrawReporter => {
3132
if (!RNSentryOnDrawReporter) {
32-
RNSentryOnDrawReporter = nativeComponentExists && ReactNativeLibraries.ReactNative?.requireNativeComponent
33+
RNSentryOnDrawReporter = !isExpoGo() && nativeComponentExists && ReactNativeLibraries.ReactNative?.requireNativeComponent
3334
? ReactNativeLibraries.ReactNative.requireNativeComponent(RNSentryOnDrawReporterClass)
3435
: RNSentryOnDrawReporterNoop;
3536
}

packages/core/test/replay/CustomMask.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,23 @@ import { beforeEach, describe, expect, it } from '@jest/globals';
22

33
describe('CustomMask', () => {
44
beforeEach(() => {
5+
jest.mock('../../src/js/utils/environment', () => ({
6+
isExpoGo: () => false,
7+
}));
58
jest.resetModules();
69
});
710

11+
it('returns a fallback when isExpoGo is true', () => {
12+
jest.mock('../../src/js/utils/environment', () => ({
13+
isExpoGo: () => true,
14+
}));
15+
16+
const { Mask, Unmask, MaskFallback, UnmaskFallback } = require('../../src/js/replay/CustomMask');
17+
18+
expect(Mask).toBe(MaskFallback);
19+
expect(Unmask).toBe(UnmaskFallback);
20+
});
21+
822
it('returns a fallback when native view manager is missing', () => {
923
jest.mock('react-native', () => ({
1024
UIManager: {},
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { getRNSentryOnDrawReporter } from '../../src/js/tracing/timetodisplaynative';
2+
import * as Environment from '../../src/js/utils/environment';
3+
4+
describe('timetodisplaynative', () => {
5+
beforeEach(() => {
6+
jest.spyOn(Environment, 'isExpoGo').mockReturnValue(false);
7+
});
8+
9+
test('getRNSentryOnDrawReporter returns Noop in Expo Go', () => {
10+
jest.spyOn(Environment, 'isExpoGo').mockReturnValue(true);
11+
const drawReported = getRNSentryOnDrawReporter();
12+
13+
expect(drawReported.name).toBe('RNSentryOnDrawReporterNoop');
14+
});
15+
});

0 commit comments

Comments
 (0)