Node follows the CommonJS specification. In order to avoid global naming conflicts and overwriting function or variable names of the same name, the concept of module is proposed and implemented internally. Each JS is an independent Modlue, and internal variables and methods are private. If you want to import your own module, use the module keyword. If you want to import other modules, use require.
After reading this article, you will know:
-
- What does Nodejs do when require
-
- Module module.export is a module module
-
- Why can be used directly
module
module.exports
And what is the direct relationship between them? Why can be used directly__dirname
__filename
?
- Why can be used directly
-
- The problem with circular references
A case in point
Q: What happens when you create a new a.js that says require(“)?
- A complains
The argument 'id' must be a non-empty string. Received
The error message is written in the nodeJS source codeSo require(“) directly goes to the require method on the Modlue prototype inside NodeJS, and checks whether the path passed in is empty. If it is empty, an error is reported and execution stops.
Let’s create a new b.js that triggers an error. When we run it, we’ll find that Node wraps a layer of javascript files like this:
(function (exports, require, module, __filename, __dirname) { var a = ;
- Nodejs imports exports,require, modlue as arguments, so it can be used directly when writing js.
- So we can just print these variables and see what their relationship is
// console.log(module);
// Module {
// id: '.',
// exports: {},
// parent: null,
// filename:
// '/Users//development//nodeFromStratch/005.require.js',
// loaded: false,
// children: [],
// paths:
// [ '/Users//development//nodeFromStratch/node_modules',
// '/Users//development//node_modules',
// '/Users//development//node_modules',
// '/Users//development/node_modules',
// '/Users//node_modules',
// '/Users/node_modules',
// '/node_modules' ] }
Copy the code
- Find a
Modlue
There’s an attribute inside that object, exports is {} so that explains why we do that when we import variables or functions, okay
var url = "test.com";
function logUrl(message) {
//do something
console.log("log method invoked");
console.log(message);
}
module.exports.log = logUrl;
module.exports.SomeUrl = url;
Copy the code
- The stack information for the call from bottom up is:
startup
->Module.runMain
->Module._load
And so on.
//b.js var a =; Function (exports, require, module, __filename, __dirname) {var a =; ^ SyntaxError: Unexpected token ; at new Script (vm.js:80:7) at createScript (vm.js:274:10) at Object.runInThisContext (vm.js:326:10) at Module._compile (internal/modules/cjs/loader.js:664:28) at Object.Module._extensions.. js (internal/modules/cjs/loader.js:712:10) at Module.load (internal/modules/cjs/loader.js:600:32) at tryModuleLoad (internal/modules/cjs/loader.js:539:12) at Function.Module._load (internal/modules/cjs/loader.js:531:3) at Function.Module.runMain (internal/modules/cjs/loader.js:754:12) at startup (internal/bootstrap/node.js:283:19)Copy the code
The principle of NodeJS requirejs
- When we write a nodeJS file. From Nodejs’ point of view, here’s what he did:
Function require() {var modlue = {exports: {}... // omit other attributes and methods}; (function(exports, modlue) {var a = 1; modlue.exports.a = 1; })(modlue, modlue.exports); return modlue.exports; } console.log(require()); //{ a: To illustrate the behavior, imagine this implementation of require(), which is quite similar to what is actually done by require(): function require(/* ... */) { const module = { exports: {} }; ((module, exports) => { // Module code here. In this example, define a function. function someFunc() {} exports = someFunc; // At this point, exports is no longer a shortcut to module.exports, and // this module will still export an empty default object. module.exports = someFunc; // At this point, the module will now export someFunc, instead of the // default object. })(module, module.exports); return module.exports; }Copy the code
How is require used? Where is it used in the file?
- Module. Exports () : module. Exports () : module. Exports () : module. Module. Exports = require/module. Exports = module.
And require can theoretically be used anywhere in the code, even without assigning to a variable, such as:
require('./a')(); Var data = require('./a').data; Var a = require('./a')[0]; // the a module exports an arrayCopy the code
You can ignore modularity and use require as a node built-in global function, and its arguments can even be expressions
require(process.cwd() + '/a'); orCopy the code
How does NodeJS solve the problem of circular references? According to the official websiteunfinished copy
- A. require B. apply b. apply C. require D. require
//a.js var b = require("./b"); console.log("in a.js get b is :" + b.b); module.exports.a = "this is a"; //in b.js get a is :undefined // in a.js get abis :this is b // b.js var a = require("./a"); console.log("in b.js get a is :" + a.a); module.exports.b = "this is b"; //in b.js get a is :undefined //in a.js get abis :this is b // //a.js module. Exports. A = "this is a"; var b = require("./b"); console.log("in a.js get b is :" + b.b); //b.js module.exports.b = "this is b"; var a = require("./a"); console.log("in b.js get a is :" + a.a); // in. Js get a is :this is a in. Js get b is :this is b // in. Js get b is :this is B in b.js get a is :this is aCopy the code
conclusion
-
- Why nodeJS can use Module? Because nodeJS wraps a layer, it passes in parameters like module,require, etc
- What is the relationship between Modlue and Module. exports? Var module = {exports: {}
- So don’t write exports.xx = {}, which overwrites references, say
modlue.exports.xxKey = xxValue
modlue.exports.xxKey1 = xxValue1
ormodlue.exports = { key1: val1, key2:val2, ... }
- How does Node solve the problem of circular references? Avoid writing it or require it.
- Thanks for reading and hope it’s helpful.
reference
- Nodejs website
- Reqiure nojejs source node / – / blob/lib/internal/modules/CJS/helpers. Js# L16:3
- nodejs vm vm.runInThisContext