App is crashing in production because of monorepo yarn workspace

My application is crashing in production if I build my application using eas-cli, reason for this crashes is I am using mono repo yarn work-space, meaning my modules/packages are in separate work-space directories to manage the code for large teams.

environments:-

eas-cli/3.13.2 darwin-x64 node-v16.18.1
node version : 16.18.1
"react-native": "0.70.8",
"expo-yarn-workspaces": "2.1.0",
"expo": "47.0.0",
"@react-native-community/netinfo": "^9.3.10",

Build command:-
eas build --platform android --profile preview --local

I have project setup examples below

-- packages
     -- hooks
      -- package.json
     -- redux
       -- package.json
     -- utils
       -- package.json
     -- my-app
      -- package.json
      -- app.json
      -- eas.json
-- package.json
-- yarn.lock

as you can see I have one root package.json and an individual package.json file for all the packages.

but my app is inside the package directory where the eas.json file and app.json files are there, when I trigger the build from my-app directory it starts the building process and generates a .apk file but when I open the app it immediately got crashed with the below error

FATAL EXCEPTION: mqt_native_modu Process: com.incapsulate.dev311, PID: 13671
com.facebook.react.common.JavascriptException: Error: @react-native-community/netinfo: NativeModule.RNCNetInfo is null. To fix this issue try these steps:
                                                                                                    
 • Run `react-native link @react-native-community/netinfo` in the project root.
 • Rebuild and re-run the app.
 • If you are using CocoaPods on iOS, run `pod install` in the `ios` directory and then rebuild and re-run the app. You may also need to re-open Xcode to get the new pods.
• Check that the library was linked correctly when you used the link command by running through the manual installation instructions in the README.
* If you are getting this error while unit testing you need to mock the native module. Follow the guide in the README.

I am getting this error in the production app because the @react-native-community/netinfo dependency is installed in the hooks directory, not inside the my-app directory. when I move these dependencies from hooks to my-app directory this issue gets fixed, but I have to duplicate the dependencies in both the package.json directory I don’t want to do this because it would become unmanageable after a certain point of time.

please help me with this sharing metro config file below

// Learn more https://docs.expo.dev/guides/monorepos
const {getDefaultConfig} = require('expo/metro-config');
const path = require('path');
const fs = require('fs');

// Find the project and workspace directories
const projectRoot = __dirname;
// This can be replaced with `find-yarn-workspace-root`
const workspaceRoot = path.resolve(projectRoot, '../..');
// packages are in the workspace root
const packagesRoot = path.resolve(workspaceRoot, 'packages');

const config = getDefaultConfig(projectRoot);

// added terser minifier
config.transformer.minifierPath = 'metro-minify-terser';

// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot];

// helper function
const getDirs = (root) => {
  return (
    fs
      .readdirSync(root, {withFileTypes: true})
      .filter((dir) => dir.isDirectory())
      // filter this out as we only want core once
      .filter((dir) => dir.name !== 'core')
      .map((dir) => dir.name)
  );
};

// find all the packages in the monorepo
const packages = getDirs(packagesRoot);

// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, 'node_modules'),
  path.resolve(workspaceRoot, 'node_modules'),
  ...packages.map((packageName) =>
    path.resolve(packagesRoot, packageName, 'node_modules'),
  ),
];

// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
config.resolver.disableHierarchicalLookup = true;

config.resolver.extraNodeModules = {
  stream: require.resolve('readable-stream'),
};

config.server.rewriteRequestUrl = (url) => {
  if (!url.endsWith('.bundle')) {
    return url;
  }
  // https://github.com/facebook/react-native/issues/36794
  // JavaScriptCore strips query strings, so try to re-add them with a best guess.
  return (
    url + '?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true'
  );
};

module.exports = config;

@mchauhan AFAIK you should remove expo-yarn-workspaces Working with monorepos - Expo Documentation

1 Like

Thank you for replying I removed expo-yarn-workspace. but getting new errors while eas build in cloud
expo 47, react-native 0.70.8

In xcode logs, I get this

❌  error: Could not determine react-native-codegen location in /Users/expo/workingdir/build/packages/core/ios/Pods/../../node_modules/react-native/React/FBReactNativeSpec/../../packages/react-native-codegen or /Users/expo/workingdir/build/packages/core/ios/Pods/../../node_modules/react-native/React/FBReactNativeSpec/../../../react-native-codegen. Try running 'yarn install' or 'npm install' in your project root.

here are my findings
Codegen on iOS is failing in monorepo projects
Fix hardcoded path to codegen cli for monorepos
Could not determine react-native-codegen location" after upgrading to 0.65

I tried to install react-native-codegen, but it didn’t worked out
even tried nohoist like below in root package.json but didn’t work out


  "workspaces": [
    "packages/*"
  ],
  "nohoist": [
    "**/react-native",
    "**/react-native/**",
    "**/react-native-codegen"
  ],