require.js深入了解 require.js特性介绍

 更新时间:2014年09月04日 11:54:30   投稿:junjie  
这篇文章主要介绍了require.js深入了解,require.js特性介绍,本文讲解了require.js和CommonJS的兼容、CDN回退、循环依赖、BaseUrl、JSONP等内容,需要的朋友可以参考下

现在,Require.js是我最喜欢的Javascript编程方式。它可以使代码化整为零,并易于管理。而Require.js Optimizer能帮助我们将一个较大的应用分散成多个较小的应用,并通过依赖串联起来,最后在编译打包时合并起来。这些原因促使我们使用require.js。

那么,让我们来看看require.js有什么牛逼的特性吧!

与CommonJS兼容

AMD (异步模块定义规范) 出现自CommonJS工作组。CommonJS旨在创造Javascript的生态系统。 CommonJS的一个重要部分是transport/c, 即AMD的前身,而require.js则是该规范的一个实现。

CommonJS模块和AMD模块的语法差异,主要由于AMD需要支持浏览器的异步特性。而CommonJS模块则需要同步进行,例如:

复制代码 代码如下:

var someModule = require( "someModule" );
var anotherModule = require( "anotherModule" );   
 
exports.asplode = function() {
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
};

AMD模块是异步加载模块的,故而模块定义需要一个数组作为第一个参数,而模块加载完毕后回调的函数作为第二个参数传入。
复制代码 代码如下:

define( [ "someModule"],  function( someModule ) {  
    return {
        asplode: function() {
            someModule.doTehAwesome();
 
            // 这将会异步执行
            require( [ "anotherModule" ], function( anotherModule ) {
                anotherModule.doMoarAwesome();
            });
        }
    };
});

然而,在require.js中AMD亦能兼容CommonJS语法。通过AMD的define函数包装CommonJS模块,你也可以再AMD中拥有一个CommonJS模块,例如:
复制代码 代码如下:

define(function( require, exports, module )
    var someModule = require( "someModule" );
    var anotherModule = require( "anotherModule" );   
 
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
 
    exports.asplode = function() {
        someModule.doTehAwesome();
        anotherModule.doMoarAwesome();
    };
});

实际上,require.js通过函数.toString解释回调函数的模块内容,找到其正确的依赖,将其变成一个通常的AMD模块。需要注意,如果你使用这种方式编写模块,可能会发生与其他AMD加载器不兼容的情况,因为这违背了AMD规范,但它能很好的理解这种格式的写法。

这里发生了什么,require.js实际上做了function.toString的回调函数解析模块的内容,找到正确的依赖,就像它,如果它是一个正常的AMD模块。重要的是要注意,如果您选择这样写模块,他们将最有可能不兼容与其他AMD模块装载机,因为这违背了AMD规范,但它是很好的了解这个格式存在!

CDN回退

另一个隐藏的require.js瑰宝是,其支持当CDN加载不正确时,回退加载本地相应的库。我们可以通过require.config达到这个目的:

复制代码 代码如下:

requirejs.config({
    paths: {
        jquery: [
            '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
            'lib/jquery'
        ]
    }
});

没有依赖?对象字面量?没问题!

当你写一个没有任何依赖的模块,并且只是返回一个对象包含一些功能函数,那么我们可以使用一种简单的语法:

复制代码 代码如下:

define({
    forceChoke: function() {
 
    },
    forceLighting: function() {
 
    },
    forceRun: function() {
 
    }   
});

很简单,也很有用,如果该模块仅仅是功能的集合,或者只是一个数据包。

 循环依赖

在一些情况中,我们可能需要模块moduleA和moduleA中的函数需要依赖一些应用。这就是循环依赖。

复制代码 代码如下:

// js/app/moduleA.js
define( [ "require", "app/app"],
    function( require, app ) {
        return {
            foo: function( title ) {
                var app = require( "app/app" );
                return app.something();
            }
        }
    }
);

得到模块的地址

如果你需要得到模块的地址,你可以这么做……

复制代码 代码如下:

var path = require.toUrl("./style.css");

BaseUrl

通常,在进行的单元测试时,你的源代码可能放在类似src的文件夹里,同时,可能你的测试放在类似tests的文件夹里。这可能比较难让测试配置正确。

