不匹配的匿名define()模块

当我第一次浏览我的webapp时(通常是在禁用caching的浏览器中),我收到了这个错误。

错误:不匹配的匿名定义()模块: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 }); }); 

无论如何知道这个错误究竟意味着什么,为什么发生?

源文件 ,关于它在github问题页面的简短讨论

就像AlienWebguy所说的,根据文档, require.js可能会炸掉

  • 你有一个匿名定义(“ 模块调用define()没有stringID ”)在其自己的脚本标签(我假设他们指的是全球范围内的任何地方)
  • 您的模块名称有冲突
  • 您使用加载器插件或匿名模块,但不要使用require.js的优化器来捆绑它们

我在使用browserify和require.js模块一起构buildbundle时遇到了这个问题。 解决办法是:

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

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

我有这个错误,因为我包括了requirejs文件以及直接包含在脚本标记中的其他库。 那些图书馆(如lodash)使用了一个与需求定义相冲突的定义函数。 requirejs文件是asynchronous加载的,所以我怀疑require的定义是在其他库定义之后定义的,因此冲突。

为了摆脱这个错误,使用requirejs包含所有其他的js文件。

根据文档 :

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

另外,如果您手动在HTML中编写脚本标记来加载具有几个命​​名模块的脚本,但是却尝试加载一个匿名模块,该模块最终与手动加载的脚本中的某个命名模块具有相同的名称编码的脚本标签。

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

为了避免这个错误:

  • 确保通过RequireJS API加载所有调用define()的脚本。 不要在HTML中手动编写脚本标记来加载其中已定义()调用的脚本。

  • 如果您手动编写HTML脚本标记,请确保它只包含命名模块,并且不会加载与该文件中的某个模块具有相同名称的匿名模块。

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

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

在开始使用reactjs的时候,我遇到了这个问题,作为一个初学者,这个文档也可能写在希腊语里。

我碰到的问题是,当你应该使用“stringID”时,大多数初学者的例子使用“匿名定义”。

匿名定义

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

用stringid定义

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

当你使用一个stringID的定义,然后你会避免这个错误,当你尝试使用像这样的模块:

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

现有的答案很好地解释了这个问题,但是如果在使用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> 

不是最好的,但似乎工作,并已经节省了大量的耐火材料。

这种方式适用于我:

包含require.js 之前包含其他javascipts。 这样做的安全方法是在html标签之外包含require.js

 <html> <body> <script src="other/library.js"></script> <script> console.log("Some init script"); </script> </body> <!-- require.js goes here --> <script data-main="main_app" src="path/to/require.js"></script> </html>