匿名的define()模块不匹配

问题描述 投票:108回答:7

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

错误:匿名的define()模块不匹配:function(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 file,关于它的short discussion在github问题页面

javascript jquery requirejs
7个回答
132
投票

就像AlienWebguy所说,按照文档,require.js can blow up if

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

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

A.在加载require.js之前,在脚本标记中加载非require.js独立包,或者

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


12
投票

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

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


10
投票

根据docs

如果在HTML中手动编写脚本标记以使用匿名的define()调用加载脚本,则可能会发生此错误。

还可以看到,如果您在HTML中手动编写脚本标记以加载具有一些命名模块的脚本,但随后尝试加载一个匿名模块,该模块最终与手动加载的脚本中的一个命名模块具有相同的名称编码脚本标记。

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

为了避免错误:

  • 确保通过RequireJS API加载调用define()的所有脚本。不要在HTML中手动编写脚本标记以加载其中包含define()调用的脚本。
  • 如果手动编写HTML脚本标记代码,请确保它只包含命名模块,并且不会加载与该文件中某个模块同名的匿名模块。
  • 如果问题是使用加载程序插件或匿名模块但是RequireJS优化器不用于文件绑定,请使用RequireJS优化程序。

9
投票

在开始使用reactjs时,我遇到了问题,作为一个初学者,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!') } };
})

当您使用带有字符串id的define时,当您尝试使用这样的模块时,您将避免此错误:

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

5
投票

请注意,某些浏览器扩展可以向页面添加代码。在我的情况下,我有一个“emmet in all textareas”插件与我的requireJs搞砸了。通过在浏览器中检查,确保没有额外的代码添加到文档中。


4
投票

现有的答案很好地解释了这个问题,但如果使用或之前使用requireJS包含脚本文件并不是一个简单的选择,因为遗留代码稍微麻烦的解决方法是在脚本标记之前从窗口范围中删除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>

不是最好的,但似乎工作,并节省了大量的重构。


1
投票

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

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

<script data-main="js/app.js" src="js/require.js"></script>

它会做什么将在加载require.js后加载你的脚本。

© www.soinside.com 2019 - 2024. All rights reserved.