AMD 和 CMD

来源:互联网 发布:网络维护员工资 编辑:程序博客网 时间:2024/05/20 16:32

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 0
原创粉丝点击