Codegen on iOS is failing in monorepo projects
See original GitHub issueDescription
As mentioned in the partner sync, the current codegen scripts contain hardcoded paths which are incorrect in monorepo projects.
To demonstrate the issue, I updated my Expo monorepo example repository. You can see a failed build in this PR with the relevant xcode logging pointing to these hardcoded paths.
Note that Android does work fine in the example repo, but I don’t think we are using it. I can also see other hard-coded paths from the template.
Core issue
In React Native’s native files, we use quite some scripts to generate certain things. Paths to these scripts are often hard coded. These hardcoded paths are fine, but only within the react-native
package.
When hardcoding paths to other packages, like react-native-codegen
, you could easily break general monorepo support. Some monorepo tools allow people to mark certain packages as “do not hoist”. While this works for some cases, it’s often not the best usage of monorepos as this would duplicate installations in bigger repos and consume more disk space. With that in mind, we basically can’t assume the location of a package, we have have to ask Node to resolve it.
Issue from the example repo
The linked example repository uses a relatively simple structure listed below. We hoist as many packages as possible to speed up installation and consume minimal disk space.
Expo monorepo
├── apps
│ └── mobile
│ └── node_modules
│ └── react-native@0.70.5
└── node_modules
└── react-native-codegen@0.70.6
In this case, the path to react native codegen is incorrect, as the monorepo tool (pnpm) is installing codegen in the root node_modules folder.
Looking to npm & future
We might run into more issues in the future when the npm isolation mode RFC is accepted. It’s probably worth it to think of solutions before that.
From Expo SDK 43, we switched these hard-coded paths to node module resolution references to better accommodate monorepos and custom setups. (android example, ios example)
Using a similar but slightly different solution could even help make React Native compatible with Plug’n’Play modules. Instead of using hard-coded paths, and “expect files to be installed on disk”, we could ask Node or the package manager to resolve the file locations. If all of these requests go through a Plug’n’Play manager, it could download those files on the fly, and return the location. The first run will be slow, but IMHO it’s worth investigating.
Version
0.70.5
Output of npx react-native info
System:
OS: macOS 12.6
CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
Memory: 880.21 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.18.0 - ~/.nvm/versions/node/v16.18.0/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v16.18.0/bin/yarn
npm: 8.19.2 - ~/.nvm/versions/node/v16.18.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods: 1.11.2 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
Android SDK:
API Levels: 21, 26, 28, 29, 30, 31
Build Tools: 26.0.3, 28.0.0, 28.0.1, 28.0.2, 28.0.3, 29.0.0, 29.0.1, 29.0.2, 29.0.3, 30.0.0, 30.0.1, 30.0.2, 30.0.3, 31.0.0, 31.0.0
System Images: android-21 | Google APIs ARM EABI v7a, android-22 | Intel x86 Atom_64, android-22 | Google APIs ARM EABI v7a, android-22 | Google APIs Intel x86 Atom_64, android-23 | Intel x86 Atom_64, android-26 | Google APIs Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google Play Intel x86 Atom
Android NDK: Not Found
IDEs:
Android Studio: 2021.2 AI-212.5712.43.2112.8815526
Xcode: 14.1/14B47b - /usr/bin/xcodebuild
Languages:
Java: 18.0.2 - /usr/local/opt/openjdk/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: Not Found
react-native: 0.70.5 => 0.70.5
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Steps to reproduce
To trigger the issue:
$ git clone git@github.com:byCedric/expo-monorepo-example.git ./example
$ cd ./example
$ git checkout 0c94b0aa06e95a3ac9dcb87aff3bf3e3f767d7ac
(this is the latest onmain
without a patch)$ pnpm install
$ cd apps/mobile
$ npx expo prebuild --platform ios
$ xed ios
- Build the app, should fail
To test the fix from PR #73
$ git clone git@github.com:byCedric/expo-monorepo-example.git ./example
$ cd ./example
$ git checkout fix/codegen-monorepo-paths
(this is the latest onmain
without a patch)$ pnpm install
$ cd apps/mobile
$ npx expo prebuild --platform ios
$ xed ios
- Build the app, should succeed
Snack, code example, screenshot, or link to a repository
Issue Analytics
- State:
- Created 10 months ago
- Reactions:6
- Comments:6 (5 by maintainers)
What would be the suggested path for the codegen that works out of the box in most cases?
Yes it is 👍 or at least let’s move the discussion to
discussions-and-proposal
repo so more people can participate over there.@cortinico, that makes sense, thanks. Might be worth defaulting in the templates to non-hardcoded paths that work out of the box in most environments, though 😃
I can confirm that PR #35430 does fix the issue in my monorepo templates, including the repo I linked - made a patch to apply this change.
Is it worth to make an RFC to discuss supporting node module resolutions, isolated mode, and possibly plug and play (with
pnpapi
)?