深刻浅出requireJS-1

  咱们都知道,虽然咱们能够经过原型和继承来使javascript面向对象。可是,当js代码和逻辑过多时,代码的维护和扩展会变的很不方便。这时,nodejs作的很是好,可是在浏览器端模块化的js编程一直都是个难题。而requireJS就是来帮助咱们解决这个问题的。requireJS遵循amd规范,因此让咱们先了解下关于AMD规范的事情。javascript

1、AMD规范css

  AMD规范是浏览器端的模块规范,它的全称为异步模块定义。从名称上看便知它是适合script tag的。也能够说AMD是专门为浏览器中JavaScript环境设计的规范。它吸收了CommonJS的一些优势,但又不照搬它的格式。开始AMD做为CommonJS的transport format 存在,因没法与CommonJS开发者达成一致而独立出来。它有本身的wiki 和讨论组 。java

AMD设计出一个简洁的写模块API:node

define(id?, dependencies?, factory);jquery

其中:git

  • id: 模块标识,能够省略。
  • dependencies: 所依赖的模块,能够省略。
  • factory: 模块的实现,或者一个JavaScript对象。
id遵循CommonJS  Module Identifiers 。dependencies元素的顺序和factory参数一一对应。
 
如下是使用AMD模式开发的简单三层结构(基础库/UI层/应用层):
 
base.js
define(function() {
    return {
        mix: function(source, target) {
        }
    };
});

  

ui.jsgithub

define(['base'], function(base) {
    return {
        show: function() {
            // todo with module base
        }
    }
});

 

page.js编程

define([ 'base' ],  function (base) {
     return  {
         show:  function () {
             // todo with module base
         }
     }
});

 

data.jsapi

define({
     users: [],
     members: []
});

 

以上同时演示了define的三种用法
  1. 定义无依赖的模块(base.js)
  2. 定义有依赖的模块(ui.js,page.js)
  3. 定义数据对象模块(data.js)
 
细心的会发现,还有一种没有出现,即具名模块
 
4,具名模块
define( 'index' , [ 'data' , 'base' ],  function (data, base) {
     // todo
});

 

具名模块多数时候是不推荐的,通常由打包工具合并多个模块到一个js文件中时使用。
 
前面提到dependencies元素的顺序和factory一一对应,其实不太严谨。AMD开始为摆脱CommonJS的束缚,开创性的提出了本身的模块风格。但后来又作了妥协,兼容了 CommonJS  Modules/Wrappings 。即又能够这样写
 
5,包装模块
define( function (require, exports, module) {
     var  base = require( 'base' );
     exports.show =  function () {
         // todo with module base
     }
});

 

不考虑多了一层函数外,格式和Node.js是同样的:使用require获取依赖模块,使用exports导出API。
 
除了define外,AMD还保留一个关键字require。 require 做为规范保留的全局标识符,能够实现为 module loader,也能够不实现。
 
目前,实现AMD的库有 RequireJS 、 curl 、 Dojo 、 bdLoadJSLocalnet 、 Nodules 等。
也有不少库支持AMD规范,即将本身做为一个模块存在,如 MooTools 、 jQuery 、 qwery 、 bonzo  甚至还有  firebug 。
2、CMD规范
  与AMD规范相似的还有CMD规范,
在CMD中,一个模块就是一个文件,格式为:
     define( factory );
 
    全局函数define,用来定义模块。
    参数 factory  能够是一个函数,也能够为对象或者字符串。
    当 factory 为对象、字符串时,表示模块的接口就是该对象、字符串。
 
    定义JSON数据模块:
  1. define({ "foo": "bar" });
    经过字符串定义模板模块:

  1. define('this is {{data}}.');
    factory 为函数的时候,表示模块的构造方法,执行构造方法即可以获得模块向外提供的接口。

  1. define( function(require, exports, module) { 
  2.     // 模块代码
  3. });


     define( id?, deps?, factory );
    define也能够接受两个以上的参数,字符串id为模块标识,数组deps为模块依赖:

  1. define( 'module', ['module1', 'module2'], function( require, exports, module ){
  2.     // 模块代码
  3. } );
    其与 AMD 规范用法不一样。
 
     require 是 factory 的第一个参数。
    require( id );
    接受模块标识做为惟一的参数,用来获取其余模块提供的接口:

  1. define(function( require, exports ){
  2.     var a = require('./a');
  3.     a.doSomething();
  4. });
 
    require.async( id, callback? );
    require是同步往下执行的,须要的异步加载模块能够使用 require.async 来进行加载:

  1. define( function(require, exports, module) { 
  2.     require.async('.a', function(a){
  3.         a.doSomething();
  4.     });
  5. });
    require.resolve( id )
    能够使用模块内部的路径机制来返回模块路径,不会加载模块。
 
     exports 是 factory 的第二个参数,用来向外提供模块接口。

  1. define(function( require, exports ){
  2.     exports.foo = 'bar'; // 向外提供的属性
  3.     exports.do = function(){}; // 向外提供的方法
  4. });
    固然也能够使用 return 直接向外提供接口。

  1. define(function( require, exports ){
  2.     return{
  3.         foo : 'bar', // 向外提供的属性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });
    也能够简化为直接对象字面量的形式:

  1. define({
  2.     foo : 'bar', // 向外提供的属性
  3.     do : function(){} // 向外提供的方法
  4. });


    与nodeJS中同样须要注意的是,一下方式是错误的:

  1. define(function( require, exports ){
  2.     exports = {
  3.         foo : 'bar', // 向外提供的属性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });


    须要这么作

  1. define(function( require, exports, module ){
  2.     module.exports = {
  3.         foo : 'bar', // 向外提供的属性
  4.         do : function(){} // 向外提供的方法
  5.     }
  6. });
    传入的对象引用能够添加属性,一旦赋值一个新的对象,那么值钱传递进来的对象引用就会失效了。开始之初,exports 是做为 module.exports 的一个引用存在,一切行为只有在这个引用上 factory 才得以正常运行,赋值新的对象后就会断开引用,exports就只是一个新的对象引用,对于factory来讲毫无心义,就会出错。
 
    module 是factory的第三个参数,为一个对象,上面存储了一些与当前模块相关联的属性与方法。
        module.id 为模块的惟一标识。
        module.uri 根据模块系统的路径解析规则获得模块的绝对路径。
        module.dependencies 表示模块的依赖。
        module.exports 当前模块对外提供的接口。
相关文章
相关标签/搜索