转载地址:http://www.wlo-o.com/archives/354/
在一个内部项目里试用RequireJs,遇到个一个小问题。
问题现象是第一次请求时所有的依赖的文件路径错误,再次请求后问题消失,强制刷新后问题又复现。
原因是书写的不规范,初始化方式错误,同步运行代码无法调用异步加载的配置文件造成,下面是详细的。
先看看文档里的2处描述
部分1
baseUrl亦可通过RequireJS config手动设置。如果没有显式指定config及data-main,则默认的baseUrl为包含RequireJS的那个HTML页面的所属目录
。
部分2
require.js 在加载的时候会检察data-main 属性:
<!--when require.js loads it will inject another script tag
(with async attribute) for scripts/main.js-->
<script data-main="scripts/main" src="scripts/require.js"></script>
你可以在data-main指向的脚本中设置模板加载 选项,然后加载第一个应用模块。.注意:你在main.js中所设置的脚本是异步加载的
。所以如果你在页面中配置了其它JS加载,则不能保证它们所依赖的JS已经加载成功。
项目目录
.
├── images
├── js
│ ├── app
│ │ ├── invite.js
│ │ ├── mask.js
│ │ └── share.js
│ ├── lib
│ └── common.js
└── wechat
├── front
│ ├── invite.htm
│ └── share.htm
├── images
├── js
└── qudao
└── other.htm
配置文件common.jsn内容
requirejs.config({
baseUrl : '/js',
paths : {
'underscore' :'lib/underscore/underscore'
, 'jquery' : 'lib/jquery/dist/jquery'
, 'zepto' : 'lib/zepto/zepto'
, 'deferred' : 'lib/simply-deferred/deferred'
, 'zepto-custom': 'app/core/zepto-custom'
, 'zepto-custom-deferred' : 'app/core/zepto-custom-deferred'
// plugins
, 'text' : 'lib/requirejs-text/text'
, 'css' : 'lib/require-css/css'
, 'tpl' : 'lib/requirejs-underscore-tpl/underscore-tpl'
, 'weixinsdk':'http://res.wx.qq.com/open/js/jweixin-1.0.0.js'
, 'mask':'app/mask'//分享好友的图片提示
},
map: {
'*' : {
'zepto' : 'zepto-custom'
},
'zepto-custom' : {
'zepto' : 'zepto'
}
},
shim : {
'underscore' : {
exports : '_'
},
'zepto' : {
exports : 'Zepto'
}
}
});
在invite.htm、share.htm内引用下列脚本,common.js内是config配置,由于不是单页应用,每个页面都需要去加载配置,所以抽出来复用的。应用初始化只能放到下面。
之前的错误
代码
<script data-main="/js/common" src="/js/lib/requirejs/require.js"></script>
<script>
var wxData = {
"appId": "${appid!}"
};
require(['app/invite']);
</script>
上面问题就是初始化,common加载初始化是异步的,所以下面的require方法的默认baseUrl是/js
第一次加载的时候就报错了,第二次的时候配置文件缓存了,所以路径是没问题的。坑爹的问题出现了,第一次刷新页面的时候是app/invite加载没错,但是这个文件内依赖的zepto文件就找不到了,由于默认baseUrl的是js
所以找的是js/zepto.js
。自然报错了。
这种问题的解决方法官网上也有,改成下面的引用方式就行了.
<script src="/js/lib/requirejs/require.js"></script>
<script>
require(['/js/common.js'], function() {
require(['app/share']);
});
</script>
先加载配置文件,再加载页面对应的应用。问题解决。
PS:页面里不用写大量js引用的方式真不错,维护起来方便多了。