I use NX monorepo with Next.js and React Ntive. And using shared-lib.
I am getting an error from metro when trying to use something from shared-lib im my application. For example import SVG or function from shared-lib to mobile app. But in web working well.
I really don’t know why, because I kept the default Nx configuration but I have a weird metro error about fs.
Here is the error I am getting : Cannot resolve fs
BUNDLE src/main.tsx
error: Error: Cannot resolve fs
at /Users/mac/projects/nx-app/node_modules/@nx/react-native/plugins/metro-resolver.js:33:15
at Object.resolve (/Users/mac/projects/nx-app/node_modules/metro-resolver/src/resolve.js:32:12)
at ModuleResolver.resolveDependency (/Users/mac/projects/nx-app/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:73:31)
at DependencyGraph.resolveDependency (/Users/mac/projects/nx-app/node_modules/metro/src/node-haste/DependencyGraph.js:231:43)
at /Users/mac/projects/nx-app/node_modules/metro/src/lib/transformHelpers.js:156:21
at resolveDependencies (/Users/mac/projects/nx-app/node_modules/metro/src/DeltaBundler/buildSubgraph.js:42:25)
at visit (/Users/mac/projects/nx-app/node_modules/metro/src/DeltaBundler/buildSubgraph.js:83:30)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Promise.all (index 2)
at async visit (/Users/mac/projects/nx-app/node_modules/metro/src/DeltaBundler/buildSubgraph.js:92:5)
And sometimes see this message:
(NOBRIDGE) ERROR [Error: InternalError Metro has encountered an error: Cannot resolve fs: /Users/mac/projects/nx-app/node_modules/@nx/react-native/plugins/metro-resolver.js (33:15)
31 | console.log(chalk.red(`[Nx] Unable to resolve with any resolver: ${realModuleName}`));
32 | }
> 33 | throw new Error(`Cannot resolve ${chalk.bold(realModuleName)}`);
| ^
34 | };
35 | }
36 | exports.getResolveRequest = getResolveRequest;]
my metro config:
const { withNxMetro } = require('@nx/react-native');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const path = require('path');
const defaultConfig = getDefaultConfig(__dirname);
const { assetExts, sourceExts } = defaultConfig.resolver;
/**
* Metro configuration
* https://reactnative.dev/docs/metro
*
* @type {import('metro-config').MetroConfig}
*/
const customConfig = {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
resolver: {
assetExts: assetExts.filter((ext) => ext !== 'svg'),
sourceExts: [...sourceExts, 'cjs', 'mjs', 'svg'],
},
watchFolders: [path.resolve(__dirname, '../../node_modules')],
};
module.exports = withNxMetro(mergeConfig(defaultConfig, customConfig), {
// Change this to true to see debugging info.
// Useful if you have issues resolving modules
debug: false,
// all the file extensions used for imports other than 'ts', 'tsx', 'js', 'jsx', 'json'
extensions: [],
// Specify folders to watch, in addition to Nx defaults (workspace libraries and node_modules)
watchFolders: [],
});
my webpack config:
const { composePlugins, withNx } = require('@nx/webpack');
const { withReact } = require('@nx/react');
// Nx plugins for webpack.
module.exports = composePlugins(
withNx(),
withReact({
// Uncomment this line if you don't want to use SVGR
// See: https://react-svgr.com/
// svgr: false
}),
(config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
config.resolve.alias = {
...(config.resolve.alias ?? {}),
// 'react-native$': 'react-native-web',
};
config.resolve.extensions = [
'.web.tsx',
'.web.ts',
'.web.jsx',
'.web.js',
...config.resolve.extensions,
];
config.module.rules.push({
test: /.(js|jsx)$/,
include: /react-native-vector-icons/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }],
],
},
});
return config;
},
);