Home > Back-end >  React-native monorepo iOS release build crash
React-native monorepo iOS release build crash

Time:06-06

I have a monorepo with this architecture :

├── node_modules
├── packages
    ├── app            # React native project
        ├── android    
        └── ios        
    ├── common         # TS package
    └── web            # Next JS project

In common package I have some shared services such as API calls for web front and mobile app. During development phases, build and run process were working fine for both app and web.

Now I would like to publish my app to the app store but I'm not able to compile a working release ios app. I have this crash logs when launching the app :

022-06-02 15:33:14.173898 0200 XXXX[33899:2579321] *** Terminating app due to uncaught exception 'RCTFatalException: Unhandled JS Exception: Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect. 
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.', reason: 'Unhandled JS Exception: Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the applica..., stack:
<unknown>@13:289
value@760:3143
<unknown>@760:747
value@760:2538
value@760:719
value@(null):(null)
'
*** First throw call stack:
(0x185361288 0x19e05b744 0x1003c0538 0x10043fd8c 0x10044066c 0x1852e9b24 0x185307610 0x18533e5fc 0x1003d7bd4 0x1003f5e98 0x1003f5ac8 0x184fc6e6c 0x184fc8a30 0x184fd0124 0x184fd0c80 0x184fdb500 0x1f6c240bc 0x1f6c23e5c)
libc  abi: terminating with uncaught exception of type NSException

I follow this article to build monorepo : https://medium.com/@ratebseirawan/react-native-0-63-monorepo-walkthrough-36ea27d95e26.

I have in my xcode project, Build Phases > Bundle React Native code and images :

set -e
export NODE_BINARY=node
export EXTRA_PACKAGER_ARGS="--entry-file packages/app/index.js --reset-cache"
../../../node_modules/react-native/scripts/react-native-xcode.sh "packages/app/index.js"

and in Start packager :

export RCT_METRO_PORT="${RCT_METRO_PORT:=8081}"
echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${SRCROOT}/../../../node_modules/react-native/scripts/.packager.env"
if [ -z "${RCT_NO_LAUNCH_PACKAGER xxx}" ] ; then
  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then
    if ! curl -s "http://localhost:${RCT_METRO_PORT}/status" | grep -q "packager-status:running" ; then
      echo "Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly"
      exit 2
    fi
  else
    open "$SRCROOT/../../../node_modules/react-native/scripts/launchPackager.command" || echo "Can't start packager automatically"
  fi
fi

In my AppDelegate.m

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"packages/app/index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

metro.config.js :

const {getDefaultConfig} = require("metro-config");
const path = require('path');

module.exports = (async () => {
    const {
        resolver: {sourceExts, assetExts}
    } = await getDefaultConfig();
    return {
        projectRoot: path.resolve(__dirname, '../../'),
        transformer: {
            babelTransformerPath: require.resolve("react-native-svg-transformer"),
            getTransformOptions: async () => ({
                transform: {
                    experimentalImportSupport: false,
                    inlineRequires: true,
                },
            }),
        },
        resolver: {
            assetExts: assetExts.filter(ext => ext !== "svg"),
            sourceExts: [...sourceExts, "svg"]
        }
    };
})();

Env : react-native 0.67.4

output of npx react-native info :

System:
    OS: macOS 12.3.1
    CPU: (8) arm64 Apple M1
    Memory: 555.95 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 8.5.0 - /usr/local/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.11.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.1 AI-211.7628.21.2111.8092744
    Xcode: 13.4/13F17a - /usr/bin/xcodebuild
  Languages:
    Java: 17.0.2 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: Not Found
    react-native: Not Found
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

I think that the main.js bundle generated is at the wrong place but I don't find the solution, have you any idea ?

Thanks !

CodePudding user response:

in your packages/app/metro.config.js file did you do the changes that are shown in the article? also and could you share that file.

(The article that you mentioned was specifically supposed to work with ReactNative 0.63, at that time there was little to no tooling to work with React Native on a Monorepo but now we have great tooling and support for it that will solve these annoying issues out of the box, I personally have been using https://nx.dev/guides/react-native)

for your issue tho I can try to help but there might be many things that could cause the error, one might be behind the M1 chip (doesn't have to be tho)

another info that might help, I read the patch notes of RN version 0.65 or 0.66 that they fixed an issue with monorepos where metro doesn't work nicely with symlinks so that might help.

but if I where you, I would clone the NX monorepo template and see their setup and compare with what you have (Files I would look at are metro.config. info.plist. babel.config)

CodePudding user response:

Atm, I found a temporarily workaround :

  • I added in packages/app/package.json :
    "build-prod:ios": "react-native bundle --platform ios --dev false --entry-file ./packages/app/index.js --bundle-output ios/MyAppName/main.jsbundle --assets-dest ios",

  • in Xcode > Build Phases > Copy Bundle Ressources : add main.jsbundle
  • Comment all lines in "Bundle React Native code and images" and "Start packager"

For each new release, I now need to run yarn build-prod:ios before use xcode to build.

  • Related