4

Introducing React Native Support for Nx

 3 years ago
source link: https://blog.nrwl.io/introducing-react-native-support-for-nx-48d335e90c89
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Introducing React Native Support for Nx

https://nx.dev
https://nx.dev

We’re very excited to announce official support for React Native with our new @nrwl/react-native Nx plugin! With this release you will be able to easily develop multiple web and native apps in the same workspace — and take advantage of all of Nx’s capabilities, including shared workspace libraries.

If you use React Native in a monorepo then Nx is the tool for you!

Getting Started

Let’s create a new Nx workspace.

npx create-nx-workspace acme --preset=empty

Next, install the React Native plugin in the workspace.

cd acme
yarn add -D @nrwl/react-native# Or if you use npm
npm install --save-dev @nrwl/react-native

Lastly, generate the React Native app and run it in a simulator.

npx nx g @nrwl/react-native:app awesome-app# Start the dev app in iPhone simulator
# This will also start the packager server
npx nx run-ios awesome-app

Note that you must be on a Mac to use run-ios. If you are on Windows or Linux, you can use run-android instead — but make sure you have Java and the Android SDK installed (See: Environment Setup).

You should see something like the following.

Image for post
Image for post
iOS app running inside a simulator

Make some changes in the App.tsx file and see the app refresh in the simulator.

Creating and Using Workspace Libraries

One of the advantages of using Nx is the ease of creating and sharing libraries. Let’s say we want to create a shared UiHeading component to be used by every screen in our app.

nx g @nrwl/react:lib UiHeading --style=none

Now, replace the content of libs/ui-heading/src/lib/ui-heading.tsx with the following.

This new component can be used in our native app because Nx enhances the Metro resolver to support workspace libraries. Let’s use it in our apps/awesome-app/App.tsx component.

Upon refresh, you will see the heading rendered in the app.

Image for post
Image for post
Using a shared component in the app

Imagine that your company have multiple native apps that use a shared design system. By using Nx, sharing UI libraries is just a simple nx g command!

Sharing Native Libraries with Web

In addition to native apps, you likely have websites or web apps that use React as well. By using the react-native-webpackage, you will be able to share the UI libraries with your websites and web apps.

Let’s look at an example using a plain React app.

npx nx g @nrwl/react:app website --style=none

We can try using the same UiHeading component in our website. Open up apps/website/src/app/app.tsx and replace it with the following.

Also replace apps/website/src/main.tsx with the following code to register the app — the same way you would a native app.

Now, if you try to serve the web app — npx nx serve website — you will notice babel compile errors. These errors because native components are not supported by react-dom (for obvious reasons).

To remedy the situation, we can add the react-native-web package to our workspace and configure the ui-heading lib to use it for the web. We will also need the babel plugin to transform our code.

yarn add react-native-web
yarn add -D babel-plugin-react-native-web# or npm
npm install --save react-native-web
npm install --save-dev babel-plugin-react-native-web

The babel config for ui-heading can be updated adding the babel-plugin-react-native-web plugin to libs/ui-heading/.babelrc.

Now when you run serve again, it will render properly

Image for post
Image for post
React app using native components

Now that both the native and web apps can use the same shared UI library, we can take advantage of Nx’s affected and computation cache features.

Next, we’ll show you how to migrate existing React Native apps to Nx.

Migrating to Nx

Say that you already have an existing React Native app that lives at ~/projects/my-native-app. Here is how you can migrate it to Nx.

Step 1

Copy the app directory over the the Nx workspace.

cp -r ~/projects/my-native-app apps

Step 2

Remove the app’s node_modules folder and copy dependencies from the app’s package.json to the root.

rm -rf apps/my-native-app/node_modules# Copy and paste dependencies from app/my-native-app.package.json
# over to root package.json# Install new dependencies
yarn # or npm install

Step 3

Let’s use the Nx Metro enhancer in our app’s apps/my-native-app/metro.config.js file. This will allow the existing native app to use workspace libraries as well.

Step 4

We’ll need to update the Android and iOS code to pick up the JS bundle correctly. This step is needed because Nx sets the Metro config’s root to the workspace root, as opposed to the app root.

iOS:

Open the AppDelegate.m file and look for the jsBundleURLForBundleRoot:@"index". Replace this with jsBundleURLForBundleRoot:@"apps/my-native-app/index".

Open your Xcode workspace, and edit your Build Phases settings. Under the Bundle React Native code and images script, change ENTRY_FILE to the following.

export NODE_BINARY=node
export ENTRY_FILE=./apps/my-native-app/index.js
../node_modules/react-native/scripts/react-native-xcode.sh

Android:

Open your MainApplication.java file and look for the method getJSMainModuleName(). Replace the return value of "index" with "apps/my-native-app/index". It should look something like the following.

Step 5

Now we’ll update apps/my-native-app/tsconfig.json, nx.json and workspace.json to add our native app.

apps/my-native-app/tsconfig.json:

nx.json:

workspace.json:

After performing the previous five steps, you should be able to start the JS bundler and the iOS app.

npx nx run-ios my-native-app

You should see your existing iOS app open in the simulator. 🎉

Note on Autolinking

If you use any npm packages that have native modules, you will need to install it to the workspace root and also add an entry to the app’s package.json file. This is needed in order for React Native’s autolinking feature to work.

For example,

yarn add react-native-snackbar

And say we want to use it in my-native-app, then we need this entry in apps/my-native-app/package.json.

{
"dependencies": {
...
"react-native-snackbar": "*"
}
}

Then, we’ll need to run pod install from the apps/my-native-app/ios folder. React Native will see the package entry — and that it has native modules — and handle adding dependencies (e.g. CocoaPods) and configuring build steps for iOS and Android.

In Closing

In this post you learned how to:

  1. Create a new Nx workspace and add a React Native app.
  2. Add a shared UI lib and use it in the native app.
  3. Use the native UI lib in a web app using react-native-web.
  4. Migrate existing React Native app to an Nx workspace.

I hope you found this useful, and we look forward to hearing your feedback.

If you’re new to Nx and want to learn more, visit nx.dev and check out our React tutorial for getting started.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK