require problem in nodejs source code

Keywords: Javascript github

When you mention the module in nodejs, you will think of using require to add it to the reference module. After reading many blogs, the loading mechanism understands that my mind is always confused with the idea that every file will be'(export, require, module, _filename, _dirname)'.
// Source code for files
'n};'Wrap, naturally there's the require command in the file. I saw the source code of the module the other day. https://github.com/nodejs/nod...
The first few lines of module.js source code

const NativeModule = require('native_module');
const util = require('util');
const internalModule = require('internal/module');
const vm = require('vm');
const assert = require('assert').ok;
const fs = require('fs');
const internalFS = require('internal/fs');

First of all, it's confused. Is module.js just for require? Why use require to refer to other modules in the first place and get into a dead loop? Questions on some technical websites https://cnodejs.org/topic/58b... Although not very clear, but got some ideas, and then began to re-look at the source code, and start debugging, finally think clearly. So I want to write and record my whole process.

1. Where did the require s in the first few lines of module.js come from?

Write two JS files, a.js

const b = require('./b.js');

b.js

exports.done = false;

node executes a.js
The first js file is executed when the node starts first https://github.com/nodejs/nod...
This file defines the NativeModule for the first line in module.js. You can see the definition of NativeModule

function NativeModule(id) {
this.filename = `${id}.js`;
this.id = id;
this.exports = {};
this.loaded = false;
this.loading = false;

}

As you can see from the entry function startup

const Module = NativeModule.require('module'); that is to say, the module.js module is loaded.

In require function

NativeModule.require = function(id) {
if (id === 'native_module') {
  return NativeModule;
}
/..../
const nativeModule = new NativeModule(id);Newly build NativeModule object

nativeModule.cache();
nativeModule.compile();  //Main steps

return nativeModule.exports;

};

In compile

NativeModule.prototype.compile = function() {
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);   

this.loading = true;

try {
  const fn = runInThisContext(source, {
    filename: this.filename,
    lineOffset: 0,
    displayErrors: true
  });
  fn(this.exports, NativeModule.require, this, this.filename);

  this.loaded = true;
} finally {
  this.loading = false;
}

};

wrap wraps files

NativeModule.wrap = function(script) {
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};

NativeModule.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];

The require here is NativeModule.require

The next step is to execute the Module.runMain function, which goes into module.js, so module
The require that started in.js is NativeModule.require, which is not contradictory.

II. Implementation of a.js
When a.js is executed, it enters module.js through the runMain function of bootstrap_node.js

Module.runMain = function() {
// Load the main module--the command line argument.
Module._load(process.argv[1], null, true);
// Handle any nextTicks added in the first tick of the program
process._tickCallback();
};call Module._load Function, process.argv[1]by a.js


Module.runMain->Module._load->tryModuleLoad->module.load->Module._extensions['.js']->module._compile

In module._compile

var wrapper = Module.wrap(content); at this point, the wrap function of NativeModule is called to wrap a.js

Next

 var require = internalModule.makeRequireFunction.call(this);Will pass
 https://The makeRequireFunction function in github.com/node js/node/blob/master/lib/internal/module.js creates a require function.
  function require(path) {
  try {
  exports.requireDepth += 1;
  return self.require(path);
} finally {
  exports.requireDepth -= 1;
}

}
call.(this) Point the pointer to Module.prototype.require, so that the require in the head of a.js package is Module.prototype.require.

Module.prototype.require = function(path) {
return Module._load(path, this, /* isMain */ false);
};
require Will call Module._load To load other modules.

Requirement in a.js ('. / b.js') calls Module.prototype.require to load b.js.

This is the relationship of several require s.

New people write for the first time. If there are any mistakes, please correct them.

Posted by robstl70 on Thu, 11 Apr 2019 13:51:32 -0700