getsentry / sentry-react-native

Official Sentry SDK for React Native
https://sentry.io
MIT License
1.59k stars 337 forks source link

Sentry metro bundle splitting - filename hash is wrong and source code does not point to correct module .js files #4317

Open ricklove opened 2 hours ago

ricklove commented 2 hours ago

What React Native libraries do you use?

Expo Web, Expo Router

Are you using sentry.io or on-premise?

sentry.io (SaS)

@sentry/react-native SDK Version

6.3.0

How does your development environment look like?

"@sentry/react-native": "~6.3.0", "expo": "^52.0.11", "react": "18.3.1", "react-native": "0.76.3",

Sentry.init()

Sentry.init({ dsn: process.env.EXPO_PUBLIC_APP_SENTRY_DSN, debug: true, });

Steps to Reproduce

Use React.lazy to dynamically load a module (that uses a default export):

const DynamicComponent = React.lazy(() => import('.example.tsx'));

This will enable bundle splitting. Now use getSentryExpoConfig instead of getDefaultConfig and the dynamic bundle will fail to import at runtime. (Everything builds and the initial index.js will load, but upon first loading a dynamic module, it fails because the module filename hash is wrong.)

The filenames for the bundles are changed, but internally the module code still tries to import the original paths.

Expected Result

The imported file names should match the new module filenames after sentry injected it's code.

Actual Result

The imported file names do not match the actual file names. The actual filenames saved in the dist folder is changed, but the imports still try to import the original filenames.

For example:

/_expo/static/js/web/icon-85ddfcb05c4f588fb9924ef24ca2aea9.js (This is imported) changes to /_expo/static/js/web/icon-1131b4f3e7922204435b95f36bc75f6e.js (This should be imported)

However, the module map still points to: "2125":"/_expo/static/js/web/icon-85ddfcb05c4f588fb9924ef24ca2aea9.js"

Also: the file contents had this prefixed:

var _sentryDebugIds,_sentryDebugIdIdentifier;void 0===_sentryDebugIds&&(_sentryDebugIds={});try{var stack=(new Error).stack;stack&&(_sentryDebugIds[stack]="9769af17-...",_sentryDebugIdIdentifier="sentry-dbid-....")}catch(e){}

Analysis:

Confirmed, commenting out this line in metro fixes this. This line updates filenames after unstable_beforeAssetSerializationPlugin is called.

https://github.com/expo/expo/blob/0d46fc187c55e6b73507f7e44f0d9e19c4893f64/packages/%40expo/metro-config/src/serializer/serializeChunks.ts#L403

ricklove commented 2 hours ago

This seems related, but it is not the same: https://github.com/getsentry/sentry-react-native/issues/3663

ricklove commented 2 hours ago

This appears to be where it goes wrong: https://github.com/getsentry/sentry-react-native/blob/8ab11b68f5637b8a7886341bcc06214f8cd48ebb/packages/core/src/js/tools/sentryMetroSerializer.ts#L22

ricklove commented 2 hours ago

In the latest metro code, it has something similar to this old PR:

https://github.com/expo/expo/pull/29054/files#diff-e51e0a447b1c87524c067bc171823cb544895a690991f436ea3fa1fc96351d38R280

That may be what introduced the bug.

ricklove commented 2 hours ago

Confirmed, this line in metro is what causes this issue:

https://github.com/expo/expo/blob/0d46fc187c55e6b73507f7e44f0d9e19c4893f64/packages/%40expo/metro-config/src/serializer/serializeChunks.ts#L403

ricklove commented 2 hours ago

This bug was introduced with this pr: https://github.com/expo/expo/commit/a6e59b19fb933bac5b2928f9872a46034d179bb5

ricklove commented 2 hours ago

https://github.com/expo/expo/pull/30980 @EvanBacon this PR seems to have broken sentry for bundle splitting: the filenames are saved with the new hash, however the internal imports still point to the original filenames.

This is a circular issues since updating the file would cause a cascade of needed updates through all the files following their dependencies.