Let's make our react-native
app work in the browser, the right way.
This tutorial was made for
react-native <= 0.61
. If you are using a newer version, I recommend that you fork this repository instead: brunolemos/react-native-web-monorepo, I am keeping it updated 🙌
Why am I writing this?
Hi 👋 I'm Bruno Lemos. I recently launched a project called DevHub - TweetDeck for GitHub and one of the things that caught people's attention was the fact that it is an app made by a single developer and available on 6 platforms: Web (react-native-web), iOS (react native
), Android (react native
), macOS, Windows and Linux (electron
, for now), with almost 100% code sharing between them. It even shares some code with the server! This is something that would require a team of 3+ until a couple years ago.
Since then, I've received dozens of tweets and private messages asking how to achieve the same and in this tutorial I'll walk you through it.
What's react-native-web
?
If you are not familiar with react-native-web, it's a lib by Necolas (ex Twitter engineer) to make your React Native
code render in the browser. Roughly speaking, you will write <View />
and it will render <div />
, making sure all styles render the exact same thing. It does more than that, but let's keep it simple.
The new Twitter was created using this technology and it's awesome.
If you already know react-native
, you don't need to learn any new syntax. It's the same API.
Summary
- Starting a new
React Native
project - Turning our folder structure into a monorepo
- Making
react-native
work in a monorepo - Sharing code between our monorepo packages
- Creating a new web project using
create-react-app
andreact-native-web
- Making
CRA
work inside ourmonorepo
with code sharing - ???
- Profit
Step-by-step tutorial
Starting a new React Native
 project
