fix(expo): Resolve config-plugins through the expo package - #6581
Conversation
withSentryAndroidGradlePlugin was the only plugin file requiring the bare
@expo/config-plugins, which is not declared as a dependency, peer dependency
or optional dependency of @sentry/react-native. It resolved only when another
package happened to hoist it to the project root — true on Expo SDK 57 via
expo/expo-sharing/expo-splash-screen, false on SDK 56 — so expo config,
expo-doctor and expo prebuild crashed before any native compilation.
withSentry.js requires the module eagerly, so the failure was not gated on
experimental_android.enableAndroidGradlePlugin being enabled.
expo/config-plugins is a plain re-export (module.exports =
require('@expo/config-plugins')), so this is resolution-only, with no
behavioural change. The test now mocks the same specifier the source imports,
so a regression back to the bare package fails instead of resolving through
the re-export.
Fixes #6564
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
If a user enables AGP
Our docs instruct React Native users to set |
@alwx might be worth fixing this before shipping a new release, it's unrelated to this PR so it might have slipped into main.. |
📲 Install BuildsAndroid
|
iOS (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5fe1c6c+dirty | 1220.79 ms | 1217.63 ms | -3.16 ms |
| 0a147b2+dirty | 3838.15 ms | 1221.94 ms | -2616.21 ms |
| 41d6254+dirty | 3845.71 ms | 1224.51 ms | -2621.20 ms |
| a636fa4+dirty | 3852.48 ms | 1236.10 ms | -2616.38 ms |
| 1a2e7e0+dirty | 3842.49 ms | 1220.04 ms | -2622.45 ms |
| 3d377b5+dirty | 1218.48 ms | 1219.51 ms | 1.03 ms |
| 4bb93c7+dirty | 3845.98 ms | 1218.02 ms | -2627.96 ms |
| bbb8d67+dirty | 3838.98 ms | 1217.84 ms | -2621.14 ms |
| ab203f9+dirty | 3848.07 ms | 1219.71 ms | -2628.35 ms |
| 7436d0f+dirty | 3851.58 ms | 1232.21 ms | -2619.38 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5fe1c6c+dirty | 3.38 MiB | 4.77 MiB | 1.39 MiB |
| 0a147b2+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 41d6254+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
| a636fa4+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| 1a2e7e0+dirty | 4.98 MiB | 6.46 MiB | 1.49 MiB |
| 3d377b5+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 4bb93c7+dirty | 5.08 MiB | 6.68 MiB | 1.60 MiB |
| bbb8d67+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| ab203f9+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 7436d0f+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
iOS (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 7a89652+dirty | 3827.11 ms | 1211.49 ms | -2615.62 ms |
| 0a147b2+dirty | 3845.11 ms | 1230.81 ms | -2614.30 ms |
| 5b7e8a7+dirty | 3855.46 ms | 1234.47 ms | -2620.99 ms |
| 5fe1c6c+dirty | 1201.36 ms | 1209.15 ms | 7.78 ms |
| 580fb5c+dirty | 3835.45 ms | 1218.61 ms | -2616.84 ms |
| 94af3bd+dirty | 3847.84 ms | 1230.33 ms | -2617.51 ms |
| f3215d3+dirty | 3846.08 ms | 1231.85 ms | -2614.23 ms |
| a636fa4+dirty | 3846.16 ms | 1210.10 ms | -2636.05 ms |
| 5a21b51+dirty | 3837.87 ms | 1223.47 ms | -2614.40 ms |
| 4bb93c7+dirty | 3869.22 ms | 1230.76 ms | -2638.47 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 7a89652+dirty | 5.15 MiB | 6.70 MiB | 1.55 MiB |
| 0a147b2+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 5b7e8a7+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
| 5fe1c6c+dirty | 3.38 MiB | 4.77 MiB | 1.39 MiB |
| 580fb5c+dirty | 4.98 MiB | 6.46 MiB | 1.48 MiB |
| 94af3bd+dirty | 5.15 MiB | 6.69 MiB | 1.53 MiB |
| f3215d3+dirty | 5.15 MiB | 6.67 MiB | 1.52 MiB |
| a636fa4+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| 5a21b51+dirty | 5.15 MiB | 6.67 MiB | 1.51 MiB |
| 4bb93c7+dirty | 5.08 MiB | 6.68 MiB | 1.60 MiB |
📢 Type of change
📜 Description
withSentryAndroidGradlePluginwas the only one of the four Expo config plugin files importing the bare@expo/config-plugins; the other three use theexpo/config-pluginssub-export. It now uses the sub-export too.expo/config-plugins.jsis a plain re-export (module.exports = require('@expo/config-plugins')), so this is a module-resolution fix only, with no behavioural change.The test now mocks the same specifier the source imports. Previously it mocked
@expo/config-plugins, which passes under either import because of the re-export chain, so it could not catch a regression.💡 Motivation and Context
Fixes #6564.
@expo/config-pluginsis not declared in@sentry/react-native'spackage.jsonas a dependency, peer dependency or optional dependency, so the bare specifier resolved only when some other package happened to hoist it to the project root — true on Expo SDK 57 (viaexpo,expo-sharing,expo-splash-screen), false on SDK 56. Where it was not hoisted,expo config,expo-doctorandexpo prebuildfailed withCannot find module '@expo/config-plugins', so EAS builds died before any native compilation.withSentry.tsrequires the module eagerly at load time, so the failure was not gated onexperimental_android.enableAndroidGradlePluginbeing enabled.💚 How did you test it?
yarn jest test/expo-plugin— 67 tests pass.tsc -p plugin/tsconfig.jsonclean, and the emittedplugin/build/*.jsnow contains four identicalrequire("expo/config-plugins")calls instead of three plus one barerequire("@expo/config-plugins").expo/config-plugins.js.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
All four plugin files import
ExpoConfigfrom@expo/config-types, which is also undeclared. Harmless at runtime (type-only, erased on compile), but the reference survives into the generated.d.ts. Not addressed here.test/expo-plugin/modifyMainApplication.test.tsandmodifyAppDelegate.test.tsstill mock@expo/config-pluginswhile their sources importexpo/config-plugins. Works through the re-export, same inconsistency, left alone.