最近新公司在用requireJS进行JS的整合,刚开始接触有点蒙,于是深入了解了一下。requireJS主要是为了解决一下两个问题:
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
但是在使用的时候有个最大的困惑就是加载模块时候的路径问题,在requirejs的模块路径解析里, baseUrl
是非常基础的概念。在demo.html里加载requirejs,同时在requirejs所在的script上声明 data-main
属性,那么,requirejs加载下来后,它会做两件事件:
- 加载js/main.js
- 将baseUrl设置为data-main指定的文件所在的路径,这里是 js/。
如果没有通过 data-main
属性指定 baseUrl
,也没有通过config的方式显示声明 baseUrl
,那么 baseUrl
默认为加载requirejs的那个页面所在的路径。
requirejs.config({
baseUrl: 'js'
});
baseUrl+path可以使依赖更加灵活和简单:
requirejs.config({
baseUrl: 'js',
paths: {
model: 'common/model'
}
});
path使用要点:
1、没有在paths规则里定义,于是为 baseUrl + demo.js => js/demo.js
2、model已经在paths里定义,于是为baseUrl + common/model + apple.js => js/common/model/apple.js
3、model尽管已经在paths里定义,但是 ../model/demo
并不是以model开头,于是为 baseUrl + ../model/demo.js => model/apple.js,也就是说model与js在同一层级。
在requireJS中最令人困惑的也就是"./module"的用法:
demo1、
requirejs.config({
baseUrl: 'js/common'
});
// 实际加载的路径都是是 /lib.js
require(['./lib', 'lib'], function(Lib){
Lib.say('hello');
});
依赖于当前路径的下的lib.js文件。
demo2、
通过 define
定义模块A时,模块A依赖的模块B,如果是 ./module
形式,则基于模块A所在目录解析模块B的路径。
main.js和lib.js
requirejs.config({
baseUrl: 'js'
});
// 依赖lib.js,实际加载的路径是 js/common/lib.js,而lib模块又依赖于util模块('./util'),解析后的实际路径为 js/common/util.js
require(['common/lib'], function(Lib){
Lib.say('hello');
});
// 依赖util模块
define(['./util'], function(Util){
return {
say: function(msg){
Util.say(msg);
}
};
});
demo3、
lib模块依赖的util模块,最终解析出来的路径是 js/util.js
main.js和lib.js
requirejs.config({
baseUrl: 'js',
paths: {
lib: 'common/lib'
}
}); // 实际加载的路径是 js/common/lib.js
require(['lib'], function(Lib){
Lib.say('hello');
});
// util模块解析后的路径为 js/util.js
define(['./util'], function(Lib){
return {
say: function(msg){
Lib.say(msg);
}
};
});
可以理解为util.js是依赖于在lib的根目录下得文件。
demo4、
main.js和lib.js
requirejs.config({
baseUrl: 'js',
paths: {
common: 'common'
}
}); // 实际加载的路径是 js/common/lib.js
require(['common/lib'], function(Lib){
Lib.say('hello');
});
define(['./util'], function(Lib){
return {
say: function(msg){
Lib.say(msg);
}
};
});
最终解析的util为js/common/util.js。
通过分析上面的四个例子,有了一个基本的思路。找相对于当前文件的根目录,这样就会更加清晰些。模块名可以为 "相对的" 或 "*的"。如果首字符为"."或".."则为"相对的"模块名