最近准备将自己的项目替换为requirejs,在使用requirejs的过程中,模块的路径解析踩了一波坑,于是在这里记录一下。
requirejs中使用关于路径解析的配置主要有以下方面:通过requirejs.config配置、使用data-main属性声明、基于html文件的路径。
基于html文件的路径这里不做过多解释,就是所有的路径解析是基于这个html文件路径,这在实际项目中可能并不常见。
requirejs.config中主要涉及两个关键字段,即baseUrl和paths,而baseUrl是指定所有的模块都是基于这个路径的来寻找依赖的模块的。如有以下路径关系:

main模块依赖于hello模块,配置baseUrl:js/;加载时下面这样写即可正确解析:
requirejs.config({
baseUrl:'js/'
});
requirejs(['main'], function(main) {
})
requirejs中可以使用相对路径和绝对路径,绝对路径需要注意的是使用需要添加上.js后缀,不然无法解析。我们重点关注一下相对路径。
上文中的路径假设为以下目录结构:

baseUrl依旧不变,加载修改为以下内容:
requirejs(['./main/main'], function(main) {
})
这时使用开发者工具可以看到并没有报错,说明解析正确,这时相对路径是以js/路径为基础的,
我们再来看看加载模块时模块的依赖模块的相对路径情况,将代码修改为以下内容:
requirejs.config({
baseUrl:'js/',
paths: {
main: "main/main"
},
shim:{
main:{exports: 'main'}
}
});
requirejs(['main'], function(main) {
console.log(main);
})
main模块引入hello模块,如下:
define('main',['hello'], function(hello){
hello.fun1();
return {main: hello.fun1()};
});
在浏览器端可以看到此时报错:

改为相对路径./,如下
define('main',['./hello'], function(hello){
hello.fun1();
return {main: hello.fun1()};
});
报错依旧,说明此时相对路径是基于baseUrl的,不管是加载的主模块还是模块依赖的模块。
接下来再来看看paths,paths从上文中可以看到是基于baseUrl进行路径的join的,如果在在引入时使用相对路径如下:
requirejs(['./main'], function(main) {
console.log(main);
})
浏览器不报错,说明相对路径是基于join后的路径的。
如果没有设置baseUrl,就可以看到报错,如下:

说明此时的baseUrl被设置为了基于当前页面的路径。
此时设置一下data-main属性,如下:
<script data-main="js/main/hello.js" src="js/require.js"></script>
此时报错为

说明此时baseUrl是基于data-main属性的。
如果此时同时设置了baseUrl属性为js/,可以看到报错为:

说明此时data-main属性设置的路径被替换为了baseUrl。
基于以上的种种报错,我们可以得出一个结论就是:baseUrl是最高级的,data-main是次级的,当前页面是最低级的。baseUrl的设置依次按照以上高低级方式设置,而相对路径就是相对于baseUrl的。
不过这也带来一个问题就是在工程上,模块的复用非常常见,baseUrl可能随着页面而变,因此使用相对路径会有一定风险,而避免这种风险的方式就是使用data-main属性引入主模块,或者使用baseUrl+paths的方式,按照原作者的意思还是使用data-main方式最好。
网友评论