CommonJS, AMD, CMD, UMD 扫盲

参考1  参考2  参考3

CommonJS

  • CommonJS是服务器端模块的规范。Node.js采用了这个规范。
    这些规范涵盖了模块、二进制、Buffer、字符编码、I/O流、
    进程环境、文件系统、套接字、单元测试、服务器网关接口、
    包管理等。
  • 根据CommonJS规范一个单独的文件就是一个模块。
    加载模块使用require方法,该方法读取一个文件并执行,
    最后返回文件内部的exports对象。
  • CommonJS加载模块是同步的。
    像Node.js主要用于服务器的编程,加载的模块文件一般
    都已存在本地硬盘,所以加载起来比较快。
    不用考虑异步加载的方式,所以CommonJS规范比较适用。
    //模块定义 myModel.js
    
    var name = 'Byron';
    
    function printName(){
        console.log(name);
    }
    
    function printFullName(firstName){
        console.log(firstName + name);
    }
    
    module.exports = {
        printName: printName,
        printFullName: printFullName
    }
    
    //加载模块
    
    var nameModule = require('./myModel.js');
    
    nameModule.printName();

AMD Asynchronous Module Definition 异步模块加载机制

  • AMD是RequireJS在推广过程中对模块定义的规范化产物。
    AMD依赖前置,在定义模块的时候就要声明其依赖的模块。
    // AMD 默认推荐的是
    define(['./a', './b'], function (a, b) {
      a...
      b...
    })

CMD Common Module Definition 公共模块定义规范

  • CMD是SeaJS在推广过程中对模块定义的规范化产物。
    CMD推崇依赖就近,只有在用到某个模块的时候再去require 。
    // CMD
    define(function (require, exports, module) {
      var a = require('./a')
      a...
      var b = require('./b')
      b...
    })

UMD Universal Module Definition 通用模块定义

  • UMD是AMD和CommonJS的结合
    AMD是以浏览器为出发点的异步加载模块
    CommonJS是以服务器为出发点的同步加载模块
    所以人们想出了另一个更通用的模式UDM,
    来解决跨平台的问题。
    (function (root, factory) {  
        if (typeof exports === 'object') {
            // Commonjs  
            module.exports = factory();  
    
        } else if (typeof define === 'function' && define.amd) {  
            // AMD
            define(factory);  
    
        } else {  
            //  没有使用模块加载器的方式
            window.eventUtil = factory();  
        }  
    })(this, function() {  
        // module  
        return {  
            addEvent: function(el, type, handle) {  
                //...  
            },  
            removeEvent: function(el, type, handle) {  
    
            },  
        };  
    }); 

    根据jquery 源码提取。(支持amd、cmd、commonjs规范的模块加载)

      ;(function( global, factory ){
    
        "use strict";
    
        if ( typeof module === "object" && typeof module.exports === "object" ) {
    
            // For CommonJS and CommonJS-like environments where a proper window
            // is present, execute the factory and get jQuery.
            // For environments that do not have a window with a document
            // (such as Node.js), expose a factory as module.exports.
            // This accentuates the need for the creation of a real window.
            // See ticket #14549 for more info.
            module.exports = global.document ?
                factory( global, true ) :
                function( w ) {
                    if ( !w.document ) {
                        throw new Error( "jQuery requires a window with a document" );
                    }
                    return factory( w );
                };
        } else if (define && define.cmd) {
            define( function () {
                    return factory(global);
            } );
        } else {
            factory( global );
        }
    })( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
    
        // 核心逻辑代码...
    
        // 使代码支持 amd 模块加载
        if ( typeof define === "function" && define.amd ) {
            define( "jquery", [], function() {
                return jQuery;
            } );
        }
    
        return {
          add: function(a, b) { return a + b }
        }
    
    })