彻底搞清CommonJS、AMD、CMD...

·  阅读 1023
彻底搞清CommonJS、AMD、CMD...

发展过程

CommonJS、AMD、CMD、requeir, moudle.exports, exports,import,export...原地爆炸...

先从时间线上大概对这几种规范有个大致了解

  • 2009 -> CommonJS
  • 2010 -> AMD规范
  • 2011 -> CMD规范
  • 2015 -> ES6 Module

CommonJS

CommonJS规范诞生比较早,Mozilla工程师Kevin Dangoo在2009年发起,它出现的目的是希望JS可以运行到更多地方,主要是服务端,前期的nodejs采用了这种规范。

用法示例

module.exports或exports负责对外暴漏数据,require来引入

<!--a.js-->
module.exports = {
    name: '四大名将'
}
<!--也可以用exports导出-->
<!--export.name = '四大名将'-->

<!--b.js-->
const res = require('./a.js')
console.log(res.name) // 四大名将
复制代码
module.exports 和 exports的区别

乍一看,还以为CommonJS提供了两种方法来导出数据,其实不然,require并不认识exports,之所以它也好使,那是因为模块内部这些代码的作用。

var module = {
    exports: {
        <!--导出的内容-->
    }
}

var exports = module.exports
return module.exports
复制代码

require方能看到的只有module.exports这个对象,它是看不到exports这个对象的,而我们在编写模块时用到的exports实际上是对module.exports的引用。

举个例子
<!--a.js-->
exports = {
    name: '四大名将'
}
如果这样导出,exports被重新赋值,指向的地址便不再是module.exports,所以此时的exports失去了它的导出功能,只会导出一个默认空对象
复制代码

AMD (Asynchronous Module Definition)

AMD规范在2010由requireJS提出,CommonJS规范主要是弥补服务端的模块化机制,不像服务器加载速度很快,客户端加载时需要等待,可能存在假死情况,鉴于浏览器的特殊情况,AMD规范出来了,它采用异步方式加载模块定义的所有依赖,在依赖加载完成后再执行回调函数。

define([module-name?], [dependencies?], [factory])

  • module-name:字符串,模块名称(可选)
  • dependencies:要载入的依赖模块(可选),数组格式,相对路径
  • factory: 工厂方法,返回一个模块函数
<!-- 定义模块 -->
<!-- AMD中require的模块会先加载完成 依赖前置 提前执行 -->
define('module', ['dep1', 'dep2'], function(dep1, dep2){
  function foo(){
      dep1.doSomething();
      dep2.doSomething();
  }
  return {
    foo : foo
  };
})

<!-- 数组中声明需要加载的模块,可以是模块名、js文件路径 -->
<!-- 两个参数:加载的模块,加载成功后的回调函数 -->
require(['module'], function(module){
    module.foo()
});
复制代码

CMD (Common Module Definition)

CMD规范在2011年由seaJS提出,CMD规范和AMD规范类似,主要区别是CMD规范是就近加载依赖,延迟执行,只有到require时依赖才执行。

<!-- a.js -->
define(function(require, exports, module) {
  function foo(){
    <!-- require的模块此时才会执行 依赖就近 延迟执行 而AMD中依赖是前置的 一开始就全都执行完毕了  -->
    var dep1 = require('dep1') 
    dep1.doSomething();
 }
 <!--暴漏给外部调用-->
 exports.foo = foo
 
 /** return或者exports都行
 return {
   foo : foo
 };
 **/
});
<!-- b.js -->
seajs.use("./a", function(a){
  a.foo()
});

复制代码

ES6 Module

2015年es6横空出世,引入了新特性 ES Module,诸如export, import等命令。

es6的module比较常用,贴一个阮一峰的es6链接ES6 Module


最后,圣诞快乐~

分类:
前端
标签:
分类:
前端
标签: