简体   繁体   中英

What happens when using “require()” in Node.js?

Sorry if this is a dumb question but I'm new to JavaScript/Node.js. This code below eludes me and I've done a fair bit of research... My questions below are more specifically related to instantiation.

I don't understand this:

var myApp = require('express'); 
var myCode = myApp();

How I see that it should be for instantiation:

var myApp = new Express();
var myCode = myApp.insideExpress();

How anonymous function expressions are:

var myApp = function();
var myCode = myApp();

If the word " require " acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?

My questions are:

  1. What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?
  2. Are people who do this just creating bad patterns? Why should I use this pattern?
  3. If no instantiation, then why not?

Thanks in advance

const myVar = require("someModule") loads a module from the file system, runs the module initialization code and assigns the module exports to your variable. The module loading sub-system maintains a cache so if it was previously loaded, it is not loaded or run again, the module's exports are just retrieved from the cache and assigned to your variable.

So, when you do this:

var myApp = require('express');      // load express module, assigns exports to myApp
var myCode = myApp();                // calls myApp() function and assigns result to myCode

The first line loads the express module and assigns the exports from that module to your myApp variable. In this particular case (it varies from module to module), the exports from the Express module is a function. So, after that first line of code, myApp contains a function which happens to be a factory function for creating new Express app objects.

The second line of code calls that factory function which returns a new Express app object.

A module can export anything it wants. In the case above, it exported a function, but it's also common to export an object that has a whole bunch of properties which you can then access. You can also export a constructor in which case the caller would then use new with the constructor to create a new object from it.

In the Express module, it did not export a constructor (which is why you don't use new with it). Instead, it decided to export a factory function that, when called, creates and returns a new object. This is just a design decision that can go either way depending upon the needs of the module and the whims of the code writer.


I can't really tell what you're asking here with this code:

var myApp = new Express();          // the express module does not export a constructor
var myCode = myApp.insideExpress();

This would work only if Express was a constructor function. The express module itself does not choose to export a constructor function so this is not how you use the express module. It could have been designed this way, but it was not. They simply made a different design decision when designing it.


For this other case you show:

var myApp = function();
var myCode = myApp();

That first line of code doesn't make any sense. Perhaps you meant for it to have a body to the function:

var myApp = function() { some code here };
var myCode = myApp();

In that case, myApp is being assigned a function expression (which is just one of several ways to declare a function). It's similar, though not exactly the same as:

function myApp() { some code here }

If the word "require" acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?

require('someModule) loads a module and returns the exports from the module which can be any Javascript data type. It doesn't act as an anonymous function in any way. require() is an actual function and you are just calling it and getting back its return value. Remember that in Javascript, you can return any data type from a function, include return another function (which is what the express module does).

What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?

No instantiating or constructing. It's just loading a module, running its initialization code and return its exports. Some objects are created by the module loading system that are used for its own housekeeping, but the module itself is just initializing itself and then deciding what it wants to export.

Are people who do this just creating bad patterns? Why should I use this pattern?

Modules are highly useful in node.js development and it is considered good design to use proper module design. There are many, many advantages to good module design such as easier code maintenance, easier code testing, easier code reuse, easier code sharing, no need to create globals in order to share code, etc...

If no instantiation, then why not?

A module decides what it wants to export. It can, in its initialization code, create an instance of an object and export it. It can export a factory function that creates an instance of an object when called. It can export a constructor directly that lets the caller use new with it to create an instance of an object. It can export a utility function that just carries out some function and doesn't create any objects. It can export just data. It can export a plain object with multiple properties on it that have all sorts of possible uses. The possibilities are endless and it entirely depends upon what the purpose is of the module and what it wishes to share with the other module that loaded it.

It's just loading a library or a module into your script. It is not instantiating a new object. It's just making the loaded module's functions etc available to your current script. Here is a good writeup that I found, http://fredkschott.com/post/2014/06/require-and-the-module-system/ I hope that helps answer your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM