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 相关文章推荐
javascript Zifa FormValid 0.1表单验证 代码打包下载
Jun 08 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
Aug 08 Javascript
javascript中的变量作用域以及变量提升详细介绍
Oct 24 Javascript
js实现的类似于asp数据字典的数据类型代码实例
Sep 03 Javascript
jQuery oLoader实现的加载图片和页面效果
Mar 14 Javascript
jsMind通过鼠标拖拽的方式调整节点位置
Apr 13 Javascript
jQuery往返城市和日期查询实例讲解
Oct 09 Javascript
运用js教你轻松制作html音乐播放器
Apr 17 Javascript
js获取浏览器的各种属性
Apr 27 Javascript
vue使用drag与drop实现拖拽的示例代码
Sep 07 Javascript
创建echart多个联动的示例代码
Nov 23 Javascript
AJAX实现指定部分页面刷新效果
Oct 16 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
实例(Smarty+FCKeditor新闻系统)
2007/01/02 PHP
php安全配置 如何配置使其更安全
2011/12/16 PHP
php基本函数汇总
2015/07/09 PHP
javascript数组使用调用方法汇总
2007/12/08 Javascript
JS的递增/递减运算符和带操作的赋值运算符的等价式
2007/12/08 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
2010/11/14 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
BootStrap table表格插件自适应固定表头(超好用)
2016/08/24 Javascript
js简易版购物车功能
2017/06/17 Javascript
基于EasyUI的基础之上实现树形功能菜单
2017/06/28 Javascript
基于vue cli重构多页面脚手架过程详解
2018/01/23 Javascript
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
jquery实现动态添加附件功能
2018/10/23 jQuery
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
react组件基本用法示例小结
2020/04/27 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
vue-quill-editor的使用及个性化定制操作
2020/08/04 Javascript
[01:23:59]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 VP vs Secret
2018/04/03 DOTA
Python中的条件判断语句基础学习教程
2016/02/07 Python
详解K-means算法在Python中的实现
2017/12/05 Python
浅谈Python使用Bottle来提供一个简单的web服务
2017/12/27 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
利用Python对文件夹下图片数据进行批量改名的代码实例
2019/02/21 Python
Python进阶之@property动态属性的实现
2019/04/01 Python
python kafka 多线程消费者&amp;手动提交实例
2019/12/21 Python
详解Python中的分支和循环结构
2020/02/11 Python
Python3操作YAML文件格式方法解析
2020/04/10 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
2021/02/02 Python
css3 线性渐变和径向渐变示例附图
2014/04/08 HTML / CSS
canvas 如何绘制线段的实现方法
2018/07/12 HTML / CSS
Ann Taylor官方网站:美国最大的女性产品制造商之一
2016/09/14 全球购物
MYSQL基础面试题
2012/05/13 面试题
《曹刿论战》教学反思
2014/03/02 职场文书
《北大荒的秋天》教学反思
2014/04/14 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书