Internals of Node- Advance node ✌️

Internals of Node- Advance node ✌️

Here We are going to understand and get some walkthrough related to the internals of Node JS 😉.

We will try to leverage that knowledge to write some more performant code in the application.

We are going to see the very simple snapshot that depicts the overall of an architecture of lying Node Js.

The very first thing here is that javascript code that we write and execute in the command line. When we run node index.js, we are invoking the Node Js framework. Now like any other javascript framework in the industry, Node Js is also have many dependencies that actually execute our code.

Two major dependencies we now are looking at

  1. V8 project
  2. Libuv project

V8 Project

V8 is a powerful open source Javascript engine provided by Google.

The actual purpose of this project is to execute the javascript code outside the browser. So what actually is a Javascript Engine? It is a program that converts Javascript code into lower level or machine code that browser can understand.

The Chrome V8 is written in C++ and Node Js. It implements ECMAScript specified in ECMA-262.

There are many more javascript engine like SpiderMonkey, Rhino, Chakra, Javascript Core etc. These runtime engines follow ECMAScript standards. Javascript is the dialect of ECMAScript which is supported in web browser and many more applications.

Libuv project

The Libuv project is the open source project written totally in C++(100%). The purpose of this project is to give access to the Node, the operating system file system. It gives us access to the networking and also handles some aspects of concurrency as well.

So now, we get some understanding about these project and what they are used for. But what about Node, What may be the purpose of Node here, Yes the same question arises in your mind too.

So instead of using V8 and Libuv directly Why we are using Node here i will explain it in further moments.

To understand this 🔓, i will try to show that the some of these dependencies are not totally a javascript code.

The V8 project is like 70% written in C++ and 30% in Javascript.

The Libuv project is 100% C++ code.

So as per this, you don’t want to write C++ code at all 😟 . Here comes the Node Js into picture.

Node Js give us a nice interface to use and relates our Js side of our application to the actual C++ that is running on our computer to actually interprets it in JS code.

The other things 😇 Node does is to provide a bunch of wrappers to write consistent API’s for us to use inside our project.

For example:- Node implements the Http module and Fs modules, path, crypto etc.

All these modules have very consistent APIs ⛑. So in this case you don’t want to access the exact C++ code in Libuv to do these things for you. 👉

You just required some javascript functions or a wrapper to run your codebase. Not the Libuv project directly. 😌

So with the use of Node Js ✊, you don’t have to work with C++ code at all that lives inside the Libuv project. You call the Node modules whichever required and implements your javascript code as per your need. So, this is how Node Js eases our work 😋 and lets us use its own javascript functions to get the things done.

Modules implementations

Let try out some practical examples 🛠 that will show how node will do things for us.

  1. Pick a Function in Node standard library. ⛏

2. Find where its implemented in node source code . ℹ️

3. See how V8 and Libuv are used to implement that functions — See how node leverages and wraps functionality inside of V8 and Libuv. 😈

This would be exciting and let you know how actually node works.

Which function to Investigate in Node ?

To know how actually Node works and its all modules let’s deep dive into the Node Library. We are going to investigate over a function lying in Node’s Crypto module — usually it is used to hash the password to be stored inside the db. Its name after some hashing algorithm.

hashes 😉

Let’s look into the source code of this scrypt function in Crypto library.

and see how node make use of Libuv and V8 to work around it.

Open the https://github.com/nodejs/node to see.

This is for the educational purpose.

Two folders we are majorly looking at in the Source code :-

  1. Lib — contains all the Js definitions of all the functions and modules that you and I require into our projects — JS side of node project. 😇

You can think of it as the Javascript side of Node Library. 👐

2. Src — Inside this folder is the C++ implementation of all the functions 😧 . This is where Node actually pulls 🔧 in the Libuv and V8 project and flushes 😳 out the actual implementation of all the functions and modules which you and I are using it like the FS module, Http module and so on.

Lets see the function in Lib folder and find the JS definitions of that function.

