Modularity Overview

For a long time, JavaScript has had the idea of modularity, such as namespaces, which were popular in the early days of development, but JavaScript has never had a module system, which can break up a large program into small interdependent files and put them together in a simple way. Other languages have this functionality, such as Ruby’s require, Python’s import, and even CSS has @import, but JavaScript has no support for any of this, which is a huge barrier to developing large, complex projects. Prior to ES6, there were several module loading schemes developed by the community, the most important being CommonJS and AMD. After the release of ES6, the modular function — ES6 Module was realized on the level of language standard. It can replace CJS and AMD specifications as a common module solution for browsers and servers.

CommonJS

  • One module per file. If there are multiple exports, the last export is taken
  • Exports ={} or exports.xx =… Exposed to the module
  • Import modules using the require() method
  • Require () is executed synchronously
  • Can only be used in NodeJS environment, not browser

The sample

// a.js
let fn = function(msg){
  console.log(msg);
}
exports.printMsg = fn;
 
//b.js
const a=require('./a.js');
a.printMsg('hello CommonJS'); // hello CommonJS
Copy the code

AMD (Asynchronous Module Definition)

  • Using the define (…). Defining a module
  • Use the require (…). Loading a module
  • Dependencies are front-loaded and executed ahead of time
  • RequireJS is an implementation of AMD

The sample

// Module definition
/ * * *@param Id Module name. If null, the module name defaults to the name of the script requested by the module loader@param Dependencies The module depends on *@param Factory Factory function, the module initializes the execution function or object */
define(id,dependencies,factory)
 
// For modules, use require to load modules
require([module], callback);Copy the code

CMD (Generic module definition)

  • A file is a module
  • Using the define (…). Define a module (similar to AMD)
  • Use the require (…). Load a module (similar to AMD)
  • SeaJS is an implementation of CMD

The sample

define(function(require.exports.module){
  var a=require('./a');
  a.sayHello();
  var b=require('./b');// Rely on nearby writing;
  b.sayHello();
  / /...
});
Copy the code

UMD (Universal module Definition)

  • It can be used on the server side or the browser side

He did three main things:

  1. Check whether AMD is supported
  2. Check whether CJS is supported
  3. If none is supported, use global variables

His main code is as follows:

(function (root, factory) {
    // Correspond to the three steps above
    if (typeof define === 'function' && define.amd) {
        // 1. Check whether AMD is supported
        // If the define method is defined and the define method is an AMD specification, then the factory module entity is defined in the DEFINE method with the AMD specification
        define([], factory); // [] is a dependency, and factory is a module entity
    } else if (typeof exports= = ='object') {
        // 2. Check whether CommonJS is supported
        // exports is an object that runs in Node, CommonJS is supported, and module.exports is used to expose the entire module entity
        module.exports = factory();
    } else {
        // 3. If none is supported, use global variables
        // Browser globals (root = window)
        root.returnExports = factory();
  }
}(this.function () {
    // Module Defination
    var sum = function(x, y){
        return x + y;
    }
    var sub = function(x, y){
        return x - y;
    }
    var math = {
        findSum: function(a, b){
            return sum(a,b);
        },
        findSub: function(a, b){
            returnsub(a, b); }}return math;
}));
Copy the code

ES Module (ES6 Module)

  • Import the module using import
  • Export the module using export

The sample

// Export the module
export var a='123'; // Export variables
export function fn(){}; // Export the function
export default {name:'ann'.age:18} // Export objects; Export cannot export the object directly.
export class Myclass{} // Export class;
Copy the code

conclusion

The most significant difference between CMD and AMD is that AMD executes early, while CMD executes late and relies on proximity. AMD: the process of execution will be all the dependent module front execution, that is, their own code logic before all the execution; CMD: if require but the entire logic does not use the dependency or does not execute until the logic uses it. The difference between ES6 and CommonJS modules is that: 1. CommonJS outputs a copy of a value; The ES6 module outputs references to values; 2. CommonJS modules are loaded at runtime; The ES6 module is a compile-time output interface;

The ES6 module is designed to be as static as possible, so that the module dependencies, as well as the input and output variables, can be determined at compile time. Both CommonJS and AMD modules can only determine these things at runtime. For example, a CommonJS module is an object, and you have to look for object properties when you enter it. Because ES6 modules are loaded at compile time, static analysis is possible. With it, you can further expand JavaScript syntax by introducing features such as macros and type systems that can only be implemented with static analysis.

In addition to the benefits of static loading, ES6 modules have the following benefits.

  • No longer needUMDES6 module format will be supported by both servers and browsers in the future. This is already being done through various tool libraries.
  • In the future, the browser’s new apis will be available in module format and will no longer have to be global variables ornavigatorObject properties.
  • Objects are no longer required as namespaces (e.gMathObject), and in the future these functions could be provided through modules.