How to Share Code Between React Web and React Native Apps
Introduction
When we build a web app and mobile app using React and React Native (RN), there can be a lot of common functionality between mobile and web. For example, GraphQL queries, state management using Redux, and utility functions.
When we want to change in this functionality, we have to then do it in both our apps. By default, React and React Native don’t allow you to import code from outside the root directory.
In order to do this, we have to configure a few things:
- In the web app, we can import code from outside the root directory by performing a few changes in our Webpack files.
- In the mobile app, we have to modify the metro bundler config.
Before moving ahead with this tutorial, you’ll need to install the following on your development machine:
System Requirements
Node ≥ 8.10 and npm ≥ 5.6
Android Studio
Xcode(for mac)
For more details on how to set this up, see: https://reactnative.dev/docs/environment-setup
Now let’s jump to an example implementation.
Directory Structure
1. Create a new project directory
mkdir my-app
cd my-app
2. Create a new react web app inside the my-app directory
npx create-react-app webApp
3. Create a new react native app inside the my-app directory
npx react-native init mobileApp
4. Create a new directory for common code inside the my-app directory
mkdir common
cd common
npm init
The directory structure should now look like this.
Run web app
cd webApp
npm start
Run mobile app
cd mobileApp
yarn run ios
When you run the mobile app, Metro bundler looks for JS files only in the mobileApp directory. We also want to load JS files from outside the mobileApp directory i.e from the common directory
Now create a new JS file named sum.js in common directory
# sum.js# returns sum of two numbers
export const getSum = (a, b) => {
return a + b;
};
Let’s import this function getSum in mobileApp/App.js file
When you try to import anything from outside mobileApp directory, bundler will throw an error: Unable to resolve module
Let’s add our common directory to the metro config on the watch list.
Now, re-build our react native app.
yarn run ios
Metro bundler will also look for JS files in the common directory. Now you can import any file from a common directory e.g Redux code, GraphQL queries, utility functions.
Let’s try to use the same getSum method in our Web App
When you try to import anything outside of src directory, the web app fails to compile.
There are multiple ways to fix this error.
1. Don’t use the create-react-app package to create your web app in the first place.
2. If you already have a web app created using create-react-app, you can eject it (more on that later)
3. You can use the react-app-rewired npm package to override the existing configuration.
We already created our app using create-react-app. Let’s eject
cd webApp
npm eject
When you eject your app, you will see a few extra files and some file changes.
Now we can remove ModuleScopePlugin, which is stopping us from importing files from outside src directory.
Remove ModuleScopePlugin from config/webpack.config.js file.
Start our web app again.
cd webApp
npm start
Voila, look at that — you’re now sharing code between your React native web and mobile apps! Write once, deploy everywhere 😃