$ react-native init myprojectname
$ cd myprojectname
$ git init && git add . -A && git commit -m "Initial commit"
Note: It's much easier to create a cross platform app from scratch than trying to port an existing mobile-only (or even harder: web-only) project, since they may be using lot's of platform specific dependencies.
EDIT: If you use expo, it seems they will soon have built in support for web!
Turning our folder structure into a monorepo
Monorepo means having multiple packages in a single repository so you can easily share code between them. It's a bit less trivial than it sounds because both react-native
and create-react-app
require some work to support monorepo projects. But hey, at least it's possible!
We'll use a feature called Yarn Workspaces
for that.
Requirements: Node.js, Yarn and React Native.Â
- Make sure you are at the project root folder
$ rm yarn.lock && rm -rf node_modules
$ mkdir -p packages/components/src packages/mobile packages/web
- Move all the files (except
.git
) to thepackages/mobile
folder - Edit the
name
field onpackages/mobile/package.json
frompackagename
tomobile
- Create this
package.json
at the root directory to enableYarn Workspaces
:
{
"name": "myprojectname",
"private": true,
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": []
}
"dependencies": {
"react-native": "0.61.3"
}
}
- Create aÂ
.gitignore
at the root directory:
.DS_Store
.vscode
node_modules/
yarn-error.log
$ yarn
Making react-native work in a monorepo
Check where
react-native
got installed. If it was at/node_modules/react-native
, all right. If it was at/packages/mobile/node_modules/react-native
, something is wrong. Make sure you have the latest versions ofnode
andyarn
. Also make sure to use the exact same version of dependencies between the monorepo packages, e.g."react": "16.11.0"
on bothmobile
andcomponents
, not a different version between them.Open your favorite editor and use the
Search & Replace
feature to replace all occurrences ofnode_modules/react-native/
with../../node_modules/react-native/
.For react-native <= 0.59, open
packages/mobile/package.json
. Yourstart
script currently ends in/cli.js start
. Append this to the end:--projectRoot ../../
.Open
packages./mobile/metro.config.js
and set theprojectRoot
field on it as well so it looks like this:
const path = require('path')
module.exports = {
projectRoot: path.resolve(__dirname, '../../'),
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
}
- [Workaround] You currently need to add the
react-native
dependency to the rootpackage.json
to be able to bundle the JS:
"dependencies": {
"react-native": "0.61.3"
},
iOS changes
$ open packages/mobile/ios/myprojectname.xcodeproj/
- Open
AppDelegate.m
, findjsBundleURLForBundleRoot:@"index"
and replaceindex
withpackages/mobile/index
- Still inside Xcode, click on your project name on the left, and then go to
Build Phases
>Bundle React Native code and Images
. Replace its content with this:
export NODE_BINARY=node
export EXTRA_PACKAGER_ARGS="--entry-file packages/mobile/index.js"
../../../node_modules/react-native/scripts/react-native-xcode.sh
$ yarn workspace mobile start
You can now run the iOS app! 💙 Choose one iPhone emulator and press the "Run" triangle button inside Xcode.
Android changes
$ studio packages/mobile/android/
- Open
packages/mobile/android/app/build.gradle
. Search for the textproject.ext.react = [...]
. Edit it so it looks like this:
project.ext.react = [
entryFile: "packages/mobile/index.js",
root: "../../../../"
]
- Android Studio will show a Sync Now popup. Click on it.
- Open
packages/mobile/android/app/src/main/java/com/myprojectname/MainApplication.java
. Search for thegetJSMainModuleName
method. Replaceindex
withpackages/mobile/index
, so it looks like this:
@Override
protected String getJSMainModuleName() {
return "packages/mobile/index";
}
If you get the
Cannot get property 'packageName' on null object
error, try disabling auto linking
You can now run the Android app! 💙 Press the "Run" green triangle button inside Android Studio and choose the emulator or device.
Sharing code between our monorepo packages
We've created lots of folders in our monorepo, but only used mobile
so far. Let's prepare our codebase for code sharing and then move some files to the components
package, so it can be reused by mobile
, web
and any other platform we decide to support in the future (e.g.: desktop
, server
, etc.).
- Create the file
packages/components/package.json
with the following contents:
{
"name": "components",
"version": "0.0.1",
"private": true
}
[optional] If you decide to support more platforms in the future, you'll do the same thing for them: Create a
packages/core/package.json
,packages/desktop/package.json
,packages/server/package.json
, etc. The name field must be unique for each one.Open
packages/mobile/package.json
. Add all the monorepo packages that you are using as dependencies. In this tutorial,mobile
is only using thecomponents
package:
"dependencies": {
"components": "0.0.1",
...
}
- Stop the react-native packager if it's running
$ yarn
$ mv packages/mobile/App.js packages/components/src/
- Open
packages/mobile/index.js
. Replaceimport App from './App'
withimport App from 'components/src/App'
. This is the magic working right here. One package now have access to the others! - Edit
packages/components/src/App.js
, replaceWelcome to React Native!
withWelcome to React Native monorepo!
so we know we are rendering the correct file. $ yarn workspace mobile start
Yay! You can now refresh the running iOS/Android apps and see our screen that's coming from our shared components package. 🎉
$ git add . -A && git commit -m "Monorepo"
Web project
Note: You can reuse up to 100% of the code, but that doesn't mean you should. It's recommended to have some differences between platforms to make them feel more natural to the user. To do that, you can create platform-specific files ending with
.web.js
,.ios.js
,.android.js
or.native.js
. See example.
Creating a new web project using CRA and react-native-web
$ cd packages/
$ npx create-react-app web
-
$ cd ./web
(stay inside this folder for the next steps) -
$ rm src/*
(or manually delete all files insidepackages/web/src
) - Make sure the dependencies inside
package.json
are the exact same between all monorepo packages. For example, update the "react" version to "16.9.0" (or any other version) on bothweb
andmobile
packages. $ yarn add react-native-web react-art
$ yarn add --dev babel-plugin-react-native-web
- Create the file
packages/web/src/index.js
with the following contents:
import { AppRegistry } from 'react-native'
import App from 'components/src/App'
AppRegistry.registerComponent('myprojectname', () => App)
AppRegistry.runApplication('myprojectname', {
rootTag: document.getElementById('root'),
})
Note: when we import from
react-native
inside acreate-react-app
project, itswebpack
config automatically alias it toreact-native-web
for us.
- Create the file
packages/web/public/index.css
with the following contents:
html,
body,
#root,
#root > div {
width: 100%;
height: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
- Edit
packages/web/public/index.html
to include our CSS before closing thehead
tag:
...
<title>React App</title>
<link rel="stylesheet" href="%PUBLIC_URL%/index.css" />
</head>
Making CRA work inside our monorepo with code sharing
CRA doesn't build files outside the src
folder by default. We need to make it do it, so it can understand the code from our monorepo packages, which contains JSX and other non-pure-JS code.
- Stay inside
packages/web/
for the next steps - Create aÂ
.env
file (packages/web/.env
) with the following content:
SKIP_PREFLIGHT_CHECK=true
$ yarn add --dev react-app-rewired
- Replace the scripts inside
packages/web/package.json
with this:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
- Create the
packages/web/config-overrides.js
file with the following contents:Â
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const appDirectory = fs.realpathSync(process.cwd())
const resolveApp = relativePath => path.resolve(appDirectory, relativePath)
// our packages that will now be included in the CRA build step
const appIncludes = [
resolveApp('src'),
resolveApp('../components/src'),
]
module.exports = function override(config, env) {
// allow importing from outside of src folder
config.resolve.plugins = config.resolve.plugins.filter(
plugin => plugin.constructor.name !== 'ModuleScopePlugin'
)
config.module.rules[0].include = appIncludes
config.module.rules[1] = null
config.module.rules[2].oneOf[1].include = appIncludes
config.module.rules[2].oneOf[1].options.plugins = [
require.resolve('babel-plugin-react-native-web'),
].concat(config.module.rules[2].oneOf[1].options.plugins)
config.module.rules = config.module.rules.filter(Boolean)
config.plugins.push(
new webpack.DefinePlugin({ __DEV__: env !== 'production' })
)
return config
}
The code above overrides some
create-react-app
'swebpack
config so it includes our monorepo packages in CRA's build step
$ git add . -A && git commit -m "Web project"
That's it! You can now run yarn start
inside packages/web
(or yarn workspace web start
at the root directory) to start the web project, sharing code with our react-native
mobile
project! 🎉
Some gotchas
-
react-native-web
supports most of thereact-native
API, but a few pieces are missing likeAlert
,Modal
,RefreshControl
andWebView
; - If you come across a dependency that doesn't work well with the monorepo structure, you may add it to the nohoist list; But avoid that if possible, because it may cause other issues, specially with the metro bundler.
Some tips
- Navigation may be a bit of a challenge; you can use something like react-navigation which recently added web support or you can try using two different navigators between and mobile, in case you want the best of both worlds by compromising some code sharing;
- If you plan sharing code with the server, I recommend creating a
core
package that only contain logic and helper functions (no UI-related code); - For Next.js, you can check their official example with react-native-web
- For native windows, you can try react-native-windows;
- For native macOS, you can the new Apple Project Catalyst, but support for it is not 100% there yet (see my tweet);
- To install new dependencies, use the command
yarn workspace components add xxx
from the root directory. To run a script from a package, runyarn workspace web start
, for example; To run a script from all packages, runyarn workspaces run scriptname
;
Thanks for reading! 💙
If you like react, consider following me here on Dev.to and on Twitter.
Links
- Source code: react-native-web-monorepo
- DevHub: devhubapp/devhub (production app using this structure + Desktop + TypeScript)
- Twitter: @brunolemos
Top comments (158)
HELP! something changed and i cannot replicate this tutorial anymore. i cannot get past the first time you are testing android studio. I remember something like --version react-native@next that is now missing from this tutorial. and now i cannot replicate it at all some one please help.
this is now the 7th time im following the instructions and i get this error first time i try test in the android simulator after trying to create monorepo
Unable to resolve module `./packages/mobile/index
Hi, I updated the tutorial with the latest changes from
react-native@0.59
, search forprojectRoot
to see the updated step involving the filemetro.config.js
.Hey Bruno how are you?
Im still running into a issue. Soon as i complete the web section of the tutorial. my mono repo breaks for mobile. it installs all the modules in packages/mobile/node-modules instead of root/node_modules.
Thus when I run packages/mobile/yarn start i get the following error
"Error: Cannot find module 'E:\2019_PROJECTS\moco-messenger-project\code\repo\test\node_modules\react-native\local-cli\cli.js'"
I dont understand how the web project is affecting the mobile project. Please assist.
kind regards
Make sure you have the correct content inside the root
package.json
and you usedyarn
at the root directory to install the dependencies, not inside each package neithernpm
instead ofyarn
.Compare your code with the repository to see if anything is different: github.com/brunolemos/react-native...
hey bruno,
I just did like you said, I even upgraded react-native to v0.59.0 stable. yet still when i run yarn in the root it still installs packages/mobile/node-modules and not in root/node_modules.
how can i compare an entire project with difference in vs code? are you sure there isnt a step missing? I have tried 3 times now following your exact instructions.
Do you have the latest version of nodejs and yarn? How is your root package.json?
I just checked on my computer, im running yarn 1.130 and node v10.0.0 i believe those are the latest versions.
my root package.json file looks exactly like yours.
{
"name": "myprojectname",
"version": "0.0.1",
"private": true,
"workspaces": {
"packages": [
"packages/*"
]
}
}
like i said im extremely confused becasue i dont understand why the monorepo breaks when i add the web
i just downloaded your project at
github.com/brunolemos/react-native... and when i run yarn in the root it is also installing the packages in the wrong places.
Hey everyone, I downloaded the project, followed the updated tutorial and ran into the same exact issue. I got
/mobile
running again by updating the relative filepath in its package.json to the react-native-cli:good luck!
Hey, you both were right! React Native started getting installed inside
packages/mobile/node_modules
, which is wrong. Changing the path is not the right solution though.I investigated and you need to make sure all your dependencies have the exact same version between the monorepo packages. For example, change your
"react"
dependency inside themobile
andweb
'spackage.json
to the exact same version (e.g.16.8.4
).This will make react-native get installed in the root
node_modules
again and also prevent multiple instances of react being installed in the same project, which would cause all kinds of bugs.Updated the tutorial and also the repository: github.com/brunolemos/react-native...
thank you so much for the new changes in the tutorial. i made the changes to the metro.config.js just like you suggested and i can now run it on android. i will continue with the rest of the tutorial in the morning.
Hi Bruno,
How to use 3rd lib, I want to add
react-native-element
package.It's work well on mobile, but when I run web app, it's error below:
Here's what I added to
config-override.js
onpackages/web
In future, I will add react-navigation and some other packages.
Please help, many thanks!
Did you make it work?
I haven't tried your code but yes, changing
config-override.js
correctly should be enough.Was anyone able to add react-navigation to the project? I got react-native-elements working by following the above comment.
Here's a working example for React-Navigation with web :
github.com/react-native-elements/r...
Thank for documenting all this work thoroughly.
As a React-Native noob, this guide was very easy to follow along ! Cheers!
I got react-navigation's drawer working on the web.
The following is my config-override.js
thanks for the input
i am facing similar issue while using GoogleSigninButton from react-native-google-signin.
i tried adding require.resolve('@babel/plugin-proposal-class-properties') as you suggested below.
also tried to update babel.config.js with the following, didnt worked as well...
module.exports = {
plugins: [
[
'@babel/plugin-proposal-decorators',
{
legacy: true,
},
],
[
'@babel/plugin-proposal-class-properties',
{
loose: true,
},
],
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-regenerator',
[
'@babel/plugin-transform-runtime',
{
helpers: false,
regenerator: true,
},
],
],
presets: ['@babel/preset-flow', 'module:metro-react-native-babel-preset'],
}
also tried with loose: true
require.resolve('@babel/plugin-proposal-class-properties', {
loose: true,
}),
any suggestion please?
thanks for you time.
Hi Oz, were you able to make it run? Did you try with a compatible release (any before 0.60)?
Hi Nishant,
Unfortunately I was not able to solve it.
I am not sure about earlier versions but I went over many possible suggestions, none of them worked...
Any additional idea that I can try?
Thanks for the reply
Use this config to fix the issue
Add the above code before the
return config
lineThanks Rajendran
i tried adding the above as part of config-overrides.js
it didn't helped.
BTW, i`ve executed 'sudo yarn add @react-native-community/google-signin'
Under the folder 'react-native-web-monorepo/packages/components'
Is that the right location?
Thanks, Oz
An update...
i had to add two more dev dependencies under the web module.
sudo yarn add --dev babel-loader
sudo yarn add --dev @babel/preset-flow
now i am getting different error:
/react-native-web-monorepo/node_modules/@react-native-community/google-signin/src/GoogleSigninButton.js
Attempted import error: 'requireNativeComponent' is not exported from 'react-native'.
With the react-native-version 0.60.4, I have some problems with libhermes.
When starting the android-app, it crashes and I always get the message: E/SoLoader: couldn't find DSO to load: libhermes.so. Any suggestions what to do?
Edit: Fixed my problem. You have to enable hermes, so that it looks like this in your build.gradle in app:
project.ext.react = [
entryFile: "packages/mobile/index.js",
root: "../../../../",
enableHermes: true, // clean and rebuild if changing
]
This works for me thanks!
throws error error: unknown option `--projectRoot'
On modifying
--projectRoot
to
--projectRoots
I get following error
Loading dependency graph...jest-haste-map: Watchman crawl failed. Retrying once with node crawler.
You mean when trying to use jest? If not please check the repository to see what you made differently.
Sorry, I modified my comment. I am getting an error with --projectRoot. I was trying on my own repo. I'll be cloning your repo and then let you know if the problem persists.
I'm using the unreleased react-native 0.59 in this tutorial, some dependencies got a major bump so maybe there are some differences if you are using an older version.
did you find an alternative for --projectRoot please ?
Hi Bruno, thanks for the awesome detailed tutorial with all the updates. And i can see you are very active in comments also which is awesome!
Its really nice to see react's progress towards PWA and cross platform portability.
I am following this tutorial to convert our old add(on Rn 0.59) over to react-native web. I followed this tutorial and setup everything up.
Than i copied the dependencies from our mobile repo's package json to packages/components/package.json. And all other code respectively in src. Idea was to get everything running on ios in this monorepo setup and than go from there to fix whatever needs to be fixed for web.
But i am getting some errors like first i got:
bundling failed: Error: Unable to resolve module
path
from/Users/..../projec/node_modules/react-native-dotenv/index.js
: Modulepath
does not exist in the Haste module mapFixed it by adding
path
explicitly in dev-dependencies. Than started getting error:bundling failed: Error: While trying to resolve module
fs
from file/Users/..../projec/node_modules/babel-plugin-dotenv/index.js
, the package/Users/..../projec/node_modules/fs/package.json
was successfully found. However, this package itself specifies amain
module field that could not be resolved (/Users/..../projec/node_modules/fs/index.js
. Indeed, none of these files existI am not very experienced in react and react-native, i am mainly on Ruby on Rails, so maybe this is something basic which i am getting wrong.
I found: stackoverflow.com/a/39046690/4738391 which suggests omething wrong with node environment or something. But i am a bit confused, i mean i can add these dependencies etc but it should work out of the box for mobile, as it was working fine in previous repo.
Any help will be greatly appreciated. Thanks.
This was a stupid error, i had forgot to add
'module:react-native-dotenv'
in my babel config presets. Adding it solved the problem and i got my mobile app compiled. There were some imports fixes etc in scode needed to be done to run app successfully. But that is done.But now next errors(on web), i posted this SO question: stackoverflow.com/questions/571953...
If i can get any help, would be great.
After cache clean and everything, second error changed to:
error: bundling failed: Error: While trying to resolve module
fs
from file/Users/..../projec/node_modules/babel-plugin-dotenv/index.js
, the package/Users/..../projec/node_modules/fs/package.json
was successfully found. However, this package itself specifies amain
module field that could not be resolved (/Users/..../projec/node_modules/fs/index.js
. Indeed, none of these files existI was running into the same issue and I think I figured out the cause of the problem. I unfortunately don't know how to fix it. It seems to be related to react-native-cli not being able to locate the metro and babel configs because it's being run from the root of the repository.
Since they aren't found, when the bundler comes across react-native-dotenv within a source file it will actually import the source file rather than using the replacement provided by the babel plugin.
Please remove all node_modules folders and .lock files from your project, clear all caches (xcode, —reset-cache, etc), and try following the steps again. Maybe you missed something.
You shouldn’t remove the dependencies from mobile. Check this repo source code and commit diffs: github.com/brunolemos/react-native...
After running yarn to install dependencies, check the contents of packages/mobile/node_modules, and let me know which folders it has. It shouldn’t have any, all should be in the root node_modules.
If nothing works, maybe they released a new version of the cli that broke something, in that case you can use a previous version or investigate the change.
I think i was not clear in my comment, actually it did work with barebone setup as described in this post. It was working perfectly, than i started exporting my mobile code, that's when it exploded.
I wanted to just have mobile app running as it is in this architecture. Than move un-convertable code to mobile and write replacement code for only those in web. But my mobile app is not running with these errors.
I did all the cache clear and everything but same issue. mobile repo's node_modules folder have 2 folder, .bin and metro-react-native-babel-preset.
I am pretty sure it is some of my mobile dependency. I don't know if i should share the package json etc and everything here. It will just get annoyingly long here.
Let me know if i should share that here, or i can reach you through some other medium.
I do understand this blog post is like THE go to blog right now for new projects which want to take this route. but porting old projects is a lot more messy. If i do succeed in porting my app on this architecture and support web, i will leave pointers and can also write an extension of this blog post.
You can run debug session from vscode with React Native Tools extension. But with monorepo its little hacky... btw, read-native run-its --project-path "./packages/mobile/ios" also work
I setup only iOS project with macos: you need to specify "runArguments": ["--project-path", "./packages/mobile/ios"] in debug task in launch.json and symlink with command:
~if somebody already setup android debug, please ping me~
Update:
in vscode task for android add
Thanks for sharing!
I am unable to run android app. When I run
yarn android
I am getting this error.How to update
project.ext.react.cliPath
path?Can anyone suggest what changes did I miss?
I found it. Thank you. I needed to add
cliPath
insideproject.ext.react
in app/build.gradlehow did you do that, could you please add a screenshot or something ?
I apologies for the late response.
Basically what you need to do is go to
mobile/android/app/build.gradle
and update the file as show below.If you want to jump right into the code then you can check out my repo, I have updated the setup.
Nice, thanks for the mention in the article!
Were you able to share code between web and mobile using nohoist? I've had problems with this approach in the past but I don't remember exactly why. It has some downsides but it's definitely much simpler to setup. Everything working well for you this way?
No, sry for taking so long to reply.
Our yarn workspace is just set up to include app / backend / website
And they do not share components.
The problem is that metro does not support symbol links. Which is what yarn workspace uses.
github.com/facebook/metro/issues/1
Hi man, absolutely amazing tutorial, my dev team managed to get it up an running in no time.
However, we are facing two problems, one is related to babel plugins, no matter what i did, i could not add the @babel/plugin-transform-react-jsx, therefore the web package crashes:
The other problem comes with
react-native-vector-icons: ^7.0.0
, we added the:but we could not get them to render in android, instead it shows the crossed box, here is how we implemented it:
try this, please see the following :
step
npm install @babel/plugin-transform-react-jsx or yarn add @babel/plugin-transform-react-jsx
go to config-overrides.js : Then add the package installed to plugins...
please see below,
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);
// our packages that will now be included in the CRA build step
const appIncludes = [
resolveApp('src'),
resolveApp('../common/src'),
resolveApp('../../node_modules/@react-navigation'),
resolveApp('../../node_modules/react-navigation'),
resolveApp('../../node_modules/react-native-gesture-handler'),
resolveApp('../../node_modules/react-native-screens'),
];
module.exports = function override(config, env){
config.module.rules.push({
test : /.(js|mjs|tsx|ts)$/,
exclude : /@babel(?:\/|\{1,2})runtime/,
use : {
loader : 'babel-loader',
options : {
babelrc : false,
configFile : false,
compact : false,
// The configration for compilation
presets : [
[
'module:metro-react-native-babel-preset',
], // Add this line,
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory : true,
plugins : [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-transform-flow-strip-types',
'@babel/plugin-transform-react-jsx'
[
'module-resolver',
{
alias : {
'^react-native$' : 'react-native-web',
},
},
],
],
},
},
});
return config;
};
thanks
paste it to *config-overrides.js
This JS is not valid (check module-resolver)
I am able to run this setup in Dev mode on both ios and android but when I create a releaze, I get an error saying the shared package is not found because it is a symlink and metro bundler doesn't support symlink yet. Were you able to create release builds? If yes, were there any changes required?
ios or android? which react-native version? what's your operating system? try using the latest react-native version and maybe also try using the yarn resolutions feature to force it use the latest version of @react-native-community/cli which as of today is 5.0.1-alpha.0.
So, I have a mobile app in production on iOS and Android that we plan to provide over the browser also. To reuse the logic code in the web app, I am putting those in shared packages managed using the yarn workspaces. Initially, I was using react-native 0.63.3 which uses react 16.13.1 for the mobile app. When I created the web app, it was using react 17.0.1. There were a couple of invalid hook call errors which happen due to conflicting versions of react. I tried no-hoisting react and react-native specific packages but that resulted in some packages under root node modules and some under the package node_modules which becomes problematic during auto-linking. So, I ended up upgrading react-native to 0.64.0-rc.1 which uses react 17.0.1. I was able to build and run the app on both iOS and Android but when I created the release build, I got some errors mainly around not able to find the shared packages since they are symlinks and metro doesn't support symlinks. I read about some workaround by providing extraNodeModules and projectRoots in metro.config.js but I kept on getting one error or the other.
I wanted to ask if you made any special changes to create release builds for your app and what are those?
After banging my head for the last few days to convert the existing app to the mono-repo, I started out creating a brand new app in a mono-repo structure, have a dummy shared package and create release builds from it and then port my code over. I am getting the below error on iOS while creating an archive. I am able to run the app in dev mode:
error: Build input file cannot be found: '/Users/varungupta/Projects/galarm-combined/node_modules/react-native/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm' (in target 'FBReactNativeSpec' from project 'Pods')
This error doesn't appear if I create a new project and create an archive without making it into a mono-repo.
One more thing I wanted to ask is do I need to change the paths in node_modules/react-native/scripts/react_native_pods.rb and react.gradle files as they contain some references to node_modules.
See this repository: github.com/brunolemos/react-native...
Dear Bruno,
Thanks for your response. I am already doing #2 as yarn seem to update the packages without updating package.json if there are minor upgrades available. I was not aware of the yarn resolutions but that is pretty cool I do have some node_modules in my web and mobile folder which I will fix using yarn resolutions.
For setting the project root in metro.config.js, I guess I just need to set it to the dirname like projectRoot: path.resolve(dirname, '.')
For the react-native.config.js file, could you please tell me where and how it is used. I created it based on your blog instructions but I am not sure how it is used.
Also, I checked the devhub repository (great resource btw), it doesn't have a react-native.config.js file or setting a projectRoot in metro.config.js file.
Thanks again for your valuable time.