Ana Laura T.
Ana Laura T.

Reputation: 670

What is the role of Node.js in React-Native?

I'm trying to understand the development process of React-Native, so I've found information about Metro, And then I've read/watch this Metro video):

Metro is the development platform for React Native and it does that by exposing an HTTP server so clients, in this case, emulators can communicate with it and it also exposes a Websocket server so it can push updates into the clients.

The docs talk about the "React Native Packager" (now called Metro, according to the video) which runs on port 8081, so that is the HTTP server that starts when we type react-native run-android for example?

Regarding the Websocket I still need to read more.

The documentation says we're running our JavaScript code in two environments, depending if we're in debug mode or not, which I understood. But this article confused me a little bit, says:

No. 4 You Code Does Not Run on Node.JS: The JavaScript runtime you’ve got is ether JavaScriptCore (non-debug) or V8 (debug). Even though you can use NPM and a node server is running on the background, your code does not actually run on Node.JS. So you won’t be able to use of the Node.JS packages. A typical example is jsonwebtoken, which uses NodeJS’s crypto module.

And, then I've read things like:

React Native uses Node.js, a JavaScript runtime, to build your JavaScript code.

Node.js is a server-side JavaScript runtime environment. React Native ships with some tools that are written for Node.js.

Node.js is an open source platform built on Chrome's JavaScript runtime; it offers a way to easily build fast, scalable programs. Node.js allows you to run JavaScript in Terminal, and helps create modules.

In this article, it says:

Download node.js from nodejs.org. This JavaScript runtime gives you access to npm, which is a convenient tool created by the node.js project that you can use to manage open source packages. Make sure that you download the latest LTS (Long Term Support) version of node.js. Also included with this download is a development server called the Metro bundler, which provides live updates when debugging.

So:

Upvotes: 31

Views: 21299

Answers (2)

Stanley
Stanley

Reputation: 159

For anyone that comes across this, here's my 2 cents of explanation. I'll try to explain the step taken to bundle and execute your app in debug and release mode.

In Dev / Debug mode

Metro bundler (which runs on top of Node.js) bundles all your JavaScript codes: The ones you wrote, the ones in your app's dependency packages, and the ones that comes with React Native. It bundles them into one big JS file, then spins up a local server on port 8081 to serve the bundled file when requested. That is pretty much how Node.JS is involved.

Further explanation:
Now when you open your compiled debug app (.apk for Android or .ipa for iOS), it makes a request to the local metro server to fetch the bundled JS file so that the JS interpreter (JavaScriptCore or Hermes which is packaged into your app can begin executing it. But you may ask, what happens to the native codes (Java/Kotlin or Obj-C/Swift) that is also part of the compiled app?

The simple answer is, these native codes cannot be executed by the JS interpreter, so it has to be executed separately but within the same app. That means JS has to be executed separately and native codes also has to be executed separately, but all within the same app.

Fortunately, Threading allows for such things, they allow you to run multiple sub-programs (threads if you will) within the main program (process).

So when your compiled React Native app is opened (as a process), what actually happens is it spins up three threads from within it:

  1. JS thread
    This is where the JavaScript interpreter which executes your bundled JavaScript - sent from metro server - lives
  2. Shadow thread
    This is where the flexbox-based styles and layout you give to your elements are converted into layout and styles that the native platform (Android or iOS) can understand. This is done by Yoga, a cross-platform layout engine.
  3. Main/UI/Native thread
    This is where all the native Java/Kotlin or Obj-C/Swift codes are executed. It is here that native platform APIs (e.g Camera) are accessed from and native platform UI elements (e.g View for Android and UIView for iOS) are rendered. It is from this thread that the other two threads are spawn.

The communication between the three threads mentioned above are facilitated by the React Native Bridge or Turbo Native Modules which is the new approach.

In Prod / Release mode (when you compile for release to app stores)

Everything is the same as in Dev/Debug mode except that the bundled JavaScript file is packaged together with your app (apk or ipa) as an asset when the app is being compiled, rather than being loaded from metro server.

So when you open the compiled app, the JS bundle is just loaded to the JS thread from within the app's assets folder and is executed. That also means there's no need for Metro or Node.js from that point as everything the app needs to work is already precompiled into it.

Upvotes: 4

Jonas Wilms
Jonas Wilms

Reputation: 138537

There are four types of JavaScript you'll write in todays environments:

1) Clientside browser JavaScript:

That's what gets sent to webbrowsers when they visit your webpage, it then gets executed in the browser at the clientside. As you want the JS to load fast and run on all kinds of browsers, you usually use transpilers to turn the modern ESnext you write into a minified version with better support.

2) Clientside native JavaScript:

Most devices do have a native JS runtime, therefore you can ship JS files with your Android / iOS / Desktop application and then start them there. These engines also support adding hooks from JavaScript into your native code, that's how React Native does provide it's APIs.

3) Serverside NodeJS JavaScript:

NodeJS is a runtime you'll use to run servers.

4) Buildscripts running on NodeJS:

You can use JavaScript to generate JavaScript files. That's how you bundle the files for (1) and (2) (maybe also (3)).

Now metro is a serverside buildscript (on NodeJS) that you can use to either a) start a server that serves your JS as a webpage (1 & 3), or b) that bundles your JS in a native App that you can install on your device (2).

The role of Node.js in RN is to only access npm and manage the packages?

No. metro is itself a package that you then run on NodeJS.

Upvotes: 23

Related Questions