What is RequireJS
实现CommonJS规范的API是同步加载模块的,而实现AMD规范的API是则是异步加载模块。所以理论上来说,AMD规范的非阻塞加载更加适合浏览器端。而RequireJS就是AMD规范的最好实现。
RequireJS 是一个JavaScript模块加载器。
Why RequireJS
- 异步“加载”: 通常网站都会把script脚本的放在html的最后,这样就可以避免浏览器执行js带来的页面阻塞。使用RequireJS,会在相关的js加载后执行回调函数,这个过程是异步的,所以它不会阻塞页面。
- 按需加载: 通过RequireJS,可以在需要加载js逻辑的时候再加载对应 的js模块,这样避免了在初始化网页的时候发生大量的请求和数据传输。
- 更加方便的模块依赖管理: 通过RequireJS的机制,能确保在所有的依赖模块都加载以后再执行相关的文件,所以可以起到依赖管理的作用。避免因为script标签顺序问题而导致依赖关系发生错误,这个函数未定义,那个变量undefine之类的。
RequireJS使用
需要在页面引入的文件
<script data-main="js/main" src="xxx/xxxx/require.js"></script>
页面的所有业务逻辑只需要在main.js里面写
其它引用的依赖通过require按需引入
require
//index.html
<!DOCTYPE html>
<html>
<head>
<title>Require Demo 1</title>
</head>
<body>
<div>
<h1>Require Demo 1 -- usage of Require()</h1>
<button id="contentBtn">Click me</button>
<p id="messagebox"></p>
</div>
<script data-main="js/script/main" src="js/lib/require.js" type="text/javascript"></script>
</body>
</html>
index.html通过
// js/script/main.js
require.config(
{
paths: {
'jquery': '../lib/jquery-1.7.2'
}
}
);
require(['jquery'],function ($) {
$(document).on('click','#contentBtn',function(){
$('#messagebox').html('You have access Jquery by using require()');
});
});
main.js文件,里面被一个匿名立即执行函数所包括。在require.config(…)中,可以配置许多配置项。上面在config中添加了一个path,在path配置了一个模块ID和路径的映射,这样在后续的所有函数中就可以直接通过模块ID来引入依赖,而不用再多次引入依赖多次输入路径带来的麻烦。
require(…)函数接受的第一个参数是,所依赖模块的一个数组。
传入的依赖有注入变量(函数),然后在回调函数中需要用到,就需要按照顺序在回调函数的参数中添加别名。例:通过别名$来使用jQuery的相关API。
有注入的模块需要放在无注入或者不需要调用模块的模块前面。
相对路径
-
如果
以上三条优先级逐级提升,如果有重叠,后面的根路径覆盖前面的根路径。
define
require定义一个模块是通过
define = function (name, deps, callback)
完成的。
第一个参数是定义模块名,第二个参数是传入定义模块所需要的依赖,第三个函数则是定义模块的主函数,主函数和require的回调函数一样,同样是在依赖加载完以后再调用执行。
- 没有任何依赖的时候
// js/script/desc.js
define(function(){
return{
decs : 'this js will be request only if it is needed',
};
})
// 然后在main.js的添加如下代码
// js/script/main.js
$('#messagebox').html('You have access Jquery by using require()');
+ require(['script/desc'],function(desc){
+ alert(JSON.stringify(desc));
- 有相关依赖的时候
// js/script/alertdesc.js
define(['script/desc'],function(desc){
return function (){
alert(JSON.stringify(desc));
};
})
// 然后在main.js的再做如下修改
// js/script/main.js
$('#messagebox').html('You have access Jquery by using require()');
// require(['script/desc'],function(desc){
// alert(JSON.stringify(desc));
+ require(['script/alertdesc'],function(alertdesc){
+ alertdesc();
require.config
将require.config()抽出来单独放一个js文件的参考例子
// 添加config.js
// js/script/config.js
define(function(){
require.config({
baseUrl: './js/',
paths: {
'jquery': 'lib/jquery-1.7.2'
}
});
});
// 替换main.js
// js/script/main.js
require(['config'],function(){
require(['jquery'],function ($) {
$(document).on('click','#contentBtn',function(){
$('#messagebox').html('You have access Jquery by using require()');
require(['script/alertdesc'],function(alertdesc){
alertdesc();
});
});
});
});
shim()为那些没有使用define()来声明依赖关系、设置模块的“浏览器全局变量注入”型脚本做依赖和导出配置。
// jQuery等库插件的配置
requirejs.config({
shim: {
'jquery.colorize': {
deps: ['jquery'],
exports: 'jQuery.fn.colorize'
},
'jquery.scroll': {
deps: ['jquery'],
exports: 'jQuery.fn.scroll'
},
'backbone.layoutmanager': {
deps: ['backbone']
exports: 'Backbone.LayoutManager'
}
}
});
实际运用
- 引用jQuery.bsgrid插件时
// main.js
require.config(
{
paths: {
'jquery': 'jquery.min.1.8.3',
'jquery.bsgrid': "../bsgrid/js/bsgrid.all.min",
'zhCN': "../bsgrid/js/grid.zh-CN.min"
},
shim: {
'zhCN': ['jquery'],
'jquery.bsgrid': {
deps: ['jquery', 'zhCN'],
exports: '$.fn.bsgrid'
}
}
}
);
//diagram里写bsgrid的init方法渲染表格。
require(['jquery', 'jquery.bsgrid', 'diagram'], function ($, grid, diagram) {
...
});
});
//表格自定义方法,方法名同w_render="XXX"一样。方法应该是公共方法,不然访问不到。
function XXX(record, rowIndex, colIndex, options){...}