The interview will ask

Do you understand the operation mechanism and cache policy of require?

Does require load modules synchronously or asynchronously? Talk about your understanding

What is the difference between exports and module.exports?

What exactly is being loaded when require loads a module?

Koala is dedicated to sharing the complete Node.js technology stack, from JavaScript to Node.js, to back-end database. Wish you become an excellent senior Node.js engineer. [Programmer growth refers to north] Author, Github blog open source project github.com/koala-codin…

require

Exports and module.exports we have to mention the require keyword. Everyone knows that Node.js follows the CommonJS specification and uses the require keyword to load modules.

Require introduces the problem repeatedly

Q: Do you use require to introduce modules? Do you use multiple code files to introduce the same module?

This is because in C++ keywords like #IFNDEF are used to avoid file duplication, but in node.js you don’t need to worry about this because node.js loads modules from the cache first by default, and after a module is loaded once, it maintains a copy in the cache. Duplicate modules are fetched directly from the cache if they are repeatedly loaded, meaning that there is only one instance of each module in the cache at any time.

Does require load modules synchronously or asynchronously?

Answer the questions first, in sync! But what if the interviewer asks you why are you synchronous or asynchronous? The answer is not set in stone, but it can be explained in several ways.

  1. A module that is a public dependency, of course, wants to be loaded all at once, so synchronization is better
  2. The number of modules is usually limited, and Node.js will automatically cache loaded modules when require, plus access to local files, resulting in almost negligible IO overhead.

Cache policy for require()

Node.js will automatically cache files imported through require, so that the next import does not need to go through the file system and will be read directly from the cache. However, this caching method is based on file path location. Even if two identical files are located in different paths, two copies will be maintained in the cache. Can be achieved by

console.log(require.cache)
Copy the code

Gets all files currently in the cache.

Exports differs from Module. exports

When the js file starts

When a node executes a file, it generates an exports and Module object for the file, which in turn has an exports property. The relationship between them is shown below, pointing to a {} memory region.

exports = module.exports = {};
Copy the code

Take a look at a picture to make it clear:

Require () loads the module

Let’s look at an example code when require() loads the module

//koala.js let a = 'programmer growth refers to north '; console.log(module.exports); {} console.log(exports); {} exports. A = 'programmer growth '; {a: 'module. Exports' =' pointing to other memory '; // exports = 'pointing to other memory '; // exports //test.js const a = require('/koala'); Console. log(a) // prints as {a: 'Programmer growth refers to north oh oh '}Copy the code

Looking at the printout of the code above, you should get something like this:

Module. Exports exports to memory blocks, not exports.

Exports is only a reference to module.exports, which assists the latter in adding content. It’s better to think about it in memory.

Here’s an example from the official website

Take a look at the official documentation for exports apps

We often see this written:

exports = module.exports = somethings
Copy the code

The above code is equivalent to:

module.exports = somethings
exports = module.exports
Copy the code

Module. exports disconnects from module.exports when pointing to a new object. Exports = module.exports; exports = module.exports

A bit of advice for use

Module. exports is also recommended (see the following example)

Node.js considers each file to be a separate module. If your package has two files, let’s say “A.js” and “b.js”, and then “B.js” wants to use “A.js” functions, “A.js” must expose those functions by adding attributes to exports objects:

// a.js
exports.verifyPassword = function(user, password, done) { ... }
Copy the code

When this is done, all objects requiring “a.js” get an object with the “verifyPassword” function property:

// {verifyPassword: function(user, password, done) {// verifyPassword: function(user, password, done) { }}Copy the code

However, what if we wanted to expose this function directly, rather than having it as a property of some object? We could override exports to do this, but we must not treat it as a global variable:

// a.js
module.exports = function(user, password, done) { ... }
Copy the code

Notice that we are referring to “exports” as a property of the Module object. The distinction between “module.exports” and “exports” is an important one, and one that often frustrates newcomers to Node.js.

Join us and learn!Node learning exchange group

If the number of ac group reaches 100, you cannot join the group automatically. Please add the wechat id of the group assistant: [coder_qi] Note node, you will be automatically added to the group.