Code reuse intends to save time and resources, and reduce redundancy by taking benefit of assets that have already been designed or developed in some form within the software product development process. You can reuse a lot of code between React and React Native e.g. business logic, utilities, helpers, API fetching logic, etc. But don’t overreach on what you’re sharing because doing so may leave your code harder to maintain.
UI components will have to be written separately for both mobile and web.
Contents of ‘shared’ folder:
- Business logic
- Communication with API
- State management classes: Stores, Reducers, Actions
- Helpers
- Constants
- Storage Services
- HOCs (Higher-Order Components)
Contents of ‘web’ & ‘mobile’ folder:
- Presentational components
- Navigation / Routing
- Styles
Setting up a shared project
Open terminal. Make sure you are in the project root folder.
- Run the following command to create the mobile, web, and shared folders:
$ mkdir -p packages/shared/src packages/mobile packages/web
- Create a new React Native project using
react-native-cli
insidepackages/mobile
- Create a new React app using
create-react-app
insidepackages/web
- Create a ‘
package.json
‘ file in the root directory to enable yarn workspaces and paste the following:
{
"name": "monorepo",
"private": true,
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": []
},
"dependencies": {
"react-native": "0.69.5"
}
}
Create a shared folder
Now create a shared folder where the shared code of the React and React Native apps will reside.
$ mkdir -p packages/shared
- Create a ‘
package.json
‘ file inside the shared folder and paste the following:
{
"name": "@monorepo/shared",
"version": "1.0.0",
"dependencies": {}
}
Directory Structure
Configure the web (React) application
- In your terminal, change the directory to packages/web and run the following commands:
npm install react-app-rewire-yarn-workspaces react-app-rewired --save-dev
- Replace the scripts section in the package.json file with the following:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-app-rewired eject"
}
- Create a new file named ‘
config-overrides.js'
inside web folder and paste the following:
const rewireYarnWorkspaces = require("react-app-rewire-yarn-workspaces");
module.exports = function override(config, env) {
return rewireYarnWorkspaces(config, env);
}
- Now run the following command to install the dependencies:
yarn install
Configure the mobile (React Native) application
Configuring a React Native app through monorepo is a bit tricky. Firstly, change the directory to packages/mobile on your terminal. Now, you will need to understand two things before making workspaces work.
- No Hoist
- Symlinking
1. No Hoist
Inside the package.json file, the packages that you list down under “nohoist” tag will only be available for mobile and will not be hoisted globally.
2. Symlinking
A symlink is a term used for any file that contains a reference to another file or package. To achieve symlinking, we will use ‘wml’.
- Install wml globally using the following command:
npm install -g wml
- Copy the by running the following command in the root directory:
wml add packages/shared packages/mobile/node_modules/@monorepo/shared
- Start wml using the following command:
wml start
Once you run the above command, you should see an output something like this:
In case no output gets displayed, then follow this answer to get the issue fixed: https://github.com/wix/wml/issues/38#issuecomment-521570796
You can now develop and import functions from the shared folder inside the components in the web and mobile folders. Add a file inside packages/shared/src folder and export a function inside it. You should then be able to import the function inside your web and mobile files like this:
import { functionName } from '@monorepo/shared/src/fileName';
This is how we set up a project to share code between React and React Native applications. Thanks for reading!