AMD CMD CommonJS

CommonJS

服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

require(“module”);
require(“../file.js”);
exports.doStuff = function() {};
module.exports = someValue;

优点:

  • 服务器端模块便于重用

  • NPM 中已经有将近20万个可以使用模块包

  • 简单并容易使用

缺点:

  • 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的

  • 不能非阻塞的并行加载多个模块

实现:

  • 服务器端的 Node.js

  • Browserify,浏览器端的 CommonJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积可能很大

  • modules-webmake,类似Browserify,还不如 Browserify 灵活

  • wreq,Browserify 的前身

AMD

Asynchronous Module Definition 规范其实只有一个主要接口 define(id?, dependencies?, factory),它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。

define(“module”, [“dep1”, “dep2”], function(d1, d2) {
return someExportedValue;
});
require([“module”, “../file”], function(module, file) { /* … */ });

优点:

  • 适合在浏览器环境中异步加载模块

  • 可以并行加载多个模块

缺点:

  • 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅

  • 不符合通用的模块化思维方式,是一种妥协的实现

实现:

  • RequireJS

  • curl

CMD

Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。

define(function(require, exports, module) {
var $ = require(‘jquery’);
var Spinning = require(‘./spinning’);
exports.doSomething = …
module.exports = …
})

优点:

  • 依赖就近,延迟执行

  • 可以很容易在 Node.js 中运行

缺点:

  • 依赖 SPM 打包,模块的加载逻辑偏重

实现:

  • Sea.js

  • coolie