Introduction and information
Through the official API of Node.js, we can see that Node.js itself provides many core modules http://nodejs.org/api/. These core modules are compiled into binary files and can be obtained by requiring('module name'); the core module has the highest loading priority (it will be reflected when there is a module and the core module with the same name)
(This time we mainly talk about custom modules)
Node.js also has a type of module that is a file module, which can be a JavaScript code file (.js as the file suffix), a JSON format text file (.json as the file suffix), or an edited C/C++ file (.node as the file suffix);
The file module access method is accessed through require('/filename.suffix') require('./filename.suffix') requrie('../filename.suffix') and the file suffix can be omitted; starting with "/" is loaded with an absolute path, starting with "./" and starting with "../" means loading with a relative path, and starting with "./" means loading with a file in a directory of the same level,
The file suffix mentioned earlier can be omitted, the priority js file that Nodejs tries to load > json file > node file
Create a custom module
Take a counter as an example
The code copy is as follows:
var outputVal = 0; //Output value
var increment = 1; //Increment
/* Set output value*/
function seOutputVal (val) {
outputVal = val;
}
/* Set increment*/
function setIncrement(incrementVal){
increment = incrementVal;
}
/* Output*/
function printNextCount()
{
outputVal += increment;
console.log(outputVal);
}
function printOutputVal() {
console.log(outputVal);
}
exports.seOutputVal = seOutputVal;
exports.setIncrement = setIncrement;
module.exports.printNextCount = printNextCount;
Custom module sample source code
The focus of the example is exports and module.exports; it provides an external access interface. Let's call it to see the effect.
Calling custom modules
The code copy is as follows:
/*
A Node.js file is a module, which may be Javascript code, JSON, or compiled C/C++ extensions.
Two important objects:
require is to obtain modules from outside
exports exposes the module interface
*/
var counter = require('./1_modules_custom_counter');
console.log('First call to module [1_modules_custom_counter]');
counter.seOutputVal(10); //Set counting starting from 10
counter.setIncrement (10); //Set the increment to 10
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
/*
Require calls to the same module multiple times will not be loaded repeatedly
*/
var counter = require('./1_modules_custom_counter');
console.log('Second call module [1_modules_custom_counter]');
counter.printNextCount();
Custom mode call source code
Run it and find that both the methods exposed to the public through exports and module.exports can be accessed!
As you can see in the example, I get the module twice by requiring('./1_modules_custom_counter'), but after the second reference, I call the printNextCount() method does start from 60~~~
The reason is that node.js calls the same module multiple times through requirerequirequire and will not load repeatedly. Node.js will cache all loaded file modules according to the file name, so it will not be reloaded.
Note: Caching through filename refers to the actual file name, and it will not be considered different files because the incoming path is different.
There is a printOutputVal() method in the 1_modules_custom_counter file I created, which does not provide public access methods through exports or module.exports,
What happens if you directly access the 1_modules_load file?
The answer is: TypeError: Object #<Object> has no method 'printOutputVal'
Difference between exports and module.exports
Through the above example, both exports and module.exports are available for access! Since both can achieve the effect, there must be a little difference~~~ Let’s take an example!
The code copy is as follows:
var counter = 0;
exports.printNextCount = function (){
counter += 2;
console.log(counter);
}
var isEq = (exports === module.exports);
console.log(isEq);
2_modules_diff_exports.js file source code
Let's create a new 2_modules_diff_exports_load.js file and call it
The code copy is as follows:
var Counter = require('./2_modules_diff_exports');
Counter.printNextCount();
After calling, the execution result is as shown in the figure above
I output the value of isEq in the 2_modules_diff_exports_load.js file ( var isEq = (exports === module.exports); ), the returned true
PS: Note that there are three equal signs. If you don’t know what you are looking for the information yourself!
Don't rush to draw conclusions, change these two JS files to the corresponding codes of module.exports
The code copy is as follows:
//The modified 2_modules_diff_exports.js source code is as follows
var counter = 0;
module.exports = function(){
counter += 10;
this.printNextCount = function()
{
console.log(counter);
}
}
var isEq = (exports === module.exports);
console.log(isEq);
The code copy is as follows:
//The modified 2_modules_diff_exports_load.js file source code is as follows
var Counter = require('./2_modules_diff_exports');
var counterObj = new Counter();
counterObj.printNextCount();
After calling, the execution result is as shown in the figure above
I output the value of isEq in the 2_modules_diff_exports_load.js file ( var isEq = (exports === module.exports); ), and the returned false, which is inconsistent with the result obtained before!
PS: Don't use Counter.printNextCount(); to access, you will only get an error prompt
The API provides explanation
http://nodejs.org/api/modules.html
Note that exports is a reference to module.exports making it suitable for augmentation only. If you are exporting a single item such as a constructor you will want to use module.exports directly instead
exports is just an address reference to module.exports. nodejs will only export the pointer of module.exports. If the exports pointer has changed, it is just that exports are not pointing to module.exports, so they will not be exported again.
Refer to other understandings:
http://www.hacksparrow.com/node-js-exports-vs-module-exports.html
http://zihua.li/2012/03/use-module-exports-or-exports-in-node/
module.exports is the real interface, exports is just an auxiliary tool for it. The final return to the call is module.exports instead of exports.
All properties and methods collected by exports are assigned to Module.exports. Of course, there is a prerequisite for this, that is, module.exports itself does not have any attributes or methods.
If module.exports already has some properties and methods, the information collected by exports will be ignored.
exports and module.exports override
The above also basically understands the relationship and difference between exports and module.exports, but if exports and module.exports exist for both printNextCount() method, what is the result?
Call result
As can be seen from the results, there is no error, which means that it can be defined like this, but in the end module.exports overwrites exports
Although the result will not be error-produced, if you use it like this, there will inevitably be some problems in development.
1. It is best not to define module.exports and exports separately
2.NodeJs developers recommend module.exports to export objects, and exports to export multiple methods and variables.
other...
There are other methods provided in the API, so I won’t go into details. Based on the above example, you will know it by yourself by yourself as soon as you output it.
module.id
Returns the module identifier of type string, which is generally the fully parsed file name
module.filename
Returns a fully parsed file name of a string type
module.loaded
Returns a bool type, indicating whether the loading is completed
module.parent
Returns the module that references the module
module.children
Returns an array of all module objects referenced by this module