模块规范CommonJS以及AMD、CMD

开发的时候,我们经常会把某些功能封装成可复用的模块。模块封装了功能,并且对外暴露一个API。随着Node.js的诞生和发展,JavaScript可以在服务端运行,同时客户端应用也越来越流行,JavaScript界产生了对优秀模块系统的需求。在JavaScript中定义模块的规范也随之产生。

一、CommonJS

CommonJS模块可以说是当前最流行的模块定义规范。相比于AMD,它的工作效率更高、语法更简单。
1.每个文件就是一个模块,有自己的作用域。每个模块内部,module变量代表当前模块,是一个对象,它的exports属性(即module.exports)是对外的接口。
2.module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。
3.为了方便,Node为每个模块提供一个exports变量,指向module.exports。
4.require命令用于加载模块文件。
特点

  • 没有回调函数
  • 同步加载,每个require语句会短暂阻塞代码的运行,直到模块加载完毕。不过这个加载不是通过网络加载,而是从内存或者文件系统中加载,所以这个过程很快。
  • 代码简单易懂
  • CommonJS模块不适合浏览器,因为浏览器的加载机制不支持同步。需要用打包工具把所有CommonJS模块打包成一个js文件。

二、AMD和CMD

AMD是RequireJS在推广过程中对模块定义的规范化产出。
对于依赖的模块,AMD是提前执行,CMD是延迟执行。不过 RequireJS从 2.0开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇as lazy as possible.

//CMD
define(function(require, exports, module) {   
   let a = require('./a'); 
   a.doSomething();
   ···
   let b = require('./b'); // 依赖可以就近书写   
   b.doSomething();
   ... 
})
// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { 
  // 依赖必须一开始就写好    
  a.doSomething()   
  ...
  b.doSomething()   
  ...
}) 

AMD 的API默认是一个当多个用,CMD的API严格区分,推崇职责单一。

拓展

目前所有的引擎都还没有实现import,在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require。这也是为什么在模块导出时使用module.exports,在引入模块时使用import仍然起效,因为本质上,import会被转码为require去执行。

你可能感兴趣的:(模块规范CommonJS以及AMD、CMD)