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';
参考
- AMD 规范
- Javascript模块化编程(二):require.js的用法
- amd和cmd规范的区别
- cmd官方规范
- amd官方规范
- AMD , CMD, CommonJS,ES Module,UMD
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1249118795@qq.com