JS模块化标准CommonJS/AMD/CMD区别和详解

今天接到阿里的电话面试,面试中问到CommonJS AMD CMD这3种JS模块化开发标准的特点和区别。

当时问题回答的不太好,总结了一下,以免大家采坑。

 

一、CommonJS

  CommonJS是NodeJS服务器端的概念 、采用同步加载文件的方式

  实例说明:

  目前大家项目中使用打包工具webpack就是通过node实现的功能,配置webpack.config.js中使用的module.exports 公布接口这就是CommonJS的标准

1 const path = require('path');
2 
3 module.exports = {
4   entry: './src/index.js',
5   output: {
6       path: path.resolve(__dirname, 'dist'),
7       filename: 'bundle.js'
8   }
9 };

 

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

 

优点:

  1. 服务器端便于重用
  2. NPM中已经将近20w个模块包
  3. 简单并容易使用

缺点:

  1. 同步的模块方式不适合不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
  2. 不能非阻塞的并行加载多个模块

 

二、AMD

   AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

   我们使用的RequireJS就是AMD的实现框架。

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

 

1 //定义AMD接口规范
2 
3 define("module", ["dep1", "dep2"], function(d1, d2) {  
4 
5   //定义一个模块dep1 dep2是依赖的模块 依赖的模块是前置加载的,
6 
7   return someExportedValue;  
8 
9 }); 

 

1 //引用模块
2 
3 require(['math'], function (math) {
4             //异步加载math模块 ,在回调函数中调用 
5     math.add(2, 3);
6 
7 });

 

 

三、CMD

CMD(Common Module Definition)模块定义规范 该规范的代表框架是SeaJS CMD 推崇就近,AMD 推崇前置 对比上面AMD的define 就一路了然看到二者的区别了

define(function(require, exports, module) {

var math= require('./math')  //当使用到math模块了才去加载math模块

math.add(1,2)
// 此处略去100 行

var tools= require('./tools') // 依赖可以就近书写
tools.getFile()

// ... 

})

 

最后总结:

  目前实现的框架 文件加载方式 对依赖模块的加载
AMD RequireJS 异步加载 前置加载
CMD SeaJS
异步加载 延迟加载
Command NodeJS 同步加载 同步加载

 

 

 

 

 如果大家还想了解更多关于RequireJS和SeaJS的差别 看看玉伯的文章

posted @ 2018-04-18 17:35  抱朴守拙  阅读(285)  评论(0编辑  收藏  举报