I've been having this problem for a really long time now. I'm really hoping someone has overcome this issue.
We already have an app that is being developed, but we have decided to build micro-frontends to strip out some features into separate modules. The existing app does not have this problem.
I've created a react native module with pure react-native, with an example app within it to test it which uses expo. The code is mostly copied over from the existing app mentioned above, with some changes here and there. The module uses react-native-paper.
The example app runs fine on both ios and android, until I add a component from the module that makes use of an icon.
For example, from my module, this code exists:
<Modal visible={visible} onDismiss={() => setVisible(false)}>
<Surface style={styles.containerStyle}>
<Appbar.Header>
<Appbar.Action
icon={{
uri: 'https://avatars0.githubusercontent.com/u/17571969?v=3&s=400',
}}
testID={`${props.textInputProps?.testID}Close`}
onPress={() => setVisible(false)}
touchSoundDisabled={false}
/>
I've also tried:
<Modal visible={visible} onDismiss={() => setVisible(false)}>
<Surface style={styles.containerStyle}>
<Appbar.Header>
<Appbar.Action
icon={'close'}
testID={`${props.textInputProps?.testID}Close`}
onPress={() => setVisible(false)}
touchSoundDisabled={false}
/>
and:
<Modal visible={visible} onDismiss={() => setVisible(false)}>
<Surface style={styles.containerStyle}>
<Appbar.Header>
<Appbar.Action
icon={() => <MaterialCommunityIcons name="close" />}
(This one gives a different error): Unable to resolve module @expo/vector-icons/MaterialCommunityIcons from /../../../../../src/models/FormModel.tsx: @expo/vector-icons/MaterialCommunityIcons could not be found within the project or in these directories: ../node_modlues or ../../../../node_modules
This is from my example code, where the module code with the icon is being called, with comments specifying the outcome:
<FormBuilder
control={formControl.control}
setFocus={formControl.setFocus}
formConfigArray={[
formModel.AddressLine1,
formModel.AddressLine2,
formModel.City,
formModel.Country, //component with icon that gives error
]}
/>
<Button icon="car">Press me</Button> {/* works perfectly */}
<IconButton icon="check" /> {/* works perfectly */}
Once I add an icon from react-native-paper, from any component, I start getting this error:
I get the same error on Android.
I've tried loading the fonts within the component, but I just cannot seem to over come this issue.
To note, if I add an icon from my example folder directly, I do not get any errors and the icon renders
This is the error I get in the terminal:
Error: Requiring unknown module "undefined". If you are sure the module exists, try restarting Metro. You may also want to run `yarn` or `npm install`.
Error: Requiring unknown module "undefined". If you are sure the module exists, try restarting Metro. You may also want to run `yarn` or `npm install`.
TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[6], "react/jsx-runtime").jsx')
This error is located at:
in Icon
in ThemedComponent (created by withTheme(Icon))
in withTheme(Icon) (created by IconButton)
in RCTView (created by View)
in View (created by IconButton)
in RCTView (created by View)
in View (created by TouchableHighlight)
in TouchableHighlight
in Unknown (created by TouchableRipple)
in TouchableRipple
in ThemedComponent (created by withTheme(TouchableRipple))
in withTheme(TouchableRipple) (created by IconButton)
in IconButton
in ThemedComponent (created by withTheme(IconButton))
in withTheme(IconButton) (created by TextInput.Icon)
in RCTView (created by View)
in View (created by TextInput.Icon)
in TextInput.Icon (created by Logic)
in IconAdornment (created by TextInputAdornment)
in TextInputAdornment (created by TextInputOutlined)
in RCTView (created by View)
in View (created by TextInputOutlined)
in RCTView (created by View)
in View (created by TextInputOutlined)
in TextInputOutlined (created by TextInput)
in TextInput
in ThemedComponent (created by withTheme(TextInput))
in withTheme(TextInput) (created by InputAutocomplete)
in RCTView (created by View)
in View (created by InputAutocomplete)
in RCTView (created by View)
in View (created by TouchableHighlight)
in TouchableHighlight
in Unknown (created by TouchableRipple)
in TouchableRipple
in ThemedComponent (created by withTheme(TouchableRipple))
in withTheme(TouchableRipple) (created by InputAutocomplete)
in InputAutocomplete (created by Logic)
in Logic (created by FormBuilder)
in FormBuilder (created by App)
in RCTScrollContentView (created by ScrollView)
in RCTScrollView (created by ScrollView)
in ScrollView (created by ScrollView)
in ScrollView (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by ExpoRoot)
in ExpoRoot
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[6], "react/jsx-runtime").jsx')
This error is located at:
in Icon
in ThemedComponent (created by withTheme(Icon))
in withTheme(Icon) (created by IconButton)
in RCTView (created by View)
in View (created by IconButton)
in RCTView (created by View)
in View (created by TouchableHighlight)
in TouchableHighlight
in Unknown (created by TouchableRipple)
in TouchableRipple
in ThemedComponent (created by withTheme(TouchableRipple))
in withTheme(TouchableRipple) (created by IconButton)
in IconButton
in ThemedComponent (created by withTheme(IconButton))
in withTheme(IconButton) (created by TextInput.Icon)
in RCTView (created by View)
in View (created by TextInput.Icon)
in TextInput.Icon (created by Logic)
in IconAdornment (created by TextInputAdornment)
in TextInputAdornment (created by TextInputOutlined)
in RCTView (created by View)
in View (created by TextInputOutlined)
in RCTView (created by View)
in View (created by TextInputOutlined)
in TextInputOutlined (created by TextInput)
in TextInput
in ThemedComponent (created by withTheme(TextInput))
in withTheme(TextInput) (created by InputAutocomplete)
in RCTView (created by View)
in View (created by InputAutocomplete)
in RCTView (created by View)
in View (created by TouchableHighlight)
in TouchableHighlight
in Unknown (created by TouchableRipple)
in TouchableRipple
in ThemedComponent (created by withTheme(TouchableRipple))
in withTheme(TouchableRipple) (created by InputAutocomplete)
in InputAutocomplete (created by Logic)
in Logic (created by FormBuilder)
in FormBuilder (created by App)
in RCTScrollContentView (created by ScrollView)
in RCTScrollView (created by ScrollView)
in ScrollView (created by ScrollView)
in ScrollView (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by ExpoRoot)
in ExpoRoot
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
This is my package.json:
{
"main": "index.js",
"scripts": {
"start": "expo start --dev-client",
"android": "expo start --android",
"ios": "expo run:ios",
"web": "expo start --web",
"test": "jest",
"e2e:test": "detox test -c android.emu.release --debug-synchronization 3000 --take-screenshots failing",
"e2e:build": "RN_SRC_EXT=e2e.ts detox build -c android.emu.release",
"e2e:ci": "npm run e2e:build && npm run e2e:test",
"e2e:test-ios": "detox test -c ios.emu.release --debug-synchronization 3000 --take-screenshots failing",
"e2e:test-ios-showHierarchy": "detox test -c ios.emu.release --debug-synchronization 3000 --take-screenshots failing --capture-view-hierarchy enabled",
"e2e:build-ios": "RN_SRC_EXT=e2e.ts detox build -c ios.emu.release",
"e2e:ci-ios": "npm run e2e:build-ios && npm run e2e:test-ios"
},
"dependencies": {
"expo": "~44.0.2",
"expo-app-loading": "~1.3.0",
"expo-splash-screen": "~0.14.1",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@babel/preset-typescript": "^7.16.5",
"@expo/vector-icons": "^12.0.5",
"@types/jest": "^27.0.3",
"@types/react": "^17.0.38",
"@types/react-native": "^0.66.10",
"@types/react-test-renderer": "^17.0.1",
"babel-jest": "^27.4.5",
"babel-plugin-module-resolver": "^4.1.0",
"detox": "^19.3.1",
"jest": "^27.4.5",
"react-native-vector-icons": "^9.0.0",
"typescript": "^4.5.4"
},
"private": true
}
my app.json:
{
"expo": {
"name": "example",
"slug": "example",
"version": "1.0.0",
"icon": "./appIcon.png",
"assetBundlePatterns": [
"**/*"
]
},
"name": "example"
}
my babel.config.ts:
const path = require("path");
const pak = require("../package.json");
module.exports = function (api) {
api.cache(true);
return {
presets: [
"babel-preset-expo",
["@babel/preset-env", { targets: { node: "current" } }],
"@babel/preset-typescript",
],
plugins: [
[
"module-resolver",
{
extensions: [".tsx", ".ts", ".js", ".json"],
alias: {
[pak.name]: path.join(__dirname, "..", pak.source),
}
}
]
]
};
};
my metro.config.js:
const path = require("path");
const blacklist = require("metro-config/src/defaults/exclusionList");
const escape = require("escape-string-regexp");
const pak = require("../package.json");
const root = path.resolve(__dirname, "..");
const modules = Object.keys({
...pak.peerDependencies,
});
module.exports = {
projectRoot: __dirname,
watchFolders: [root],
// We need to make sure that only one version is loaded for peerDependencies
// So we blacklist them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: blacklist(
modules.map(
(m) =>
new RegExp(`^${escape(path.join(root, "node_modules", m))}\\/.*$`)
)
),
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, "node_modules", name);
return acc;
}, {}),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
};
Please help!!