• Core operating Principles
    • Module Resolve procedure
    • Module Object
    • Module Wrapper
    • Cache
    • Cycle reference

Core operating Principles

Module Resolve procedure

test.js

require('x')
Copy the code
  1. Return if x is a Node core module (e.g. HTTP,zlib, etc.), otherwise continue
  2. Follow the Paths property of the Module object recursivelynode_modulesError(‘MODULE_NOT_FOUND’) is raised if the module exists in the folder up to the root directory.
  3. X is the path (e.g. /path/to/file)
    • Try LOAD_AS_FILE (e.g..js,.json,.node), continue if no
    • Try LOAD_AS_DIR (such as package.json in folder), if no Error is raised (‘MODULE_NOT_FOUND’)

LOAD_AS_FILE:

  1. .js
  2. .json
  3. .nodeFile (compiled binary Node plug-in)

LOAD_AS_DIR:

  1. X/package.jsonAs the module entry file
  2. index.js
  3. index.json
  4. index.node

Module object

Module {
  id: '. '.exports: {},
  parent: null.filename: '/Users/wl/Sites/myapp/node-learning/src/module/index.js'.loaded: false.children:
   [
	   Module
	   {
		   id: '/Users/wl/Sites/myapp/node-learning/src/module/a.js'.exports: [Object].parent: [Circular],
		   filename: '/Users/wl/Sites/myapp/node-learning/src/module/a.js'.loaded: true.children: [Array].paths: [Array]}],paths:
   [
		'/Users/wl/Sites/myapp/node-learning/src/module/node_modules'.'/Users/wl/Sites/myapp/node-learning/src/node_modules'.'/Users/wl/Sites/myapp/node-learning/node_modules'.'/Users/wl/Sites/myapp/node_modules'.'/Users/wl/Sites/node_modules'.'/Users/wl/node_modules'.'/Users/node_modules'.'/node_modules']}Copy the code
  • idThe module id. Usually a module fileabsolutePath, the main module is usually.
  • exportsThe module exports objects. Exports refers to module.exports
  • parentThe parent module. The dependent module
  • filenameModule file name. Usually withidThe same
  • loadedModule loading status. Whether the execution is complete
  • childrenSon module. Dependency modules
  • pathsThe module finds an array of paths.

Module Wrapper

Mainly by the following two considerations

  • Restrict top-level variables defined in a module to the method (wrapper, or module) level to prevent contamination of the global environment

Note: It is recommended to enable ‘use strict’ mode to prevent defining global variables

  • The incomingmodule.requireIt helps to implement the node modularity mechanism
(function(exports, require, module, __filename, __dirname) {
	// Module code
});
Copy the code

Cache

In a Node context, requiring the same file twice usually returns exactly the same two object references. Unless the factory function is returned with a higher-order function.

Cycle reference

Because node packages depend on each other, circular references are more likely to form, and Node uses its caching mechanism to avoid infinite loops. Such as

index.js

const prefix = 'Main module:'
const a = require('./a.js')

console.log(prefix, a)  // {a:2}
console.log(prefix, require.main === module)
console.log(module)
Copy the code

a.js

'use strict'
const prefix = 'MODULE A:'
module.exports = {a:1}
const b = require('./b.js')
console.log(prefix, b)  // {b:1}
module.exports = {a:2}
console.log(prefix, require.main === module)
Copy the code

b.js

const prefix = 'B module:'
module.exports = {b:1}
const a = require('./a.js')
console.log(prefix, a) // {a:1}
console.log(prefix, require.main === module)
Copy the code

As above. When B.js references A.js, to avoid an infinite loop, the exported object is referenced by B.js in the incomplete copy of A.js (which I believe is all the code before require(‘./b.js’), but is not specifically stated in the official documentation)