require.jsAMD模块化编程

Require.JS解决的问题

require.jsAMD模块化编程_第1张图片

RequireJS基本思想:通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载。

一 采用AMD规范编写模块

1.采用define()函数来定义模块

         @1.模块不依赖其他模块,直接定义在define()函数之中

简写:生成一个拥有method1method2两个方法的模块

define({

         method1: function(){},

         method2:function(){},

})

另一种等价的写法是,把对象写成一个函数,该函数的返回值就是输出的模块

define(function(){

         return{

                   method1:function(){},

                   method2:function(){},     

         };

})

后一种写法的自由度更高一点,可以在函数体内写一些模块初始化代码

字面量写法:

define(function (){

    var add = function (x,y){

      return x+y;

    };

    return {

add: add  前面的add对应外部调用名 后面的add对应模块里的实现函数名
    };

  });

@2.非独立模块:模块还依赖其他模块

如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。

define(['module1','module2'],function(m1,m2)){

         .......doSomething

}

define方法的第一个参数是一个数组,它的成员是当前模块所依赖的模块。比如,['module1', 'module2']表示我们定义的这个新模块依赖于module1模块和module2模块,只有先加载这两个模块,新模块才能正常运行。一般情况下,module1模块和module2模块指的是,当前目录下的module1.js文件和module2.js文件,等同于写成['./module1', './module2']

define方法的第二个参数是一个函数,当前面数组的所有成员加载成功后,它将被调用。它的参数与数组的成员一一对应,比如function(m1, m2)就表示,这个函数的第一个参数m1对应module1模块,第二个参数m2对应module2模块。

这个函数必须返回一个对象,供其他模块调用。 

define(['module1', 'module2'], function(m1, m2) {

 

    return {

        method: function() {

                               m1.methodA();

                               m2.methodB();

        }

    }; 

});

上面代码表示新模块返回一个对象,该对象的method方法就是外部调用的接口,menthod方法内部调用了m1模块的methodA方法和m2模块的methodB方法。

需要注意的是,回调函数必须返回一个对象,这个对象就是你定义的模块。 

define(['myLib'], function(myLib){

    function foo(){

      myLib.doSomething();

    }

    return {

      foo : foo

    };

  });

require()函数加载上面这个模块的时候,就会先加载myLib.js文件 

模块调用

1. 加载require.jsrequire.js嵌入网页

<script src="js/require.js"  defer async="true" ></script>

async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上

2. 加载主模块:整个网页的入口代码

加载require.js以后,下一步就要加载我们自己的代码了。假定我们自己的代码文件是main.js,也放在js目录下面。

<script data-main="scripts/main"  src=" js /require.js"></script>

data-main属性不可省略,用于指定网页程序的主模块,在上例中为js子目录下的main.js文件,这个文件会第一个被require.js加载。由于require.js默认的文件后缀名是js,所以可以把main.js简写成main

3. 编写主模块

常见的情况是,主模块依赖于其他模块,这时就要使用AMD规范定义的的require()函数。

require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){

    // some code here

  });

require()函数接受两个参数

第一个参数是一个数组,表示所依赖的模块,上例就是['moduleA', 'moduleB', 'moduleC'],即主模块依赖这三个模块;

第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require()异步加载moduleAmoduleBmoduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

默认情况下,require.js假定这三个模块与main.js在同一个目录,文件名分别为jquery.jsunderscore.jsbackbone.js,然后自动加载。

require(['foo', 'bar'], function ( foo, bar ) {

        foo.doSomething();

});

上面方法表示加载foobar两个模块,当这两个模块都加载成功后,执行一个回调函数。该回调函数就用来完成具体的任务。

require方法的第一个参数,是一个表示依赖关系的数组。这个数组可以写得很灵活,请看下面的例子。

require( [ window.JSON ? undefined : 'util/json2' ], function ( JSON ) {

  JSON = JSON || window.JSON;

 

  console.log( JSON.parse( '{ "JSON" : "HERE" }' ) );

});

上面代码加载JSON模块时,首先判断浏览器是否原生支持JSON对象。如果是的,则将undefined传入回调函数,否则加载util目录下的json2模块。

如何动态加载模块

define(function ( require ) {

    var isReady = false, foobar;

 

    require(['foo', 'bar'], function (foo, bar) {

        isReady = true;

        foobar = foo() + bar();

    });

 

4.模块加载 require.config()方法

require.config()方法,我们可以对模块的加载行为进行自定义。

require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。

@1.路径默认与main.js在同一个目录

require.config({

    paths: {

      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"

    }

  });

@2.逐一指定路径 (js/lib)

require.config({

    paths: {

      "jquery": "lib/jquery.min",
      "underscore": "lib/underscore.min",
      "backbone": "lib/backbone.min"

    }

  });

@3.设置基路径 baseUrl

require.config({

    baseUrl: "js/lib",

    paths: {

      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"

    }

  });

require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。

    return {

        isReady: isReady,

        foobar: foobar

    };

});

上面代码所定义的模块,内部加载了foobar两个模块,在没有加载完成前,isReady属性值为false,加载完成后就变成了true。因此,可以根据isReady属性的值,决定下一步的动作。

2.domready插件,可以让回调函数在页面DOM结构加载完成后再运行。

  require(['domready!'], function (doc){

    // called once the DOM is ready

  });



你可能感兴趣的:(require.jsAMD模块化编程)