cft
Become a CreatorSign inGet Started

Journey of a console.log in React Native

A brief introduction to React Native’s new architecture.


user

Shivam Bhasin

4 months ago | 3 min read
Follow

journey-consolelog-react-native-yjyca

A brief introduction to React Native’s new architecture.

I’ve been developing user interfaces for a long time now. I learned many new things during this phase, switched from JavaScript to TypeScript for a while, then back at JavaScript, worked on web apps using React and also mobile apps using React Native.

One thing that stayed with me all this time was the love for console.log . Today, I’m using different debuggers and minifiers for debugging my code but I don’t trust anyone as much as I do console.log.

Like most JavaScript beginners, I also, for a majority of the time, believed that console.log is provided to us by JavaScript. But as I got more familiar with terms like Google’s V8, JavaScript Engine, and WebAPI’s, it got clearer. But like an experienced JavaScript developer said — it’s not that simple.

It’s not that simple

Yes, it’s not. Once, I tried to print the value of console.log in the browser and got a function that says native code. See the image below.

Chrome in a normal environment

This was pretty much meeting my expectations as console.log is anyway a function lying inside WebAPIs which has native code. But I tried a similar thing inside a react native environment, and that’s where things started taking a turn. See the image below.

Safari in React Native JSContext

So what is it that React Native does to get console.log up and running from our JavaScript code to native Android and iOS devices? I knew about React Native’s asynchronous bridge and how it serializes and deserializes stuff from JavaScript to native Android and iOS. But is this just that?

Let’s find out

I finally landed on React Native’s Github repository and searched for console. See the image below.

Two console.js files came up — the first one inside flow which has the type declarations for the module, and the one inside polyfills appeared to be a good place to start investigating. So I opened the file, started messing around, and read the functions until I found this function getNativeLogFunction. See below.

function getNativeLogFunction inside console.js file

This function takes in the argument of log level, manipulates our string, and finally calls the nativeLoggingHook on the global object. But there is no function with the name nativeLoggingHook in the browser.

This got me curious and I investigated further to see if React Native provides an implementation of this function.

So now I searched for nativeLoggingHook in the repo and interestingly found one file. See the image below.

I have been a JavaScript developer for most of my development life and never really got a chance to work on CPP. But we all have a curious kid inside us and mine led me to open the file and give the method bindNativeLogger a read.

After giving it a few minutes I realized how bad I’m at CPP so before going into depression, I did what I’ve been doing a lot while learning new things — I assumed that I know what this code does and moved ahead with my investigation to how bindNativeLogger is used in the code.

I searched bindNativeLogger in the repository and found two files. See the image below.

This is where things finally started to make sense. In these two files above bindNativeLogger is called with JavaScript runtime and the native loggers — iosLoggingBinder in RCTJSIExecutorRuntimeInstaller.mm and androidLogger in OnLoad.cpp.

Then I opened the RCTJSIExecutorRuntimeInstaller.mm file where the method bindNativeLogger is called with the JavaScript runtime and iosLoggingBinder. See the code below at line 15.

After I dig a little deeper, I found out thatiosLoggingBinder is a function _RCTLogJavaScriptInternal defined in RCTLog.mm. See the image below.

This is where console.log finally gets called on the iOS ecosystem. So somehow the console I wrote in JavaScript went a bunch of methods deep and eventually called _RCTLogJavaScriptInternal method in the RCTLog.mm file. There was CPP involved in between but I as a JavaScript developer can ignore it, at least for some time. See the image below.

Credit: YT video — Building React Native: Take a look at the internals — Parashuram N

So in a way, JavaScript is invoking a native module without actually using the React Native bridge. This is not even asynchronous, it’s just one call after the other. This got me curious and I finally went back to the CPP code that I previously ignored.

The CPP code that I ignored previously is what is known as the JavaScript interface a.k.a JSI — the new React Native architecture. JSI is a new and standardized way of exposing native Java or Objective-C objects from native modules to the JavaScript world.

Bonus

This got me even more curious and then I got to know about React Native’s new architecture that’s been under development. This was just a brief introduction to light up your curiosity about this new and interesting thing that’s been cooking inside the React Native community.

If you’re someone that’s been developing mobile apps on React Native then do subscribe to this blog as in the next part of this I’ll be deep-diving more inside this new architecture and explore things like TurboModules, JSI, Fabric, and CodeGen.

LET THE GEEK INSIDE YOU WIN!

Upvote


user
Created by

Shivam Bhasin

Follow

Engineer | Learner | Writer

Simplifying things since childhood. Writes about JavaScript, application development, and self-help.


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles