Learn modules and concurrency in node.js

Modules and Concurrency

Introduction

In this article, you’ll understand Node modules and concurrency, and how to define and require modules using the exports and require objects. after that, you’ll see how Node handles slow operations and allow the execution of many things at once without using any threads. Let’s start with the simple module system the three important keywords are, the module keyword, the exports keyword, and the required keyword.

Defining Node Modules

In Node, the word module is a fancy word that means a file, or a folder, that contains code. So, this file here with this simple console. the logline is a module.

//index.js

console.log('Hello Node');

However, the reason the word module is a bit better to use than using just the terms file or folder here is that Node actually does not just execute the file as is, it wraps the file with a function first.

So, let’s understand the keyword arguments in JavaScript.If you access that keyword inside a function. the keyword arguments will represent all the arguments passed into this function,

 function ArgsFunction()
 {
   console.log(arguments);
 }
 
 ArgsFunction(1,2,3,4,5);

If we execute this file, this is the representation of the arguments keyword, and it’s representing all the arguments that we passed here to the dynamic arguments function. So this arguments keyword here is a handy way to write functions that accept a dynamic number of arguments.

 $ node index.js
 [Arguments] {'1','2','3','4','5'}

There is a function wrapper here,

 function(exports, module, require, __filename, __dirname) 
 {
 }

So, there the function call, and this function receives a set of arguments, and your code becomes the body of this function. And then the Node will call this function. The arguments that this wrapping function receives are, in order, exports, module, require, _filename, and then _dirname.

Variable declaration

You can use the exports or module. exports to define the API of a module, you can use require to require other modules inside this one, and the __filename has the path of this file, and the __dirname has the path to the folder hosting this file. All of these objects, which you can use inside this file, are not global objects. They are arguments to the wrapping function. They are customized for each file, and they’re different in each file.

So, when inside a file,

exports.a = 42;

in Node, when we define a variable in any file on the top-level like, for example,

let g = 1.

This g variable will not be a global variable at all. It’s a variable inside a function. The scope of this variable is the hidden wrapping function. This is different than what a browser would do when you define a variable top-level. Browsers do not have this hidden wrapping function.

Declare scope of variables

So, when you define a variable like this in a browser in a script, that variable will be global. It will be available to all the scripts you include after defining it because you’re putting it on the global scope. But that’s the browser, not Node. Node has the wrapping function.

And this g is not global at all. It’s a local variable inside the wrapping function. This variable here, scope to the built-in wrapping function.

the wrapping function also internally return something. And the thing it returns here is the module.exports property. This is what the built-in wrapping function return by default, all the time, for every file, it will return module.exports.

the module argument that gets passed to the function as well, and it’s the object that Node uses to manage the dependencies and to manage the APIs of modules. you don’t need to use the return keyword. The node will always make this function return the module.exports object, and this is the object we can use to define the API of this module.

 module.exports.b = 55;

The exports object is an alias for module.exports. When Node invokes the wrapping function, it passes module.exports as the value of the first argument here.

This is why we can use the exports keyword itself to export a new property on the API, but what we’re modifying when we do that is the module. exports object, which is the one being returned.

So both a and b are part of the API of this module because exports are an alias to module.exports, and we’re returning module. exports. To use this API that we defined in these 2 lines here,

there is another file here in the same folder and this is invoking the require function, and passing in as a string, the path of the module. The result of this require call, is the module. exports object that Node returned from our module.

 const modueApi = require('./3-wrapper');
 
 console.log(modueApi);

So the module’s API here becomes the module.exports that the file returned, and we can see the console.log in here.

 $ node 3-require.js
  { a:42, b:55}

we’re making this variable point to a new local object in here and no longer point to module.exports. So if, for example, you want your top-level API to be a function instead of an object, which is a valid case that we use all the time. We want our top-level API to be a function, not an object. module.exports, breaking the assignment reference between exports and module.exports, but you can do module.exports = a function.

Leave a Reply

Your email address will not be published. Required fields are marked *