Analysis of loading rules of require method in Node.js (code demonstration)

require method loading rules

The parameters of the require method are also called module identifiers.

There are three types of module identifiers:

  • The module name of the core module, in non-path form, such as require('http')

  • The module name of the third-party module, in non-path form, such as require('art-template')

    • All third-party modules are downloaded through npm

    • When you use it, you can load it by discussing require (name)

    • It is impossible for any third-party module to have the same name as the core module , otherwise there will be conflicts

  • Modules written by users themselves, path form, such as require('../xxx')


1. Load from the cache first

Code demo:

main.js file

require('./a');
let fn = require('./b');
console.log(fn);

a.js file

console.log('a被加载了');
let fn = require('./b')
console.log(fn);

b.js file

console.log('b被加载了');

module.exports = function () {
    
    
  console.log('hello');
}

The result of executing main.js:

a被加载了
b被加载了
[Function]
[Function]

The result is not that "b is loaded" will be output twice as we imagined, but only once. The output "b is loaded" is output in the a.js file, but the main.js file is not output

Since b.js has been loaded in a.js
, the code in b.js will not be executed repeatedly in main.js, it will only get the value exported in b.js.
The purpose of this is to avoid repeated loading To improve module loading efficiency

requireThe method has two functions

  • Load the file module and execute the code in it
  • Get the interface object exported from the loaded file module

require()Loading mechanism is loaded again in the module, node will be cached, and the second would not be met if the implementation of the code inside again, but will the in-memory cache of module.exports take over . So the function of the second load is to get the exported value or object inside . The purpose of this is to avoid repeated loading and improve the efficiency of module loading .


2. Load the core module

The essence of the core module is also a file, but it has been compiled into a binary file and can be directly searched by name.


3. Load the module written by the user (path form)

Use require(路径)to load, where the path has the following forms

  • ./xxx
  • ../xxx
  • /xxxHere /represents the disk root directory of the current file module belongs, rarely used
  • Use absolute paths, such as D:\code\frontend\nodeProject\test.js(almost no use)
  • .jsThe suffix name can be omitted, but ./or ../cannot be omitted
  • node will find the corresponding module according to the path

4. Load third-party modules

We download all third-party modules through npm, and load them through require('package name') when using them. Note that in which directory the npm install command is executed, the node_modules directory will be generated in which directory. The name of the third-party package cannot be the same as the name of the core module. Neither is the core module, nor is it a path in the form of modules, we search by following the path, we installed a first npm install art-template, followed by the third-party modules art-template, for example:

Directory structure: we use it in the main.js file let template = require('art-template');to load
Insert picture description here

4.1 Rule One

  • First find the node_modules directory in the directory where the current file (main.js) belongs
  • Findnode_modules/art-template
  • Find the node_modules/art-template/package.jsonfile, find the mainattribute in this file , the value of main is the entry file of the module. For example art-template, the value of main in package.json in the directory is index.js. If we install another jquery, require('jquery')we will search node_modules/jquery/package.jsonfor the main when we use it and find that dist/jquery.jsit is the entry file of the jquery module
  • Then load and use this third-party package, in fact the final file is loaded
    Insert picture description here

4.2 Rule Two

According to the situation mentioned above, the loading is relatively smooth. But what if the package.json file does not exist, or the entry file specified by main does not exist?

The answer is: node will look for index.js in this directory, which means index.js will be used as a default entry file alternative.

Let's test it: Create a new aaa folder in the node_modules directory as a module, and create a new foo.js, index.js, and package.json file in the aaa folder. Then load the reference aaa module in the main.js file. The code in each file is shown in the figure:

Insert picture description here
Execution main.js, node main.js, the output foo.js被加载了is: . The reason is that the value of main we specified in the package.json file is foo.js. When the aaa module is loaded, node will look for foo.js.

Next, we set the main attribute in the package.json file to empty, as shown in the figure.
Insert picture description here
Execute main.js again. I believe everyone is clear about the result index.js被加载了this time . The result is , because in this case node will look for the directory Index.js.

4.3 Rule Three

  • If any of the above conditions are not true and it is not found in the node_modules directory in the current directory, it will enter the upper-level directory of node_modules to search, and the specific rules for finding modules are the same as above (rules 1 and 2).
  • If the upper level is not there yet, continue to the upper level to find the root directory of the disk. If it is not found in the root directory of the disk, an error will be reportedCannot find module xxx

to sum up

//bolg目录下有两个子目录,a目录和 b目录
blog目录

  -a目录
    -node_modules目录
    -foo.js文件

  -b目录
    -test.js
      ①在b目录中的test.js文件中想要加载a目录中的foo.js需要通过相对路径 require('../a/foo');
      ②在b目录中的test.js目录中是无法直接通过模块名加载a目录中的node_modules目录下的模块的,
      但是依然可以通过相对路径来加载 require('../a/node_modules/xxx')
      
      写这么一长串的路径很难受,因此node就搞出了上边总结的那些规则来简化代码的编写

However, then again, one of our projects will only have one node_modules, which is placed in the project root directory (whoever has nothing to do with multiple node_modules directories), and the code in all subdirectories in the project can be loaded into The corresponding module.

But we have to know the rules in order to know these even know why!


Further reading

https://blog.csdn.net/weixin_43974265/category_10692693.html

Guess you like

Origin blog.csdn.net/weixin_43974265/article/details/111828794