设置/背景
我们正在尝试通过 RequireJS 加载 Facebook SDK:
require.config({
'shim': {
'facebook' : {
'exports': 'FB'
}
},
'paths': {
'facebook': '//connect.facebook.net/en_US/all/vb'
}
});
(/en_US/all/vb.js
基本和平时一样/en_US/all.js
,还包括FB的实验性音乐桥功能。但是,无论哪个版本的SDK都存在问题。)
...并且 SDK 的主体正在正确加载。但是,在 Facebook SDK 的初始化过程中,它会创建一个 iframe,该 iframe 会发出以下请求:
https://www.facebook.com/connect/ping?client_id=<CLIENT_ID>&domain=<DEVELOPMENT_SERVER>&origin=1&redirect_uri=<...>
...然后重定向到:
http://static.ak.facebook.com/connect/xd_arbiter.php?version=27#
...这反过来又返回一个带有脚本标签的最小 HTML 文档,该标签为 Facebook SDK 定义了许多额外的 javascript 模块。
问题
主要的 Facebook SDK vb.js和xd_arbiter.php脚本似乎都使用了一个require()
函数(在其默认顶级范围内的每个文件中定义)来加载 Facebook SDK 模块。
虽然主要的 Facebook SDK ( vb.js ) 是通过 RequireJS shim 加载的(因此 - 我相信 - 它的范围受 RequireJS 限制,因此require()
它定义的函数不会干扰 RequireJS 的全局require()
函数),因为xd_arbiter.php代码加载在 iframe 中,它以某种方式在浏览器的全局范围内执行。
这似乎导致与函数的 RequireJS 版本发生冲突——每次页面加载时,我们都会在xd_arbiter.php(第 13 行)中收到 RequireJS 错误:
Error: Invalid require call
http://requirejs.org/docs/errors.html#requireargs
...这似乎是由xd_arbiter.php代码调用它认为是自己的require()
函数引起的,但实际上是函数的 RequireJS 版本......因此传递给函数的参数对 RequireJS 无效。
我们目前正试图用一个不错的、通用的、相对标准的库(如 RequireJS)替换旧的遗留/自定义/手动模块系统,这让我们陷入了停顿。
问题
任何人都可以提出一种方法:
- 说服xd_arbiter.php定义一个不在全局范围内的
require()
函数, - 除了vb.js 之外,还可以通过 RequireJS 而不是 iframe加载xd_arbiter.php中定义的脚本,或者
- 说服 RequireJS 不定义全局
require()
函数(由于遗留原因,我们实际上在 RequireJS 的require()
函数周围使用了一个瘦包装器,所以我们现有的模块代码现在可以继续工作,所以改变我们调用定义 RequireJS 的方法的名称并不是什么大问题模块,因为它只在代码中的一处使用)
...没有做一些像黑客/分叉 RequireJS 或 Facebook SDK 这样的粗俗行为?
或者,我们是否在某个地方遗漏了一些我们应该采取不同方式的非常明显的事情?我对 RequireJS 和 Facebook SDK 都很陌生,所以我很清楚我们可能只是忽略了一些东西/在某个地方犯了一个愚蠢的错误。