nx-react-native icon indicating copy to clipboard operation
nx-react-native copied to clipboard

The app fails to run on iOS out of the box

Open gmenih opened this issue 4 years ago • 8 comments

I just added a react-native app to my NX environment, and tried to run it... I immediately get an error, that logo.png can't be found. I tried to follow the steps that are printed next to the error, but no luck:

error: Error: Unable to resolve module ./logo.png from /Users/gregormenih/Projects/challenger/apps/test/src/app/App.tsx: ./logo.png could not be found within the project.

If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*
  22 |                 <ScrollView contentInsetAdjustmentBehavior="automatic" style={styles.scrollView}>
  23 |                     <View style={styles.header}>
> 24 |                         <Image style={styles.logo} source={require('./logo.png')} />
     |                                                                     ^
  25 |                         <Text style={styles.heading} testID="heading">
  26 |                             Welcome to React Native
  27 |                         </Text>

Any idea why this file can't be found?

gmenih avatar Feb 05 '21 17:02 gmenih

I am getting the same problem both in a newly generated RN app and one I have migrated to NX Workspace. It looks like if the projectRoot of the metro config is changed to the workspace root, metro will stop resolving non .js files. All the images, json, etc... will come back unresolved. I have managed to "fix" it by patching the @nrwl/react-native/plugins/metro-resolver.js to resolve these files:

// new function to generate absolute path from the relative image paths
function getAbsolutePath(relativePath, originModulePath) {
  var absolutePath = originModulePath.substring(0, originModulePath.lastIndexOf("/"));
  var absolutePathWithFile = path.join(absolutePath, relativePath);
  return absolutePathWithFile;
}
...
function resolveRequest(_context, realModuleName, platform, moduleName) {
  ...
  if (match) {
    return {
      type: 'sourceFile',
      filePath: match,
    };
  }
  else {
     var resolvedPath = getAbsolutePath(realModuleName, _context.originModulePath);
      return {
        type: 'sourceFile',
        filePath: resolvedPath,
      };
  }
  ...
}

This is obviously a pretty hacky solution as it does not really check the existence of that file. Also, it would be great to find the root cause of this issue rather than working it around with this hack but it might help you in the short term.

I will play around with this problem a bit more when I have time and update the thread / create a PR if needed.

gaborkajtar avatar Feb 08 '21 01:02 gaborkajtar

@jaysoo I'm extremely glad that's been elevated to 'bug' status! Just letting you know, even with the above patch to metro-resolver.js I keep getting the original resolve error. And that's on a newly created nx workspace and an off-the-cli react-native app.

alfonsobravi avatar Feb 11 '21 21:02 alfonsobravi

@jaysoo I'm extremely glad that's been elevated to 'bug' status! Just letting you know, even with the above patch to metro-resolver.js I keep getting the original resolve error. And that's on a newly created nx workspace and an off-the-cli react-native app.

Did you const path = require("path"); This workaround did it for me

Bushuo avatar Feb 11 '21 23:02 Bushuo

This is the same for me. Any workarounds like downgrading? It fails for images that are included in node_modules as well.

tenhaus avatar Feb 11 '21 23:02 tenhaus

Found another fix! (for yarn) Add a resolutions field to your package.json

...
  "resolutions": {
    "@nrwl/**/metro-resolver": "0.59.0"
  },
...

@jaysoo I guess a version bump of metro-resolver to 0.59.0 would fix this issue. v0.59 handles asset files differently.

Bushuo avatar Feb 12 '21 11:02 Bushuo

I've had half-success with @Bushuo fix. Assets resolve just fine now, but as soon as I try to resolve imports from the libs folder the app just goes dead blank and the bundler console won't give any meaningful feedback. If I run the debugger I then get something along those lines:

[Tue Feb 16 2021 10:36:40.723]  BUNDLE  src/main.tsx ░░░░░░░░░░░░░░░░ 0.0% (0/1)Error: EISDIR: illegal operation on a directory, read
    at Object.readSync (node:fs:606:3)
    at tryReadSync (node:fs:380:20)
    at Object.readFileSync (node:fs:417:19)
    at UnableToResolveError.buildCodeFrameMessage ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:304:17)
    at new UnableToResolveError ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:290:35)
    at ModuleResolver.resolveDependency ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:191:15)
    at DependencyGraph.resolveDependency {myPath}/node_modules/metro/src/node-haste/DependencyGraph.js:353:43)
    at {myPath}/node_modules/metro/src/lib/transformHelpers.js:271:42
    at Server.<anonymous> ({myPath}/node_modules/metro/src/Server.js:842:41)
    at Generator.next (<anonymous>)

@jaysoo any idea how to overcome this? Sounds like the monorepo is fighting against its own nature!

alfonsobravi avatar Feb 15 '21 21:02 alfonsobravi

I've had half-success with @Bushuo fix. Assets resolve just fine now, but as soon as I try to resolve imports from the libs folder the app just goes dead blank and the bundler console won't give any meaningful feedback. If I run the debugger I then get something along those lines:

[Tue Feb 16 2021 10:36:40.723]  BUNDLE  src/main.tsx ░░░░░░░░░░░░░░░░ 0.0% (0/1)Error: EISDIR: illegal operation on a directory, read
    at Object.readSync (node:fs:606:3)
    at tryReadSync (node:fs:380:20)
    at Object.readFileSync (node:fs:417:19)
    at UnableToResolveError.buildCodeFrameMessage ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:304:17)
    at new UnableToResolveError ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:290:35)
    at ModuleResolver.resolveDependency ({myPath}/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:191:15)
    at DependencyGraph.resolveDependency {myPath}/node_modules/metro/src/node-haste/DependencyGraph.js:353:43)
    at {myPath}/node_modules/metro/src/lib/transformHelpers.js:271:42
    at Server.<anonymous> ({myPath}/node_modules/metro/src/Server.js:842:41)
    at Generator.next (<anonymous>)

@jaysoo any idea how to overcome this? Sounds like the monorepo is fighting against its own nature!

I'm getting the same issue when I try to import something into the react-native project from the libs. I've spent some time on that and find out that it works only in case you run the app via the nx run app-mobile:run-ios in case I'm running it natively using the x-code it stops working! Seems like app-mobile:run-ios defines some extra env around

stingrigs avatar Apr 19 '21 14:04 stingrigs

When you migrate existing RN projects, don't forget to change the main module name which is specified in native codes. (getJSMainModuleName() in MainApplication.java on Android, and jsBundleURLForBundleRoot in AppDelegate.m on iOS.) This was my case 😅

mokoshi avatar Nov 25 '21 13:11 mokoshi