资讯专栏INFORMATION COLUMN

require.js学习笔记。

K_B_Z / 1669人阅读

摘要:他仅需简单地通过一个标签发起请求,是实现跨域服务调用一种公认手段。为了在中使用服务,须要将参数的值指定为。该示例中,的参数为,因此告诉将响应包裹到一个中

加载JavaScript文件

RequireJS的目的是鼓励代码的模块化,它使用了不同于传统script标签的脚本加载步骤。可以用它来加速、优化代码,但其主要目的还是为了代码的模块化。它鼓励在使用脚本时以module ID替代URL地址。
RequireJs以一个相对于baseUrl的地址来加载所有的代码。页面顶层script标签含有一个特殊属性data-main,require.js使用它来启动脚本加载过程,而baseUrl一般设置到与该属性相一致的目录。

baseUrl亦可通过RequireJS config手动设置。如果没有显式指定config及data-main,则默认的baseUrl为包含RequireJS的那个HTML页面的所属目录。


//app.js
require.config({
    baseUrl:"js/lib",
    paths:{
        app:"../app"
    }
});
require(["jquery","canvas","app/sub"],function($,canvas,sub){
    //....
})

注意在示例中,三方库如Jquery没有将版本号包含在它们的文件名中。我们建议将版本信息放置在多带带的文件中进行跟踪。
理想状况下,没个加载的脚本都是通过define()来定义的一个模块;但是有些浏览器全局变量注入型的传统/遗留库并没有使用define()来定义它们的依赖关系,你必须为此使用shim config来指明它们的依赖关系。如果你没有指明依赖关系,加载可能报错。这是因为基于速度的原因,srequireJS会异步地以无序的形式加载这些库。

data-main入口点

require.js在加载的时候会检查data-main属性:

你可以在data-main指向的脚本中设置模板加载选项,然后加载第一个应用模块。注意:你再main.js中所这是的脚本是异步加载的。所以如果你在页面中配置了其它JS加载,则不能保证它们所依赖的JS已经加载成功。



//main.js
require.config({
    paths:{
        foo:"libs/foo-1.1.3"
    }
});
//other.js
require(["foo"],function(foo){})
定义模块

模块不同于传统的脚本文件,它良好的定义了一个作用域来避免全局名称空间污染。它可以显式的列出其依赖关系,并以函数参数的形式将这些依赖进行注入,而无需引用全局变量。requireJS的模块是模块模式的一个扩展,其好处是无需全局引用其它模块。
RequireJs模块语法允许它尽快地加载多个模块,虽然加载的顺序不定,但依赖的顺序最终是正确的。同时因为无需创建全局变量,甚至可以做到在同一页面上同时加载同一模块的不同版本。
如果一个模块仅含值对,没有任何依赖,则在define()中定义这些值就好了:

define({
    color:"black",
    size:"unisize"
})

如果一个模块没有任何依赖,但需要一个setup工作的函数,则在define()中定义该函数,并将其传给define():

define(function(){
    return{
        color:"black",
        size:"unisize"
    }
})

如果模块存在依赖:则第一个参数是依赖的名称数组;第二个参数是函数,在模块的所有依赖加载完毕后,该函数会被调用来定义该模块,因此该模块应该返回一个定义了本模块的object。依赖关系会以参数的形式注入到该函数上,参数列表与依赖名称列表一一对应。

define(["./cart","./inventory"],function(cart,inventory){
    return{
        color:"blue",
        size:"large",
        addToCart:function(){
            inventory.decrement(this);
            cart.add(this);
        }
    }
})

对模块的返回值类型并没有强制为一定是个object,任何函数的返回值都是允许的。此处是一个返回了函数的模块定义:

define(["my/cat","my/inventory"],{
    function(cart,inventory){
        return function(title){
            return title?(window.title = title):inventory.storeName+""+cart.name;
        }
    }
})

define()中的相对模块名:为了可以在define()内部使用诸如require("./relative/name")的调用以正确解析相对名称,记得将require本身作为一个依赖注入到模块中:

define(["require","./relative/name"],funciton(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")
})

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

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

