什么是 CommonJs 、UMD、CMD、AMD

3,178 阅读4分钟

《什么是 CommonJs》 

**CommonJs**是一种 JavaScript 语言的模块化规范,它通常会在服务端的 Nodejs 上使用。项目是由多个模块组成的,模块和模块之间的调用,需要各个模块有相同规范的 API,这样一来在使用的过程中不会有那么多的学习成本,并且对于单个模块来说是类聚的。 

CommonJs 的模块化规范中,每一个文件就是一个模块,拥有自己独立的作用域、变量、以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。require 方法用于加载模块。

 CommonJS 的优点在于: 

     代码可复用于 Node.js 环境下井运行,例如做同构应用: 

     通过 Npm 发布的很多第三方模块都采用了 CommonJS 规范。 

CommonJS 的缺点在于: 

      这样的代码无法直接运行在浏览器环境下,必须通过工具转换 成标准的 ES5。 

CommonJS 还可以细分为 CommonJSl 和 CommonJS2,区别在于 CommonJSl 只能通过 exports . XX = XX 的方式导出,而 CommonJS2 在 CommonJSl 的基础上加入了 module.exports = XX 的导出方式。 CommonJS 通常指 CommonJS2。 

模块化规范给项目带来极大的好处,在业务复杂,模块众多的大型项目中,开发者都遵循相同的规则来开发各自的模块,他们通过规范来约束模块的定义,大家不需要太多的沟通或者大量的文档来说明自己的模块使用规则,成千上万的模块就这样生产,并能够容易的使用。它的意义不仅是让模块看起来很规范,在合作开发、社区中传播中也起到了重大的作用。 

 什么是【UMD】 

UMD 叫做通用模块定义规范(Universal Module Definition)。也是随着大前端的趋势所诞生,它可以通过运行时或者编译时让同一个代码模块在使用 CommonJs、CMD 甚至是 AMD 的项目中运行。未来同一个 JavaScript 包运行在浏览器端、服务区端甚至是 APP 端都只需要遵守同一个写法就行了。

 它没有自己专有的规范,是集结了 CommonJs、CMD、AMD 的规范于一身,我们看看它的具体实现: 

 不难发现,它在定义模块的时候回检测当前使用环境和模块的定义方式,将各种模块化定义方式转化为同样一种写法。它的出现也是前端技术发展的产物,前端在实现跨平台的道路上不断的前进,UMD 规范将浏览器端、服务器端甚至是 APP 端都大统一了,当然它或许不是未来最好的模块化方式,未来在 ES6+、TypeScript、Dart 这些拥有高级语法的语言回代替这些方案。 

 什么是【CMD】 

CMD 叫做通用模块定义规范(Common Module Definiton),它是类似于 CommonJs 模块化规范,但是运行于浏览器之上的,关于模块化的好处我们在 CommonJs 篇文章中我们了解过。它是随着前端业务和架构的复杂度越来越高运用而生的,来自淘宝玉伯的 SeaJS 就是它的实现。

CMD 规范尽量保持简单,并与 CommonJS 的 Modules 规范保持了很大的兼容性。通过 CMD 规范书写的模块,可以很容易在 Node.js 中运行。在 CMD 规范中,一个模块就是一个文件。格式如下:

 具体用法如下: 

CMD 规范拥有简单、异步加载脚本、友好的调试并且兼容 Nodejs,它的确在开发过程中给我们提供了较好的模块管理方式。 

 什么是【AMD】 

AMD 叫做异步模块定义规范(Asynchronous Module Definition),它是 CommonJs 模块化规范的超集,但是运行于浏览器之上的,关于模块化的好处我们在 CommonJs 篇文章中我们了解过。AMD 的特点就和它的名字一样,模块的加载过程是异步的,它大大的利用了浏览器的并发请求能力,让模块的依赖过程的阻塞变得更少了。requireJs 就是 AMD 模块化规范的实现。 

AMD 作为一个规范,只需定义其语法 API,而不关心其实现。AMD 规范简单到只有一个 API,即 define 函数: 

 具体用法如下: 

它看起来似乎和 CMD 差不多,不过在实现上还是有一定的差异,它们各有优缺点,我们未来会专门对这些模块化规范做对比。