DEV Community

Discussion on: Tutorial: How to share code between iOS, Android & Web using React Native, react-native-web and monorepo

Collapse
 
varungupta85 profile image
Varun Gupta

So, I have a mobile app in production on iOS and Android that we plan to provide over the browser also. To reuse the logic code in the web app, I am putting those in shared packages managed using the yarn workspaces. Initially, I was using react-native 0.63.3 which uses react 16.13.1 for the mobile app. When I created the web app, it was using react 17.0.1. There were a couple of invalid hook call errors which happen due to conflicting versions of react. I tried no-hoisting react and react-native specific packages but that resulted in some packages under root node modules and some under the package node_modules which becomes problematic during auto-linking. So, I ended up upgrading react-native to 0.64.0-rc.1 which uses react 17.0.1. I was able to build and run the app on both iOS and Android but when I created the release build, I got some errors mainly around not able to find the shared packages since they are symlinks and metro doesn't support symlinks. I read about some workaround by providing extraNodeModules and projectRoots in metro.config.js but I kept on getting one error or the other.

I wanted to ask if you made any special changes to create release builds for your app and what are those?

After banging my head for the last few days to convert the existing app to the mono-repo, I started out creating a brand new app in a mono-repo structure, have a dummy shared package and create release builds from it and then port my code over. I am getting the below error on iOS while creating an archive. I am able to run the app in dev mode:

error: Build input file cannot be found: '/Users/varungupta/Projects/galarm-combined/node_modules/react-native/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm' (in target 'FBReactNativeSpec' from project 'Pods')

This error doesn't appear if I create a new project and create an archive without making it into a mono-repo.

One more thing I wanted to ask is do I need to change the paths in node_modules/react-native/scripts/react_native_pods.rb and react.gradle files as they contain some references to node_modules.

Thread Thread
 
brunolemos profile image
Bruno Lemos • Edited
  1. Do not use nohoist, this causes many problems like the issue with metro you mentioned
  2. Make sure you use the exact same version of the dependencies between the projects (e.g. react "17.0.1", without "^" or "~")
  3. Make sure that all your "node_modules" are empty inside the packages. The only one with dependencies should be the node_modules in the root folder. If they are not empty, you probably have dependencies with different versions. You can use yarn resolutions to fix that.
  4. Set projectRoot in the metro config and change the entry files to packages/mobile/index as mentioned in the article
  5. RN 0.64 is still in beta and has issues. Of the of the issues is this one about FBReactNativeSpec, you need to run "pod install" again every time after you run "yarn".
  6. Yes you need to change all references of node_modules/react-native. Including on podfile and creating a react-native.config.js file

See this repository: github.com/brunolemos/react-native...

Thread Thread
 
varungupta85 profile image
Varun Gupta

Dear Bruno,

Thanks for your response. I am already doing #2 as yarn seem to update the packages without updating package.json if there are minor upgrades available. I was not aware of the yarn resolutions but that is pretty cool I do have some node_modules in my web and mobile folder which I will fix using yarn resolutions.

For setting the project root in metro.config.js, I guess I just need to set it to the dirname like projectRoot: path.resolve(dirname, '.')

For the react-native.config.js file, could you please tell me where and how it is used. I created it based on your blog instructions but I am not sure how it is used.

Also, I checked the devhub repository (great resource btw), it doesn't have a react-native.config.js file or setting a projectRoot in metro.config.js file.

Thanks again for your valuable time.