Skip to content

Conversation

ceopaludetto
Copy link
Contributor

@ceopaludetto ceopaludetto commented Aug 23, 2025

Summary

  • Add an expo plugin that allows expo router + expo CNG (expo managed projects) to work with repack.
  • Add a new guide to Expo

Test plan

  • Added a new expo managed tester application

Todos

  • Test Webpack Integration

Copy link

changeset-bot bot commented Aug 23, 2025

🦋 Changeset detected

Latest commit: 7341e40

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@callstack/repack-plugin-expo Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Aug 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
repack-website Ready Ready Preview Comment Sep 1, 2025 3:42pm

@jbroma
Copy link
Member

jbroma commented Aug 26, 2025

Test plan

Maybe we should create an expo managed example in ./apps folder

Hey @ceopaludetto, absolutely, go for it 👍

@ceopaludetto
Copy link
Contributor Author

@jbroma added a new expo guide in the docs and also added the tester application. We can combine both expo-modules and expo guides in just one page. Maybe we can also merge both plugins in just one, its up to you!

@j0nl1
Copy link

j0nl1 commented Sep 1, 2025

I'm tracking the progress in this PR, very interested on it. I just wondering if would be possible to launch just with expo instead of react-native cli since it wouldn't require to manage pods locally or any kind of build just fetching a development build from expo cloud and run it using the repack bundler.

@ceopaludetto
Copy link
Contributor Author

I'm tracking the progress in this PR, very interested on it. I just wondering if would be possible to launch just with expo instead of react-native cli since it wouldn't require to manage pods locally or any kind of build just fetching a development build from expo cloud and run it using the repack bundler.

Hey, thanks for the interest! The main reason we switched from expo CLI to React Native CLI is that when you run something like expo run ios --mode Release expo always builds the metro bundle before the native build (you'd need a patch to avoid this). Expo CLI works fine for development though (just use expo run ios --no-bundler to skip Metro).
As for expo cloud, I haven't really played around with that feature much, so I can't say for sure how it would work with this setup. If you end up experimenting with it, would love to hear how it goes!

Copy link
Member

@jbroma jbroma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @ceopaludetto sorry for the delay with the review! I found few things we need to address but the rest looks good 👍

one more thing: when doing prebuild + run-ios I kept running into issues because I don't have cocoapods globally installed and use local ruby setup - perhaps we could fix that with Gemfile + Gemfile.lock like in other testers? (or maybe there is a nicer fix for that). Prebuild + android worked fine for me, good job with the tester 👍

"node": ">=18"
},
"peerDependencies": {
"@callstack/repack": "workspace:*",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets define those explicitly as a starting point for this plugin 👍

from my experience its best to define versions with open upper boundary, like >=53.0.0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran into some issues here when building Android, I think we are missing from fields like in the other tester app

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use registerRootComponent from expo here?

Comment on lines +20 to +26
// Alias both react and react-native to ensure that we don't end up with multiple versions
// of these libraries in the bundle.
//
// This is needed in these monorepo setups where there are multiple copies of react
// and react-native in the node_modules.
react: require.resolve('react'),
'react-native': require.resolve('react-native'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this an issue here with pnpm? Sounds like this should happen in setups with hoisting 🤔

},
module: {
rules: [
...Repack.getJsTransformRules(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets use babel-swc-loader here instead (take a look at config for other tester)

Comment on lines +80 to +91
new compiler.webpack.DefinePlugin({
'process.env.EXPO_PROJECT_ROOT': JSON.stringify(root),
// If Expo Router is enabled, pass additional environment variables
...(router
? {
'process.env.EXPO_BASE_URL': JSON.stringify(router.baseUrl),
'process.env.EXPO_ROUTER_ABS_APP_ROOT': JSON.stringify(router.root),
'process.env.EXPO_ROUTER_APP_ROOT': JSON.stringify(router.root),
'process.env.EXPO_ROUTER_IMPORT_MODE': JSON.stringify('sync'),
}
: {}),
}).apply(compiler);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its cleaner to split it into two DefinePlugin

Comment on lines +94 to +105
if (
compiler.options.mode === 'development' &&
!!compiler.options.devServer
) {
compiler.options.devServer.proxy ??= [];

// Redirect `/.expo/.virtual-metro-entry` to `/index` to match metro behavior in Expo managed projects
compiler.options.devServer.proxy.push({
context: ['/.expo/.virtual-metro-entry'],
pathRewrite: { '^/.expo/.virtual-metro-entry': '/index' },
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has no effect because devServer options are set before plugin apply runs - there is no way to inject devServer options through the plugin.

An alternative to that would be to wrap the entire user configuration and inject it there, kinda like Rozenite does it here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants