Front-end modularity (iii): COMMONJS specification

Source: Internet
Author: User

1 Overview

The COMMONJS definition of the module is very simple, mainly divided into module definition, module reference and module identification. The Nodejs module system follows the COMMONJS specification. But node in the implementation is not exactly in accordance with the COMMONJS specification implementation, but the module specification has a certain trade-offs. Below, we combine node to gain insight into the COMMONJS specification.

2 module Definition

The COMMONJS specification stipulates that a file is a module that uses the module variable to represent the current module. Node provides a build function for the module inside it. All modules are instances of module. The instance code is as follows:

function Module (ID, parent) {  this. id = ID;    this. Exports = {};   this. Parent = parent;    This NULL ;    This false ;   this. Children == Module; var New Module (filename, parent);

Inside each module, there is a module object that represents the current module. It has the following properties:

    • The identifier for the module.id module, usually a module file name with an absolute path.
    • The file name of the module.filename module with an absolute path.
    • module.loaded Returns a Boolean value that indicates whether the module has finished loading.
    • module.parent Returns an object that represents the module that called the module.
    • Module.children Returns an array that represents the other modules to be used by the module.
    • The module.exports initial value is an empty object {}, which represents the interface that the module outputs externally.

2.1 module.exports Properties

The Module.exports property represents the external output interface of the current module, and the other file loads the module, essentially reading the module.exports variable.

For example, we define the Funa method in the Modulea.js file and expose the method with the Module.exports variable, the instance code is as follows:

// Modulea.js Module.exports.funcA function () {  Console.log (' This is modulea! ' );}

Then, with the introduction of the Modulea module loaded in the Moduleb module, you can use the Funa method, as shown in the example code:

// Moduleb.js var a = require ('./modulea '); A.funca (); // print ' This is modulea! '

2.2 Exports variables

For convenience, node provides a exports variable for each module, pointing to Module.exports. Inside the module is probably this:

var exports = module.exports={};

You can add methods to the exports object when the external output module interfaces.

// A.js var funa=function() {Console.log (' This is Module a! ') );}; Exports.funa=funa; // equivalent to Module.exports.funa=funa;

Exports assignment is actually to module.exports this empty object to add MyName property, why is to add properties to exports, not directly exports= Funa it?

Because, exports is a reference to the module.exports. If you assign a value directly to a exports instead of adding a property, exports will no longer point to module.exports. When exports is changed, Module.exports will not be changed, and when the module is exported, the actual export execution is module.exports, not exports. For example, change a.js to:

// A.js var funa=function() {Console.log (' This is Module a! ')  =funa;

This is not valid. Because the front is by adding properties to exports, and now exports points to the memory has been modified, exports and module.exports no longer point to the same piece of memory, that is, Module.exports point to the block of memory did not make any changes, is still an empty object {}, so the Funa method output is not valid.

If you feel that module.exports and exports are difficult to distinguish, personal advice can be used all module.exports to deal with all situations and minimize the chance of making mistakes.

3 Module Reference

The basic function of the Require function is to read in and execute a JavaScript file and then return the module's exports object. When we get the module with require (), node finds the corresponding module based on Module.id and returns the module. Exports, so that the output of the module is realized.

The Require function uses a parameter that can have the file name of the module with the full path, or the module name.

If, there are three files: one is a.js (storage path: Home/a.js), one is b.js (storage path: Home/user/b.js), and the other is c.js (storage path: home/user/c.js). We refer to the three modules in the A.js file, the example code is as follows:

var httpmodule=require (' HTTP '); // load the Service module HTTP with "module name" var b=require ('./user/b '); // load file with relative path B.js var b=require ('.. /home/user/c '); // loading files with absolute path c.js

4 Module Identification

The module identifier is the argument passed to the Require method, which must conform to the string named by the small hump, or the. 、.. The relative path at the beginning, or the absolute path, the default file name suffix. js. In the node implementation, it is based on such an identifier for the module lookup, if not found that the specified module will be an error.

Depending on the format of the parameter, the Require command goes to different paths to find the module file. The load rules are as follows:

(1) If the argument string starts with "/", it means that a module file is loaded in the absolute path. For example, require ('/home/marco/foo.js ') will load/home/marco/foo.js.

(2) If the argument string begins with "./", it means that a module file is loaded in a relative path (as opposed to the location of the current execution script). For example, require ('./circle ') will load the circle.js of the same directory as the current script.

(3) If the argument string does not start with "./" or "/", it means that a default supplied core module (located in the system installation directory of node) is loaded, or an installed module (global or partial) that is located in the Node_modules directory at all levels.

For example, the script/home/user/projects/foo.js executes the require (' bar.js ') command, and node searches for the following files in turn.

/usr/local/lib/node/bar.js/home/user/projects/node_modules/bar.js/home/user/node_modules/bar.js/home/ Node_modules/bar.js/node_modules/bar.js

The purpose of this design is to enable different modules to localize the modules they depend on.

(4) If the argument string does not start with "./" or "/" and is a path, such as require (' example-module/path/to/file '), the location of the Example-module is first found, and then it is the parameter to find the subsequent path.

(5) If the specified module file is not found, node tries to add. js,. JSON,. Node to the file name, and then searches for the. js pieces are parsed in a text-formatted JavaScript script file, and the. json file is parsed in JSON format. The node file will be parsed with the compiled binary file.

(6) Use the Require.resolve () method if you want the exact file name to be loaded by the Require command.

Commonjs is synchronous, meaning that you want to invoke the method in the module, you must first load the module with require. This is not a problem for server-side Nodejs, because the module's JS files are on the local hard disk, the CPU read time is very fast, synchronization is not a problem. But if it's a browser environment, load the module from the server. The loading of the module will depend on the speed of the network, and if synchronization is used, the page may get stuck when it is unstable, and this must be done with asynchronous mode. So, there's the AMD solution. Next we begin to introduce the AMD specification of the modular specification;

Reference links

[1] Https://en.wikipedia.org/wiki/CommonJS

[2] Https://nodejs.org/api/modules.html#modules_modules

[3] Http://javascript.ruanyifeng.com/nodejs/module.html#toc2

Front-end modularity (iii): COMMONJS specification

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.