一般说你无需使用require()去获取一个模块,而是应当使用注入到模块函数参数中的依赖。循环依赖比较罕见,它也是一个重构代码重新设计的i警示灯。
如果你熟悉CommonJS,你可以考虑使用exports为模块建立一个空object,该object可以立即被其它模块引用。再循环依赖的两头都如此操作之后,你就可以完全持有其它模块了。这种方法仅在每个模块都是输出object作为模块值的时候有效,换成函数无效。

//b.js
define(function(require,exports,module){
    var a = require("a");
    exports.foo = function(){
        return a.bar();
    }
})

或则,如果你使用依赖注入数组的步骤,则可用注入特殊exports来解决:

//b.js
define(["a","exports"],function(a,exports){
    exports.foo = function(){
        return a.bar();
    }
});

JSONP是在javascript中服务调用的一种方式。他仅需简单地通过一个script标签发起HTTP GET请求,是实现跨域服务调用一种公认手段。
为了在RequireJS中使用JSON服务,须要将callback参数的值指定为define。这意味着你可将获取到的JSONP URL的值看成是一个模块定义。
下面是一个调用JSONP API端点的示例。该示例中,JSONP的callback参数为"callback",因此"callback=define"告诉API将JSON响应包裹到一个"define()"中:

require(["http://example.com/api/data.json?callback=define"],
    function (data) {
        //The data object will be the API response for the
        //JSONP data call.
        console.log(data);
    }
);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100414.html

相关文章

  • RequireJS学习笔记

    摘要:如果有疑惑的地方,欢迎讨论,我是初学,希望能切磋和得到指点加载会阻塞页面加载默认异步加载文件方法一把放到页面底部加载方法二支持定义全局相对路径方法一自定义属性指定网页程序的主模块文件定义整个网页代码的入口文件的相对位置,以后此文件 如果有疑惑的地方,欢迎讨论,我是初学,希望能切磋和得到指点; js加载会阻塞页面加载: //requirejs默认异步加载js文件; 方法一...

    hersion 评论0 收藏0
  • JS学习笔记 - 模块化

    摘要:在开发大型的项目中,可能会使用到管理的模块化工具。说道,学习过的同学会比较熟悉,是服务器模块的规范,采用了这个规范。可能是未来模块化解决方案的首选。 本文章记录本人在学习 JavaScript 中理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。 在开发大型的web项目中,可能会使用到管理js的模块化工具。但是在前端轮子漫天飞的时代。那一款js模块化工具真正适合我...

    CntChen 评论0 收藏0
  • cordova研习笔记(二) —— cordova 6.X 源码解读(上)

    摘要:本文源码为版本。的代码结构也是一个很经典的定义结构构造函数实例修改函数原型共享实例方法,它提供事件通道上事件的订阅撤消订阅调用。 前言 cordova(PhoneGap) 是一个优秀的经典的中间件框架,网上对其源代码解读的文章确实不多,本系列文章试着解读一下,以便对cordova 框架的原理理解得更深入。本文源码为cordova android版本6.1.2。 源码结构 我们使用IDE...

    Java_oldboy 评论0 收藏0
  • 《高性能JavaScript》(读书笔记

    摘要:加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。异步加载,和,浏览器不会失去响应它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。插件,可以让回调函数在页面结构加载完成后再运行。 这次主要是对《高性能JavaScript》一书的读书笔记,记录下自己之前没有注意到或者需要引起重视的地方 第一章 加载和执行 js代码在执行过程中会阻塞浏览...

    moven_j 评论0 收藏0
  • RequireJS配置项笔记

    摘要:读不顺中文文档,对应中文文档,自行翻译的如果有问题错误,欢迎指点修改配置选项方法一在顶级页面或顶级脚本文件没有定义模块的脚本文件中配置方法二在主模块中配置缺点主模块异步加载,多入口的话,会随机报错方法三在调用之前,将配置定义为全局变量配置在 读不顺中文文档,对应中文文档,自行翻译的……如果有问题/错误,欢迎指点; 修改配置选项: 方法一、 requi...

    FWHeart 评论0 收藏0

发表评论

0条评论

K_B_Z

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<