4

考虑一下:

<script src='global.js'></script>
<script src='require.js'></script>
<script>
require(['modular_foo'], function() {
  //do stuff
});

...在 global.js 中,我们有,除其他外:

//global.js
$.getScript("modular_bar.js");

modules_foo 和 modules_bar 都是匿名定义的 AMD 模块。使用 requireJS,加载类似上面的东西会给你我们最喜欢的错误,不匹配的匿名 define() 模块

关于为什么会发生该错误已经足够好了(如果您想知道,请在该页面上阅读),但问题是,如果您无法摆脱这种情况怎么办?

我正在一个成熟的平台上工作,该平台正在逐渐迁移到 RJS 流程,目前无法同时使用内联遗留脚本(其中一些具有 AMD 检查来触发 define())和我们的 requireJS 入口点.

在某些情况下,我可以简单地将内联 AMD 兼容脚本放在加载 require.js 库的上方,但是当您需要根据 DOM 内容异步加载其他东西(modular_bar.js)时,这不起作用。我也可以从外部加载到 RJS 的文件中注释掉所有 AMD 检查,但这可以防止它们与在模块化流程中加载时不兼容。

有没有人有类似经历的?你如何混合你的流程来克服这些冲突?

4

1 回答 1

0

我没有在生产环境中使用此解决方案的经验,但我在这个问题上花了几天时间找出解决它的最佳方法。

你可以使用一个修改过的 RequireJS 库,它不允许匿名define执行,如果它正在通过eval. 此外,您可以通过删除下面代码段中define的字符串类型检查来禁止任何调用。name

以下代码片段是对 RequireJS 的修改,如果被eval. 您可以在此 GitHub Gist中找到完全修改require.js的内容。

代码依赖于parse-stack。如果您不能在 RequireJS 之前包含该库,我建议将其连接到文件顶部。

演示

// This is a snippet of RequireJS
// ...
define = function (name, deps, callback) {
    var node, context;

    // We will allow named modules to be defined by `eval`
    if (!(typeof name == 'string' || name instanceof String))
    {
        var stack = parseStack(new Error());

        // If we find any eval in the stack, do not define the module
        // This is to avoid the "Mismatched anonymous define() module" error
        // Caused by executing an anonymous define without requireJS
        for(var i = 0; i < stack.length; i++)
        {
            if(stack[i].name == "eval")
            {
                return;
            }
        }
    }

    // ...
于 2014-09-23T23:58:39.277 回答