RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一。最新版本的RequireJS压缩后只有14K,堪称非常轻量。它还同时可以和其他的框架协同工作,使用RequireJS可以提升前端代码质量。
在整个require中,主要的方法为:require和define
函数方法:
define(id?, dependencies?, factory)
总共有三个参数:id 定义的模块名字,一般在config 中会定义;dependencies为需要的依赖模块;factory为定义的模块。其中factory 为必填,另外两个为非必填项。
根据上面的参数配置可以看出,define 总共分为两种,第一种为独立模块,不依赖其他模块。第二种为非独立模块,需要依赖其他模块。
注:define定义的模块可以返回任何值,不限于对象。
独立模块
一种通过一个对象简易定义:
define({
name: "aimee",
method1: function() {},
method2: function() {}
})
*注:这样定义的对象如果被多处引用,那么引用的地方会共享这个对象的引用。
另一种通过一个函数来定义副本对象模块:
define(function () {
//Do setup work here
return {
name: "aimee",
method1: function() {},
method2: function() {}
}
})
这种自由度更高,可以在函数中处理其他逻辑。
非独立模块
需要引入依赖模块,在其他模块加载完,定义自己的模块,此时返回的method方法中包含模块1 和模块2的函数的调用。
define(['module1', 'module2'], function(m1, m2) {
return {
method: function() {
m1.methodA();
m2.methodB();
}
}
})
当定义多个时,可以通过function 函数里接受一个require默认参数来处理。
define(
[ 'dep1', 'dep2', 'dep3', 'dep4', 'dep5', 'dep6', 'dep7', 'dep8'],
function(dep1, dep2, dep3, dep4, dep5, dep6, dep7, dep8){
...
}
);
可以这样写
define(
function (require) {
var dep1 = require('dep1'),
dep2 = require('dep2'),
dep3 = require('dep3'),
dep4 = require('dep4'),
dep5 = require('dep5'),
dep6 = require('dep6'),
dep7 = require('dep7'),
dep8 = require('dep8');
...
}
})
通过define定义模块后,可以使用require来调用模块。
require(dependencies?, factory, errorCallback)
require的参数有:dependencies 为依赖模块,非必填;factory 处理函数,必填;errorCallback 为 错误的回调,非必填;
require(
['foo', 'bar'],
function ( foo, bar ) {
foo.doSomething();
bar.doSomething();
},
function(err){
console.log(err)
}
);
上述例子,在foo 和 bar 模块加载完成后,再在函数中执行foo 和 bar 的方法,如果有错误则到错误的回调函数中,并接受一个error对象作为参数。
全局error事件监听,所有没有被上面的方法捕获的错误,都会被触发这个监听函数。
requirejs.onError = function (err) {
// ...
};
define中require异步加载
例子中,define定义了一个模块,其中foobar 需要依赖 foo 和bar 模块的方法,由于require 为异步,此时return 的结果可以通过isReady 来判断是否加载完成。
define(function ( require ) {
var isReady = false, foobar;
require(['foo', 'bar'], function (foo, bar) {
isReady = true;
foobar = foo() + bar();
});
return {
isReady: isReady,
foobar: foobar
};
});
可以用过promise 来实现
define(function ( require ) {
var obj;
require(['foo', 'bar'], function (foo, bar) {
isReady = true;
obj.resolve({foobar:foo() + bar()});
});
return obj.promise()
});
上面代码返回一个promise对象,可以在该对象的then方法,指定下一步的动作。
小结
require 和 define 函数内部机制差不多,不一样的地方是 define 的回调函数需要有 return 语句返回模块对象,这样 define 定义的模块才能被其他模块引用;require 的回调函数不需要 return 语句。
paths:
可以配置模块的引用路径,可以本地相对路径,也可以是外部路径,可以提供多个路径,当第一个失败时,会使用第二个路径。
简单配置如下
require.config({
paths: {
jquery: [
'//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
'lib/jquery'
]
}
});
baseUrl:
baseUrl 指定了一个目录,然后requirejs基于这个目录来寻找依赖的模块。
可以通过config 来配置,也可以通过引入requirejs 文件的data-main属性定义。
shim:
用于配置在脚本/模块外面并没有使用RequireJS的函数依赖并且初始化函数。假设underscore并没有使用 RequireJS定义,但是你还是想通过RequireJS来使用它,那么你就需要在配置中把它定义为一个shim。
<script src="js/require.js" data-main="js/main.js"></script>
或者
requirejs.config({
baseUrl: 'js'
});
requirejs 提供多种插件,具体插件详情可以查看文档 插件类型
define([
'backbone',
'text!templates.html'
], function( Backbone, template ){
// ...
});
以上为text 插件,通过在模块名前添加text!来指定插件类型,在回调函数中能够通过template来获取模板的内容,格式为字符串。
requireJS提供一个基于node.js的命令行工具r.js,用来压缩多个js文件。它的主要作用是将多个模块文件压缩合并成一个脚本文件,以减少网页的HTTP请求数。
具体实现可以参考官方文档
参考:
官方文档api: requirejs.org
官方文档git:requirejs-git