AMD 和 CMD

CMD
CMD规范:是SeaJS 在推广过程中对模块定义的规范化产出的。


什么是CMD规范:


在CMD中,一个模块就是一个文件

define(function(require,exports,module){
    //模块代码
})

define是一个全局函数,主要用来定义模块。
将上述代码保存在文件acot.js中,那么我想要在bcont.js中依赖于acont.js的话,可以:

define(function(require,exports,module){
    var require('acont.js');
})

在seaJS中 factory可以是函数、对象或者字符串。factory为对象 字符串时候,表示该模块的接口就是该对象或者字符串

define({  
    provinces: [
    {
        name: '上海', 
        areas: ['浦东新区', '徐汇区']},
    {
        name: '江苏', 
        cities: ['南京', '南通']}
        //.....  
    ]
});

假设这个文件名为json.js,那么如果某个模块需要这个数据,只需要:

define(function(require,exports,module){
     var china = require('./json');
    //在这里使用中国省市数据
});
当factory为函数时,表示该模块的构造方法,执行该构造方法,可以得到模块向外提供的接口。默认会传入三个参数require,exports,module
是一个方法,他可以解决依赖,用于获取其他模块提供的接口
/*acont.js中的代码:*/
define(function(require, exports) {
    exports.a = function(){
    // 很多代码 
    };
});

在bcont.js里面调用acont.js里面的a方法

define(function(require,exports){

        var fun = require('./acont');

    console.log(fun.a()); // 就可以调用到及执行a函数了。

   })
require.async(id,callback) :

require.async: 方法用来在模块内部异步加载模块,并在加载完成后执行指定回调。callback参数可选

define(function(require, exports, module) {

  // 异步加载一个模块,在加载完成时,执行回调
  require.async('./bcont', function(b) {
    b.doSomething();
  });

  // 异步加载多个模块,在加载完成时,执行回调
  require.async(['./ccont', './dcont'], function(c, d) {
    c.doSomething();
    d.doSomething();
  });

});
/*require是同步往下执行的,而require.async 则是异步回调执行*/
require.resolve(id)

使用模块系统内部的路径解析机制来解析并返回模块路径。该函数不会加载模块,只返回解析后的绝对路径。

define(function(require, exports) {

  console.log(require.resolve('./bcont'));
  // ==> http://example.com/path/to/bcont.js

});

exports:是一个对象,用来向外提供模块接口

define(function(require, exports) {
    exports.a = function(){
        // 很多代码    
    };
});
define(function(require, exports) {
    return {
              i: 'a',
              a: function(){ 
                   // 执行相应的代码
              }
        }
});

module

module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。其中exports是module.exports的一个引用。

moudle.id 模块的唯一标识

define('id', [], function(require, exports, module) {
  // 模块代码
});

module.uri 根据模块系统的路径解析规则得到的模块绝对路径

define(function(require, exports, module) {
  console.log(module.uri); 
  // ==> http://example.com/path/to/this/file.js
});

AMD 规范

define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
    exports.verb = function() {
        return beta.verb();
        //或者:
        return require("beta").verb();
    }
});

require函数让你能够随时去依赖一个模块,即取得模块的引用,从而即使模块没有作为参数定义,也能够被使用;exports是定义的 alpha 模块的实体,在其上定义的任何属性和方法也就是alpha模块的属性和方法。通过exports.verb = …就是为alpha模块定义了一个verb方法,第三个参数(’definition function’)是一个用来为你的模块执行初始化的函数

// 模块定义函数 
// 依赖项(foo 和 bar)被映射为函数的参数
define('myMoudle',['foo','bar'],function(foo,bar){
    // 返回一个定义了模块导出接口的值
    // (也就是我们想要导出后进行调用的功能)
    // 在这里创建模块
    var myModule = {
        doStuff:function(){
            console.log('Yay! Stuff');
        }
    }
    return myModule;
});

define('myModule',['math', 'graph'], function ( math, graph ) {

        // 请注意这是一个和 AMD 有些许不同的模式,但用几种不同的方式
        // 来定义模块也是可以的,因为语法在某些方面还是比较灵活的
        return {
            plot: function(x, y){
                return graph.drawPie(math.randomGrid(x,y));
            }
        }
    };
});

require 则主要用来在顶层 JavaScript 文件中或须要动态读取依赖时加载代码

// 假设 'foo' 和 'bar' 是两个外部模块
// 在本例中,这两个模块被加载后的 'exports' 被当做两个参数传递到了回调函数中
// 所以可以像这样来访问他们
require(['foo', 'bar'], function ( foo, bar ) {
        // 这里写其余的代码
        foo.doSomething();
});
define(function ( require ) {
    var isReady = false, 
        foobar;

    // 请注意在模块定义内部内联的 require 语句
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();
    });

    // 我们仍可以返回一个模块
    return {
        isReady: isReady,
        foobar: foobar
    };
});

CMD规范与AMD规范的区别如下

  1. CMD依赖就近
define(function(require,exports,module){  
        var a = require('./a');  
        a.doSomthing();  
});

AMD依赖前置

define(['./a','./b'],function(a,b){  
       //......  
       a.doSomthing();  
       //......  
       b.doSomthing();  
})  

无需遍历整个函数体找到它的依赖,因此性能有所提升,缺点就是开发者必须显式得指明依赖——这会使得开发工作量变大

CMD是延迟执行的,而AMD是提前执行的

/*ADM加载器*/

define("path/library-name", [
    "require",
    "jquery",
    "./relative-path/library",
    "absolute-path/library"
], function f(require, $, lib, anotherLib) {
    // do something
    // and return the module itself.
});

/*
@脚本文件被加载时, AMD 的 define 函数被执行。它会用一些预定义的规则解析依赖路径,并且把未载入也未进入等待列表的依赖放入等待列表,并加载这些依赖所对应的文件
@当所有依赖被加载和执行完成后,执行传入的回调函数 (在此被记为 f) 才被执行,而此时加载器提供的回调函数把返回值填充于一个内部的哈希表里,以这里指定的模块名称 path/library-name, 或者隐式的使用当前加载的文件名作为模块名称为键
@相对我们定义模块的函数 f, AMD 加载器是提前执行所有依赖
*/
/*
@ CMD 加载器
@ 与 AMD 不同的是, CMD 加载器在依赖分析阶段通过字符串分析函数内形如 require("stringLiteral") 的正则匹配来获取所有依赖项。
@ 通过回调函数的Function.toString函数,使用正则表达式来捕捉内部的require字段,找到require('jquery')内部依赖的模块jquery
@ 根据配置文件,找到jquery的js文件的实际路径
@ 在dom中插入script标签,载入模块指定的js,绑定加载完成的事件,使得加载完成后将js文件绑定到require模块指定的id(这里就是jquery这个字符串)上
@ 回调函数内部依赖的js全部加载(暂不调用)完后,调用回调函数
@ 当回调函数调用require('jquery'),即执行绑定在'jquery'这个id上的js文件
*/

api设计

AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值