模块加载(require)及定义(define)时的路径
最近新公司在用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、
1 requirejs.config({ 2 baseUrl: 'js/common' 3 }); 4 // 实际加载的路径都是是 /lib.js 5 require(['./lib', 'lib'], function(Lib){ 6 Lib.say('hello'); 7 });
依赖于当前路径的下的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。
通过分析上面的四个例子,有了一个基本的思路。找相对于当前文件的根目录,这样就会更加清晰些。模块名可以为 "相对的" 或 "顶级的"。如果首字符为"."或".."则为"相对的"模块名