So inside the Lib Folder we are going to find the internal folder will then find the Crypto folder and finally we will find the scrypt.js

So here we go this is the javascript file contains the JS definitions of the function. ☺️ 😌 . This is the function that is being present in the NODE standard library. Its all like the function we are going to write inside any javascript file.

“programming language codes”

In your scrypt.js, you will find internalBinding() function now. Earlier it is being written as Process.binding() and Now they have changed it to internalBinding() as they are now inaccessible from user land because they are only available from NativeModule.require() But .

These are all C++ binding Loaders 🚛

  1. process.binding(): the legacy C++ binding loader, accessible from user land because it is an object attached to the global process object. These C++ bindings are created using NODE_BUILTIN_MODULE_CONTEXT_AWARE() and have their nm_flags set to NM_F_BUILTIN. We do not make any guarantees about the stability of these bindings, but still have to take care of compatibility issues caused by them from time to time.
  2. process._linkedBinding(): intended to be used by embedder to add additional C++ bindings in their applications. These C++ bindings can be created using NODE_MODULE_CONTEXT_AWARE_CPP() with the flag NM_F_LINKED.
  3. internalBinding(): the private internal C++ binding loader, inaccessible from user land because they are only available from NativeModule.require() These C++ bindings are created using NODE_MODULE_CONTEXT_AWARE_INTERNAL() and have their nm_flags set to NM_F_INTERNAL. ℹ️

Internal JavaScript module loader: 💪

NativeModule: a minimal module system used to load the JavaScript core modules found in lib/**/*.js and deps/**/*.js.

All core modules are compiled into the node binary via node_javascript.cc generated by js2c.py, so they can be loaded faster without the cost of I/O.

This class makes the lib/internal/*, deps/internal/* modules and internalBinding() available by default to core modules, and lets the core modules require itself via require(‘internal/bootstrap/loaders’) even when this file is not written in CommonJS style.

Process.binding/InternalBinding is the actually C++ functions which is calling incase.

Its a bridge 🔦 between the C++ code and Javascript side of Node standard library.

How Process.binding()/internalBinding() works ?

It is the bridge between the JS side of Node and C++ side of Node which is where the lot of internal work 🔧 🛠 that the Node does for you is actually implemented. Lot of your code is ultimately relies on C++ code. The binding does all the heavy lifting.

We will now see how C++ side of Node is actually implemented its in src folder.

Node_crypto.cc — inside it we will find Line of code (5000+). This is the actual code which crypto modules depends on and lies in the C++ world of Node.

Down to bottom ✌️ you will find the export of C++ setMethod() . This line of code is eventually being called by the line internalBinding() / process.binding()

SetMethod of C++ implementation for Scrypt.

This is somewhat that joins up the Javascript side of Node with C++ side of node.

This is where the actual implementation of function is being written. 100 % pure C++ code. 👊

Now I think you might get an idea of how and when you run the Javascript code it internally relies on the C++ code. 😐

Now I think you are curios 📃 📃 📃 about the how V8 and Libuv comes into play. Let me show you are screenshot at the very top of the file.

Go to top of the file ‘ 🔝 ‘

Using v8::Array etc. So the purpose of V8 inside the node source code is to essentially intact as an intermediary and allow values that are defined inside Javascript to be translated into their C++ equivalents .

So all these V8 statements are importing C++ definitions of JS concept. Like C++ understanding of what Js False, C++ understanding what a Integer is, or null, string, etc.

This is where the actual V8 project ℹ️ comes into play. V8 is used to translate the Node Js values that you and I place under different program as a Boolean , false, null , object etc and translate it into their C++ equivalent ones.

On the other hand, Libuv is also used here and its not easy to detect lets search for uv 🙈

So in this Libuv is used for lot of concurrency and processing constructs on the C++ side.

So to wrap up, Now I think you better have some understanding related to internals of node and how node works.

Hope you like it, Please comment and clap & share it as this will be a motivator for me to write.👏 👏 😉 .