天天看点

requireJS官网学习(2)

4.(将模块定义为一个函数)对模块的返回值类型并没有强制为一定是个object,任何函数的返回值都是允许的。

此处是一个返回了函数的模块定义:

define(["my/cart", "my/inventory"],
    function(cart, inventory) {    
    //返回一个函数,用于设置window的标题    
        return function(title) {
            return title ? (window.title = title) :inventory.storeName + ' ' + cart.name;
        }
    }
);
           

5.(简单包装CommonJS来定义模块)直接将这些依赖对应到一些本地变量中进行使用

define(function(require, exports, module) {
        var a = require('a'),
            b = require('b');
        //Return the module value
        return function () {};
    }
);
//该包装方法依靠Function.prototype.toString()将函数内容赋予一个有意义的字串值,
           

6.(定义一个命名模块)你可能会看到一些define()中包含了一个模块名称作为首个参数:

define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );
           

这些常由优化工具生成。你也可以自己显式指定模块名称,但这使模块更不具备移植性,就是说若你将文件移动到其他目录下,

你就得重命名。一般最好避免对模块硬编码,而是交给优化工具去生成。优化工具需要生成模块名以将多个模块打成一个包,

加快到浏览器的载入速度。

7.(其他注意事项)一个文件一个模块: 每个Javascript文件应该只定义一个模块,这是模块名-至-文件名查找机制的

自然要求。多个模块会被优化工具组织优化,但你在使用优化工具时应将多个模块放置到一个文件中。

define()中的相对模块名: 为了可以在define()内部使用诸如require(“./relative/name”)的调用以正确解析相对名称,

记得将”require”本身作为一个依赖注入到模块中:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});
           

转换CommonJS模块所设的更短的语法:

define(function(require) {
    var mod = require("./relative/name");
});
           

相对路径在一些场景下格外有用,例如:为了以便于将代码共享给其他人或项目,你在某个目录下创建了一些模块。

你可以访问模块的相邻模块,无需知道该目录的名称。

生成相对于模块的URL地址: 你可能需要生成一个相对于模块的URL地址。你可以将”require”作为一个依赖注入进来,然后调用require.toUrl()以生成该URL:

define(["require"], function(require) {
    var cssUrl = require.toUrl("./style.css");
});
           

控制台调试:如果你需要处理一个已通过require([“module/name”], function(){})调用加载了的模块,可以使用模块名作为字符串

参数的require()调用来获取它:

require("module/name").callSomeFunction()
/**
注意这种形式仅在"module/name"已经由其异步形式的require(["module/name"])加载了后才有效。只能在define内部使用形如"./module/name"的相对路径。
*/
           

8.(循环依赖)如果你定义了一个循环依赖(a依赖b,b同时依赖a),则在这种情形下当b的模块函数被调用的时候,它会得到一个undefined的a。b可以在模块已经定义好后用require()方法再获取(记得将require作为依赖注入进来):

define(["require", "a"],
    function(require, a) {
        return function(title) {
            return require("a").doSomething();
        }
    }
);
           

JSONP服务依赖

JSONP是在javascript中服务调用的一种方式。它仅需简单地通过一个script标签发起HTTP GET请求,是实现跨域服务调用一种公认手段。

下面是一个调用JSONP API端点的示例。该示例中,JSONP的callback参数为”callback”,因此”callback=define”告诉API将JSON响应包裹到一个”define()”中:

require(["http://example.com/api/data.json?callback=define"],
    function (data) {        
        console.log(data);
    }
);
           

JSONP的这种用法应仅限于应用的初始化中。一旦JSONP服务超时,其他通过define()定义了的模块也可能得不得执行,错误处理不是十分健壮。仅支持返回值类型为JSON object的JSONP服务,其他返回类型如数组、字串、数字等都不能支持。

机制

RequireJS使用head.appendChild()将每一个依赖加载为一个script标签。

RequireJS等待所有的依赖加载完毕,计算出模块定义函数正确调用顺序,然后依次调用它们。

支持的配置项

  1. baseUrl :所有模块的查找根路径。当加载纯.js文件(依赖字串以/开头,或者以.js结尾,或者含有协议),不会使用baseUrl。
  2. paths :path映射那些不直接放置于baseUrl下的模块名。设置path时起始位置是相对于baseUrl的,
  3. shim: 为那些没有使用define()来声明依赖关系、设置模块的”浏览器全局变量注入”型脚本做依赖和导出配置。
requirejs.config({
    shim: {
        'jquery.colorize': {
            deps: ['jquery'],
            exports: 'jQuery.fn.colorize'
        },
        'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'
        },
        'backbone.layoutmanager': {
            deps: ['backbone']
            exports: 'Backbone.LayoutManager'
        }
    }
});

/**
shim配置仅设置了代码的依赖关系,想要实际加载shim指定的或涉及的模块,仍然需要一个常规的require/define调用。
设置shim本身不会触发代码的加载。
*/
           

4.map: 对于给定的模块前缀,使用一个不同的模块ID来加载该模块。

requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

如果各模块在磁盘上分布如下:
foo1.0.js
foo1.2.js
some/
    newmodule.js
    oldmodule.js
当“some/newmodule”调用了“require('foo')”,它将获取到foo1.2.js文件;而当“some/oldmodule”
调用“`require('foo')”时它将获取到foo1.0.js。**map配置中仅使用绝对模块ID**
           

map中支持“”,意思是“对于所有的模块加载,使用本map配置”。如果还有更细化的map配置,会优先于“”配置。示例:

requirejs.config({
    map: {
        '*': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});
意思是除了“some/oldmodule”外的所有模块,当要用“foo”时,使用“foo1.2”来替代。对于“some/oldmodule”自己,则使用“foo1.0”。
           

5.config:常常需要将配置信息传给一个模块。这些配置往往是application级别的信息,需要一个手段将它们向下传递给模块。

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});
           

若要将config传给包,将目标设置为包的主模块而不是包ID:

requirejs.config({  
    config: {
        'pixie/index': {
            apiKey: 'XJKDLNS'
        }
    },    
   packages: [
        {
            name: 'pixie',
            main: 'index'
        }
    ]
});
           

6.packages: 从CommonJS包(package)中加载模块。

7.deps: 指定要加载的一个依赖数组。

8.callback: 在deps加载完毕后执行的函数。

从包中加载模块

project-directory/

project.html

scripts/

cart/

main.js

store/

main.js

util.js

main.js

require.js

project.html 会有如下的一个script标签:

这会指示require.js去加载scripts/main.js。main.js使用“packages”配置项来

设置相对于require.js的各个包,此例中是源码包“cart”及“store”:

main.js

require.config({
    "packages": ["cart", "store"]
});

require(["cart", "store", "store/util"],
    function (cart,   store,   util) {
        //use the modules as usual.
    });
/**
对“cart”的依赖请求会从scripts/cart/main.js中加载,因为“main”是RequireJS默认的包主模块。
对“store/util”的依赖请求会从scripts/store/util.js加载。

*/
           

如果“store”包不采用“main.js”约定,如下面的结构:

project-directory/

project.html

scripts/

cart/

main.js

store/

store.js

util.js

main.js

package.json

require.js

require.config({
    packages: [
        "cart",
        {
            name: "store",
            main: "store"
        }
    ]
});