比如我们在tests文件夹有一个index.html文件,并需要本地加载tests/spec/*.js。并假设,所有源代码在为src/js/*.js,并有一个main.js在该文件夹。

index.html中,不在加载require.js时设置data-main。

复制代码 代码如下:

<script src="src/js/vendor/require.js"></script>
<script>
require( [ "../src/js/main.js" ], function() {
    require.config({
        baseUrl: "../src/js/"
    });
 
    require([
        "./spec/test.spec.js",
        "./spec/moar.spec.js"
    ], function() {
        // start your test framework
    });
});
</script>

你可以发现main.js被加载。然而由于没有设置data-main,所欲我们需要制定一个baseUrl。而当使用data-main时,baseUrl会根据其设定的文件来自动设置。

在这里,你可以看到main.js被载入。然而,由于它没有加载数据主要脚本标记,那么您必须指定一个base即可。当数据主要是用于baseURL时从主文件中的位置推断。通过自定义baseUrl我们可以很容易将测试代码和应用代码分开存放。

JSONP

我们可以这样处理JSONP终端:

复制代码 代码如下:

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

对于非AMD库,使用shim来解决

在很多请款下,我们需要使用非AMD库。例如Backbone和Underscore并未适应AMD规范。而jQuery实际上只是将自己定义成一个名为jQuery全局变量,所以对于jQuery什么都不用做。

幸运的是,我们可以使用shim配置来解决这一问题。

复制代码 代码如下:

require.config({
    paths: {
        "backbone": "vendor/backbone",
        "underscore": "vendor/underscore"
    },
    shim: {
        "backbone": {
            deps: [ "underscore" ],
            exports: "Backbone"
        },
        "underscore": {
            exports: "_"
        }
    }
});

相关文章

  • 精通JavaScript 纠正 cleanWhitespace函数

    精通JavaScript 纠正 cleanWhitespace函数

    这个函数用在火狐(firefox)上面老是出错,今天仔细研究了下,改正了,希望别人不要遇到我这样的问题
    2010-03-03
  • 浅谈轻量级js模板引擎simplite

    浅谈轻量级js模板引擎simplite

    这篇文章主要介绍了浅谈轻量级js模板引擎simplite的简介和用法的相关资料,需要的朋友可以参考下
    2015-02-02
  • Three.js学习之Lamber材质和Phong材质

    Three.js学习之Lamber材质和Phong材质

    本篇将介绍基本材质以及两种基于光照模型的材质(Lamber与Phong),有需要的小伙伴们可以参考学习。
    2016-08-08
  • ThinkJS中如何使用MongoDB的CURD操作

    ThinkJS中如何使用MongoDB的CURD操作

    最近因为心血来潮想要试试thinkJS操作mongoDB,去官方文档看了看,默认是只给了mysql的配置,源代码也是没有配置mongo的,只有一个官方案例,无奈只能自己学习了,下面是自己的一些学习总结,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • Three.js学习之文字形状及自定义形状

    Three.js学习之文字形状及自定义形状

    今天小编带大家学习的是Three.js的文字形状与自定义形状,文章内容很详细,对大家学习Three.js或许有帮助,下面一起来看看吧。
    2016-08-08
  • 基于d3.js实现实时刷新的折线图

    基于d3.js实现实时刷新的折线图

    本文用实例演示如何用d3.js实现实时刷新的折线图,非常具有实用价值,需要的朋友可以参考下。
    2016-08-08
  • 浅谈JavaScript前端开发的MVC结构与MVVM结构

    浅谈JavaScript前端开发的MVC结构与MVVM结构

    以AngularJS为代表的MVVM结构框架或库这两年来在前端界真是火到不行,大有对抗传统jQuery绑定思想的趋势,这里我们结合传统的MVC结构,来浅谈JavaScript前端开发的MVC结构与MVVM结构
    2016-06-06
  • JavaScript库omit源码解析

    JavaScript库omit源码解析

    这篇文章主要为大家介绍了JavaScript库omit源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • node.js中的socket.io入门实例

    node.js中的socket.io入门实例

    这篇文章主要介绍了node.js中的socket.io入门实例,并对websocket等反向ajax技术做了介绍,需要的朋友可以参考下
    2014-04-04
  • 交互式可视化js库gojs使用介绍及技巧

    交互式可视化js库gojs使用介绍及技巧

    这篇文章主要介绍了如何使用可视化库gojs及使用时的小技巧,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2022-01-01

最新评论