'Expo and metro bundler: external module cannot resolve react import
I configured metro.config.js with the extraNodeModules setting so metro will find my shared modules from outside my project (a 'monorepo' configuration).
Metro is finding my external module (see dumb-module below), but I'm getting an error when that external module tries to import react. I get no error when the imported module does not import react.
Here's the error:
Unable to resolve module @babel/runtime/helpers/interopRequireDefault from /Users/jim/.../modules/dumb-module/index.js: @babel/runtime/helpers/interopRequireDefault 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-*
> 1 | import React from 'react';
2 | import { Text } from 'react-native';
3 |
4 | const DumbModule = () => {
Because it's showing the contents of dumb-module, it's clearly able to find my external modules. But it looks like it can't resolve that module trying to import react.
I've tried, as you might expect, everything. Would love to get some ideas here.
metro.config.js
const path = require('path');
const extraNodeModules = {
'modules': path.resolve(path.join(__dirname, '../../modules'))
};
const watchFolders = [
path.resolve(path.join(__dirname, '../../modules'))
];
const nodeModulesPaths = [path.resolve(path.join(__dirname, './node_modules'))];
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: true,
inlineRequires: true,
},
}),
},
resolver: {
extraNodeModules,
nodeModulesPaths
},
watchFolders
};
dumb-module/index.js
import React from 'react';
import { Text } from 'react-native';
const DumbModule = () => {
return (
<Text>I am useless.</Text>
);
};
export default DumbModule;
expo diagnostics:
expo diagnostics
Expo CLI 4.12.0 environment info:
System:
OS: macOS 11.6
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.16.1 - ~/.nvm/versions/node/v14.16.1/bin/node
Yarn: 1.22.11 - ~/.nvm/versions/node/v14.16.1/bin/yarn
npm: 7.24.0 - ~/.nvm/versions/node/v14.16.1/bin/npm
Managers:
CocoaPods: 1.11.2 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 15.0, DriverKit 20.4, macOS 11.3, tvOS 15.0, watchOS 8.0
IDEs:
Xcode: 13.0/13A233 - /usr/bin/xcodebuild
npmPackages:
expo: ~42.0.1 => 42.0.4
react: 16.13.1 => 16.13.1
react-dom: 16.13.1 => 16.13.1
react-native: https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz => 0.63.2
react-native-web: ~0.13.12 => 0.13.18
npmGlobalPackages:
expo-cli: 4.12.0
Expo Workflow: managed
Solution 1:[1]
So, this actually works fine, and my issue was I wasn't resetting the metro cache properly.
I'll leave this post up because this metro.config.js is part of the solution to getting an expo app to work inside a monorepo and utilized shared components.
The other part is using yarn's nohoist option on the expo app folder so its dependencies are kept within its node_modules.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jim B. |
