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的模块,但是编译打包后的文件体积可能很大
AMD
AMD规范其实只有一个主要接口 define(id?,dependenies?,factory),它要在声明模块的时候指定所有的依赖dependenies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置。define("module",["dep1","dep2"],function(d1,d2){ return someExportedValue; }); requie(["module","../file"],function(module,file){ ... });
优点:
- 适合在浏览器环境中异步加载模块
- 可以并行加载多个模块
缺点: - 提高开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅。(定义模块的时要把所有的依赖模块都罗列一遍,而且要做形参传递进去)
- 对于预先下载依赖的模块,提前执行了,如果是一个模块依赖其他十个模块,每个模块都执行一遍,性能消耗不容忽视。
- 为解决用到的模块才进行执行而部分兼容Modules/Warppings的鞋写法,但是这不符合通用的模块化思维方式,是一个妥协的实现
实现: - RequireJS
- curl
CMD
CMD规范和AMD规范很相似,尽量保持简单,并与CommonJS和Node.js的Modules/Warpping保持极大的兼容。define(function(require,exports,module) { var $ = require("jquery"); var spinning = require("../spinning"); exports.doSomething = .. module.exports = ... })
优点:
- 依赖就近,延迟执行
- 可以很容易在Node.js中运行
缺点: - 依赖SPM打包,模块的加载逻辑偏重
实现: - Sea.js
- coolie
ES6 模块
ecmaScript6 标准增加了javascript语言层面的模块体系定义。es6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行中确定这些东西。import "jquery"; export function doStuff() {} module "localModule" {}
优点:
- 容易进行静态解析
- 面向未来的EcmaScript 标准
缺点: - 原生浏览器还没有实现这个标准
- 全新的命令字,新版的node.js才支持
实现:
Babel
参考文章: