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


Posted in Javascript onSeptember 04, 2014

现在,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 相关文章推荐
jquery键盘事件介绍
Jan 31 Javascript
js修改input的type属性问题探讨
Oct 12 Javascript
在每个匹配元素的外部插入新元素的方法
Dec 20 Javascript
JavaScript中的ParseInt(&quot;08&quot;)和“09”返回0的原因分析及解决办法
May 19 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
Jun 13 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
Dec 28 Javascript
原生js实现手风琴功能(支持横纵向调用)
Jan 13 Javascript
JavaScript实现简单的树形菜单效果
Jun 23 Javascript
vue组件中使用props传递数据的实例详解
Apr 08 Javascript
微信小程序搭建(mpvue+mpvue-weui+fly.js)的详细步骤
Sep 18 Javascript
vue使用v-model进行跨组件绑定的基本实现方法
Apr 28 Vue.js
关于antd tree 和父子组件之间的传值问题(react 总结)
Jun 02 Javascript
用console.table()调试javascript
Sep 04 #Javascript
js设置cookie过期当前时间减去一秒相当于立即过期
Sep 04 #Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
Sep 04 #Javascript
jQuery之Deferred对象详解
Sep 04 #Javascript
Javascript Objects详解
Sep 04 #Javascript
加随机数引入脚本不让浏览器读取缓存
Sep 04 #Javascript
js不能获取隐藏的div的宽度只能先显示后获取
Sep 04 #Javascript
You might like
mysql5详细安装教程
2007/01/15 PHP
php5 mysql分页实例代码
2008/04/10 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
2013/04/10 PHP
jquery $.each()使用探讨
2013/09/23 Javascript
排序算法的javascript实现与讲解(99js手记)
2014/09/28 Javascript
纯JS前端实现分页代码
2016/06/21 Javascript
jquery把int类型转换成字符串类型的方法
2016/10/07 Javascript
jQuery倒计时代码(超简单)
2017/02/27 Javascript
AngularJS+bootstrap实现动态选择商品功能示例
2017/05/17 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
2017/10/16 Javascript
Vue2 SSR渲染根据不同页面修改 meta
2017/11/20 Javascript
利用vue和element-ui设置表格内容分页的实例
2018/03/02 Javascript
vue-devtools的安装步骤
2018/04/23 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
vue中子组件传递数据给父组件的讲解
2019/01/27 Javascript
前端Vue项目详解--初始化及导航栏
2019/06/24 Javascript
微信小程序全局变量改变监听的实现方法
2019/07/15 Javascript
PHP读取远程txt文档到数组并实现遍历
2020/08/25 Javascript
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
2020/11/18 Vue.js
[15:20]DOTA2亚洲邀请赛总决赛开幕式表演:羽泉献唱
2017/04/05 DOTA
Python面向对象之继承代码详解
2018/01/29 Python
Python实现XML文件解析的示例代码
2018/02/05 Python
pandas值替换方法
2018/07/10 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
给keras层命名,并提取中间层输出值,保存到文档的实例
2020/05/23 Python
Python 利用OpenCV给照片换底色的示例代码
2020/08/03 Python
纯CSS3实现圆角效果(含IE兼容解决方法)
2014/05/07 HTML / CSS
妇科医生自荐信
2013/11/05 职场文书
亲属关系公证书
2014/04/08 职场文书
建筑专业毕业生求职信
2014/09/30 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
2015年秋学期师德师风建设工作总结
2015/10/23 职场文书
mongodb清除连接和日志的正确方法分享
2021/09/15 MongoDB