现在,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中的函数需要依赖一些应用。这就是循环依赖。
复制代码 代码如下: