【问题标题】:Mismatched anonymous define() module不匹配的匿名 define() 模块
【发布时间】:2013-02-28 14:19:50
【问题描述】:

我第一次浏览我的webapp 时遇到此错误(通常在禁用缓存的浏览器中)。

错误:不匹配的匿名 define() 模块:函数 (require) {

HTML

<html>
   .
   .
   .
   <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
   <script> var require = { urlArgs: "v=0.4.1.32" }; </script>
   <script data-main="assets/js/main" src="assets/js/libs/require.js"></script>
   <script src="assets/js/ace/ace.js?v=0.4.1.32"></script>
   </body>
</html>

JS

$(function () {
    define(function (require) {
        // do something
    });
});

有谁知道这个错误的确切含义以及它发生的原因?

source fileshort discussion 在 github 问题页面中讨论它

【问题讨论】:

    标签: javascript jquery requirejs


    【解决方案1】:

    就像 AlienWebguy 所说,根据文档,require.js can blow up if

    • 您在自己的脚本标签中有一个匿名定义(“调用 define() 且没有字符串 ID 的模块”)(我假设它们实际上是指全局范围内的任何地方)
    • 您的模块名称冲突
    • 您使用加载器插件或匿名模块,但不使用 require.js 的优化器来捆绑它们

    我在包含使用 browserify 构建的 bundle 和 require.js 模块时遇到了这个问题。解决方案是:

    A.在 加载 require.js 之前,或

    加载脚本标签中的非 require.js 独立包

    B.使用 require.js(而不是脚本标签)加载它们

    【讨论】:

    • 有冲突的名字很常见
    • 另一种可能的解决方案,在某些使用匿名模块的特殊情况下,是覆盖 requirejs.onError 函数,以防止 requirejs 抛出的默认错误异常停止连续执行的模块或代码。跨度>
    • 刚刚添加了一个拉取请求 (github.com/requirejs/requirejs/pull/1763) 来放宽这个确切的情况。我认为这是一个非常普遍的问题。
    • 感谢您之前告诉我加载它们!我不知道为什么这个技巧不在 requirejs 自己的文档中......这就是 stack 派上用场的地方
    • 您的评论对我很有帮助。 @xtrm
    【解决方案2】:

    在开始使用 require.js 时,我遇到了这个问题,作为初学者,docs 也可以用希腊语编写。

    我遇到的问题是,大多数初学者示例在您应该使用“字符串 id”时使用“匿名定义”。

    匿名定义

    define(function() {
            return { helloWorld: function() { console.log('hello world!') } };
     })
        
      
    define(function() {
            return { helloWorld2: function() { console.log('hello world again!') } };
     })
    

    用字符串 id 定义

    define('moduleOne',function() {
        return { helloWorld: function() { console.log('hello world!') } };
    })
    
     define('moduleTwo', function() {
          return { helloWorld2: function() { console.log('hello world again!') } };
    })
    

    当您使用 define with a string id 时,您将在尝试像这样使用模块时避免此错误:

    require([ "moduleOne", "moduleTwo" ], function(moduleOne, moduleTwo) {
        moduleOne.helloWorld();
        moduleTwo.helloWorld2();
    });
    

    【讨论】:

    • (仅供后人参考)这种方法一些缺点,如in the docs 所述:“define() 调用通常包含模块名称…… " …以及this GitHub thread。这似乎是初学者示例中排除列出名称的原因。
    【解决方案3】:

    我遇到了这个错误,因为我包含了 requirejs 文件以及直接包含在脚本标记中的其他库。这些库(如 lodash)使用了与 require 的定义冲突的定义函数。 requirejs 文件是异步加载的,所以我怀疑 require 的定义是在其他库定义之后定义的,因此发生了冲突。

    要消除错误,请使用 requirejs 包含所有其他 js 文件。

    【讨论】:

    • 原来很多库都做这样的事情,或者至少使用/导出这样的功能。我会建议大家 - 如果他们使用 require - import everything with require :)
    【解决方案4】:

    根据docs

    如果您在 HTML 中手动编写脚本标记以加载带有 匿名define()调用,会出现这个错误。

    如果你也看过 在 HTML 中手动编写脚本标记以加载包含几个 命名模块,然后尝试加载一个匿名模块 与加载的脚本中的命名模块之一同名 通过手动编码的脚本标签。

    最后,如果你使用加载器 插件或匿名模块(调用 define() 的模块没有 string ID) 但不要使用 RequireJS 优化器来组合文件 一起,可能会发生此错误。优化器知道如何命名 匿名模块正确,以便它们可以与其他模块组合 优化文件中的模块。

    为了避免错误:

    • 确保通过 RequireJS API 加载所有调用 define() 的脚本。 不要在 HTML 中手动编写脚本标签来加载具有 define() 调用它们。

    • 如果您手动编写 HTML 脚本标签,请 确保它只包括命名模块,并且一个匿名模块 将与该文件中的模块之一具有相同的名称 已加载。

    • 如果问题是使用加载器插件或匿名 模块,但 RequireJS 优化器不用于文件捆绑,使用 RequireJS 优化器。

    【讨论】:

    【解决方案5】:

    现有的答案很好地解释了这个问题,但是如果由于遗留代码而使用或在 requireJS 之前包含你的脚本文件不是一个简单的选择,一个稍微hacky的解决方法是在你的脚本标记之前从窗口范围中删除 require ,然后在之后恢复它.在我们的项目中,它被包装在服务器端函数调用之后,但实际上浏览器会看到以下内容:

        <script>
            window.__define = window.define;
            window.__require = window.require;
            window.define = undefined;
            window.require = undefined;
        </script>
        <script src="your-script-file.js"></script>        
        <script>
            window.define = window.__define;
            window.require = window.__require;
            window.__define = undefined;
            window.__require = undefined;
        </script>
    

    不是最整洁的,但似乎可以工作并且节省了很多折射。

    【讨论】:

    • 实际上永远不要这样做。它在 IE 中无法正常工作。
    • 间歇性地在 IE 中,包含在 requireJS 中的脚本会在它们的窗口范围内定义缺失,即使在这些变量恢复后出现 require 命令也是如此。我们一直无法弄清楚为什么会发生这种情况,所以我们放弃了这个老套的解决方案。
    • @jcbdrn 这不仅仅是在 IE 上。我已经看到它发生在其他平台上。原因是 HTML 规范确实提供了关于同步脚本执行顺序的保证但仅相对于其他同步脚本。它不保证 异步 脚本相对于同步脚本的执行(反之亦然)。因此,在此处答案中显示的代码中,可以在任意两个script 元素之间执行异步脚本。
    • 如果你有能力编辑你正在导入的 bundle js,你可以像这样包装整个东西:(function(){ var define = undefined; // the UMD registration code won't find the global 'define' anymore! // generated content goes here })()
    • 感谢,对于有很多团队的遗留应用程序,这是理想的解决方案...:/
    【解决方案6】:

    请注意,某些浏览器扩展可以向页面添加代码。 就我而言,我有一个“所有文本区域中的 Emmet”插件,它弄乱了我的 requireJs。 通过在浏览器中检查文档,确保没有额外的代码被添加到您的文档中。

    【讨论】:

      【解决方案7】:

      或者你可以使用这种方法。

      • 在您的代码库中添加 require.js
      • 然后通过该代码加载您的脚本

      &lt;script data-main="js/app.js" src="js/require.js"&gt;&lt;/script&gt;

      它会在加载 require.js 后加载你的脚本

      【讨论】:

        【解决方案8】:

        对于基于require.js 的项目,我也在浏览器控制台上看到了同样的错误。正如MISMATCHED ANONYMOUS DEFINE() MODULEShttps://requirejs.org/docs/errors.html 中所述,此错误有多种原因,在我的案例中有趣的是:If the problem is the use of loader plugins or anonymous modules but the RequireJS optimizer is not used for file bundling, use the RequireJS optimizer。事实证明,Google Closure 编译器习惯于在构建期间合并/缩小 Javascript 代码。解决办法是去掉Google closure编译器,改用require.js的优化器(r.js)来合并js文件。

        【讨论】:

          猜你喜欢
          • 2023-03-30
          • 2016-12-27
          • 2013-05-29
          • 1970-01-01
          • 2016-04-28
          • 2020-05-09
          • 1970-01-01
          • 2015-03-24
          • 1970-01-01
          相关资源
          最近更新 更多