RequireJS - 在 require 流和内联中加载 AMD 模块

Posted

技术标签:

【中文标题】RequireJS - 在 require 流和内联中加载 AMD 模块【英文标题】:RequireJS - Loading AMD modules both inside a require flow and inline 【发布时间】:2013-07-31 07:09:23 【问题描述】:

考虑一下:

<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");

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

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

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

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

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

【问题讨论】:

【参考方案1】:

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

如果通过eval 传递,您可以使用不允许匿名define 执行的修改过的RequireJS 库。此外,您可以通过在下面的 sn-p 中删除 name 上的字符串类型检查来禁止任何 define 调用。

以下 sn-p 是对 RequireJS 的修改,如果被 eval 调用,它将忽略匿名定义。您可以找到fully modified require.js in this GitHub Gist。

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

Demo

// 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;
            
        
    

    // ...

【讨论】:

以上是关于RequireJS - 在 require 流和内联中加载 AMD 模块的主要内容,如果未能解决你的问题,请参考以下文章

RequireJS:“requirejs”和“require”函数之间的区别

RequireJS中的define和require有啥区别? [复制]

requireJS学习

Node.js require() 与 RequireJS?

requirejs 小结

Requirejs常用配置和应用