Reputation: 1
I am running into trouble with a React Native app.
Right now I have this file structure:
Outer Folder Packages ----ReactNativeApp1 --------All standard files for React Native App ----shared (Folder for shared components) --------Button.tsx sample component.
I ran npx react-native start to initialize this folder, then I created the Button.tsx file (source below):
import React from 'react'; import { TouchableOpacity, Text } from 'react-native';
const Button = ({ text, onPress }) => { return ( {text} ); };
export default Button;
My goal is to have one root folder, 2+ inner folders that represent React Native Apps, and a Shared folder that will hold code common to all the apps.
I have an App.tsx file inside ReactNativeApp1/App1
that properly registers the component, and imports the button:
import React from 'react';
import { View } from 'react-native';
import Button from '../shared/Button';
const App1: React.FC = () => {
return (
<View>
<Button text="Press Me" onPress={() => console.log('Button pressed!')} />
</View>
);
};
export default App1;
However, whenever I try to run the app, I get this error:
error: Error: Unable to resolve module ../shared/Button from C:\Users\username\VSCode Projects\SampleReactNativeSharedProject\packages\ReactNativeApp1\App.tsx:
None of these files exist:
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import Button from '../shared/Button';
I have tried many things:
However, it seems like I am stuck on this same issue either way.
I want to have all my projects (in subfolders) in one root folder, and a shared components subfolder too.
I would appreciate any help on this issue, and am happy to share more details.
Upvotes: 0
Views: 51
Reputation: 370
This is a common issue when working with monorepos. first, create a package.json
in the root ofthe project and configure it to use yarn
workspaces:
package.json
{
"private": true,
"workspaces": [
"ReactNativeApp1",
"shared"
]
}
make sure both reactnativeapp1
and shared
have their own package.json
now install dependencies:
yarn
next, configure the metro bundler for the structure of the monorepo
metro.config.js // this should be at the root of project
const path = require('path');
module.exports = {
watchFolders: [
path.resolve(__dirname, 'shared')
],
resolver: {
extraNodeModules: {
shared: path.resolve(__dirname, 'shared')
}
}
};
after this, inside the ReactNativeApp1
, create a metro config file to extend the root config
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts }
} = await getDefaultConfig();
return {
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg', 'ts', 'tsx']
},
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer')
}
};
})();
now import in App.tsx
import React from 'react';
import { View } from 'react-native';
import Button from 'shared/Button'; // alias shared as in metro.config.js
const App1: React.FC = () => {
return (
<View>
<Button text="Press Me" onPress={() => console.log('Button pressed!')} />
</View>
);
};
export default App1;
Now start the bundler by resetting the cache
npx react-native start --reset-cache or yarn start
Alternatively you can use Nx
workspace which is a commonly used tool for maintaining a monorepo workspace. Read more here : https://nx.dev/recipes/react/react-native
Upvotes: 0