Front-end modular: CommonJS,AMD,CMD,ES6

Modularized development can improve code reuse rate and facilitate code management. Usually a file is a module with its own scope, exposing only specific variables and functions. Popular JS modular specifications include CommonJS, AMD, CMD and ES6 module systems. See Teacher Ruan Yifeng’s article module-loader. First, the CommonJS

Node.js is a major practitioner of the commonJS specification and has four important environment variables to support modular implementations: Module, exports, require, global. Module. exports defines the interface for the current module’s exports (not recommended), and requires loads the module.

Math.js var basicNum = 0; function add(a, b) { return a + b; } module.exports = {// add: add, basicNum: basicNum}

Js var math = require(‘./math’); math.add(2, 5);

Var HTTP = require(‘ HTTP ‘); http.createService(…) .listen(3000); Copy the code

CommonJS loads modules synchronously. On the server side, the module files are stored on local disk and are very fast to read, so this should not be a problem. However, on the browser side, it is more reasonable to use asynchronous loading for network reasons. AMD and require.js

The AMD specification uses asynchronous loading of modules, which does not affect the execution of subsequent statements. All statements that depend on this module are defined in a callback function that will not run until the load is complete. Here is an introduction to implement the modularization of the AMD specification with require.js: specify the reference path with require.config(), define the module with define(), and load the module with require().

First we need to import the require.js file and an entry file main.js. Configure require.config() in main.js and specify the base module to use in the project.

/** 网页中引入require.js及main.js **/

{baseUrl: “js/lib”, paths: {“jquery”: // server /lib/jquery.min. Js “underscore”: “underscore. Min “,}}); // Server /lib/jquery.min. // require([“jquery”,”underscore”],function($,_){// some code here}); require([“jquery”,”underscore”],function($,_){// some code here}); Copy the code

When referencing modules, we place the module name in [] as the first argument to reqiure(); If we define modules that themselves depend on other modules, we need to place them in [] as the first argument to define().

Math.js module define(function () {var basicNum = 0; var add = function (x, y) { return x + y; }; return { add: add, basicNum :basicNum }; }); // Define ([‘underscore’],function(_){var classify = function(list){ _.countBy(list,function(num){ return num > 30 ? ‘old’ : ‘young’; })}; return { classify :classify }; })

// Reference the module, put the module in []

require([‘jquery’, ‘math’],function((“#sum”).html(sum);

});

Copy the code

CMD and sea-.js

Require.js loads and executes the code in the module when it declares a dependent module:

define([“a”, “b”, “c”, “d”, “e”, “f”], function(a, b, c, d, e, If (false) {if (false) {if (false) {if (false) {if (false) {if (false) {if (false) {if (false) {if (false) {if (false) {if (false)}}); Copy the code

CMD is another JS modularization solution, which is similar to AMD, except that AMD advocates relying on front-loading and up-front execution, while CMD advocates relying on nearby and delayed execution. This specification was actually created during the promotion of Sea-js

AMD writing / * * * * / define ([” a “, “b”, “c”, “d”, “e”, “f”], function (a, b, c, d, e, F) {// all modules that need to be used are declared and initialized first. If (false) {// do something ()}});

Define (function(require, exports, module) {var a = require(‘./a’); // declare a.dosomething () if needed; if (false) { var b = require(‘./b’); b.doSomething(); }});

Math.js define(function(require, exports, module) {var $= require(‘jquery.js’); var add = function(a,b){ return a+b; } exports.add = add; }); Seajs. use([‘math.js’], function(math){var sum = math.add(1+2); }); Copy the code

Fourth, the ES6 Module

ES6, on the level of language standards, implements module functions, and implements them quite simply, aiming to become a common module solution for browsers and servers. Its module functions are mainly composed of two commands: export and import. The export command is used to specify the external interface of a module, and the import command is used to input functions provided by other modules.

Math.js **/ var basicNum = 0; var add = function (a, b) { return a + b; }; export { basicNum, add };

/** reference module **/ import {basicNum, add} from ‘./math’; function test(ele) { ele.textContent = add(99 + basicNum); } Duplicate code

As shown in the example above, when using the import command, the user needs to know the name of the variable or function to be loaded. In fact, ES6 also provides the export default command, which specifies the default output of the module. The corresponding import statement does not need curly braces. This is also closer to ADM’s citation style.

Export default {basicNum, add}; export default {basicNum, add}; // import math from ‘./math’; function test(ele) { ele.textContent = math.add(99 + math.basicNum); } Duplicate code

ES6 modules are not objects, and the import command is statically analyzed by the JavaScript engine. The module code is introduced at compile time, rather than loaded at run time, so conditional loading cannot be implemented. Because of this, static analysis is possible. 5. Differences between ES6 module and CommonJS module

  1. The CommonJS module prints a copy of the value, the ES6 module prints a reference to the value.

    The CommonJS module outputs a copy of the value, meaning that once a value is output, changes within the module do not affect that value. ES6 modules operate differently from CommonJS. When the JS engine statically analyzes a script, it generates a read-only reference to the module load command import. When the script is actually executed, it will be evaluated in the loaded module based on the read-only reference. In other words, the IMPORT of ES6 is a bit like the “symbolic link” of Unix systems, where the original value changes and the import load value changes with it. Therefore, ES6 modules are referenced dynamically and do not cache values. Variables in modules are bound to the module in which they are located.

  2. The CommonJS module is run time loaded, and the ES6 module is compile time output interface.

    Runtime loading: CommonJS modules are objects; That is, the entire module is loaded on input, an object is generated, and methods are read from that object. This loading is called “runtime loading.”

    Compile-time loading: ES6 modules are not objects, but are output code explicitly specified through the export command and static commands when importing. That is, when you import, you can specify that an output value is loaded instead of the entire module, which is called “compile-time loading.”

CommonJS loads an object (that is, the module.exports property) that is generated only after the script runs. An ES6 module is not an object, and its external interface is a static definition that is generated during the code static parsing phase.