AMD、CMD、CommonJS以及UMD的简单对比

  1. AMD、CMD、CommonJS以及UMD的简单对比
    1. 一、AMD
  2. 三、CommonJS
  3. 四、UMD
  4. 五、ES module
  5. 参考

AMD、CMD、CommonJS以及UMD的简单对比

一、AMD

为浏览器环境设计的, 所以是异步模块加载定义的

  • 加载模块

AMD采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

   require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。

  • 定义模块

模块通过 define 函数定义在闭包中,格式如下:

define(id?: String, dependencies?: String[], factory: Function|Object)

id 是模块的名字,它是可选的参数。

dependencies 指定了所要依赖的模块列表,它是一个数组,也是可选的参数,每个依赖的模块的输出将作为参数一次传入 factory 中。如果没有指定 dependencies,那么它的默认值是 ["require", "exports", "module"]

factory 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值。

用例:

定义一个名为 myModule 的模块,它依赖 jQuery 模块:

define('myModule', ['jquery'], function($) {
    // $ 是 jquery 模块的输出
    $('body').text('hello world');
});
// 使用
require(['myModule'], function(myModule) {});

二、CMD

和AMD同样是异步加载

  • 加载模块

    分为三种:

    requirea(name);name为模块名

    require.async(name, callback);异步加载 ,callback为加载后执行函数

    require.resolve(name);不加载模块,仅仅将短串解析成完整路径

  • 模块定义

    分为define(factory)和define(name,deps,factory)

    // define(factory)
    define(function(require, exports, module) { 
      // 模块代码 
    }); 
    
    // define(name,deps,factory)
    define('hello', ['jquery'], function(require, exports, module) { 
      // 模块代码 
    }); 
  • 和AMD异同

    CMD 推崇依赖就近,AMD 推崇依赖前置

    // CMD
    define(function(require, exports, module) {   
        var a = require('./a')   
        a.doSomething()    
        var b = require('./b')   
        b.doSomething()    
        ... 
    })
    // AMD 
    define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好
        a.doSomething()
        ...
        b.doSomething()
        ...
    }) 

三、CommonJS

​ 以服务器为第一原则发展,同步加载

  • 加载

    const package = require('module-name')
  • 导出

    导出一个值

    module.exports = value

    导出多个值

    exports.a = 1
    exports.b = 2
    exports.c = 3

四、UMD

umd是CommonJS和AMD结合的产物,是一个跨平台的解决方案。

UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

五、ES module

// 报错1
export 1;
// 报错2
const m = 1;
export m;

// 接口名与模块内部变量之间,建立了一一对应的关系
// 写法1
export const m = 1;
// 写法2
const m = 1;
export { m };
// 写法3
const m = 1;
export { m as module };
// 类似于对象解构
// module.js
export const m = 1;
// index.js
// 注意,这里的m得和被加载的模块输出的接口名对应
import { m } from './module';
// 若是想为输入的变量取名
import { m as m1 }  './module';
// 值得注意的是,import是编译阶段,所以不能动态加载,比如下面写法是错误的。因为'a' + 'b'在运行阶段才能取到值,运行阶段在编译阶段之后
import { 'a' + 'b' } from './module';
// 若是只是想运行被加载的模块,如下
// 值得注意的是,即使加载两次也只是运行一次
import './module';
// 整体加载
import * as module from './module';

参考


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1249118795@qq.com