nx-react-native
nx-react-native copied to clipboard
The app fails to run on iOS out of the box
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?
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.
@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.
@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
This is the same for me. Any workarounds like downgrading? It fails for images that are included in node_modules as well.
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.
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'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
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 😅