javascript 匿名define()模块不匹配

m528fe3b  于 2023-06-20  发布在  Java
关注(0)|答案(8)|浏览(109)

当我第一次浏览我的webapp时(通常是在禁用缓存的浏览器中),我得到了这个错误。
错误:匿名define()模块不匹配:public function(){

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问题页面中有一个关于它的short discussion

t98cgbkg

t98cgbkg1#

就像AlienWebguy说的,根据文档,require.js可能会在以下情况下崩溃:

  • 你有一个匿名的define(“modules that call define()without no string ID”)在它自己的script标签中(我假设它们实际上是指全局范围内的任何地方)
  • 您的模块具有冲突的名称
  • 您使用加载器插件或匿名模块,但不使用require.js的优化器来捆绑它们

我在将browserify构建的bundle与require.js模块一起包含时遇到了这个问题。解决办法是:
A.在加载 * require.js之前,在脚本标记 * 中加载非require.js独立包,或者
B.使用require.js加载它们(而不是脚本标签)

4nkexdtk

4nkexdtk2#

在开始使用require.js时,我遇到了这个问题,作为初学者,文档也可能是用希腊语写的。
我遇到的问题是,大多数初学者的例子使用“匿名定义”,而你应该使用“字符串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和一个字符串id时,当你尝试像这样使用模块时,你会避免这个错误:

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

zbq4xfa03#

我之所以会出现这个错误,是因为我将requirejs文件沿着其他直接包含在脚本标记中的库一起包含了进去。这些库(如lodash)使用了一个与require的define冲突的define函数。requirejs文件是异步加载的,所以我怀疑require的定义是在其他库定义之后定义的,因此产生了冲突。
要消除这个错误,请使用requirejs包含所有其他的js文件。

sczxawaw

sczxawaw4#

根据文件:
如果您在HTML中手动编写脚本标记以加载带有匿名define()调用的脚本,则可能会发生此错误。
如果您在HTML中手动编写脚本标记以加载具有几个命名模块的脚本,但随后尝试加载一个匿名模块,该模块最终与手动编写的脚本标记加载的脚本中的一个命名模块同名,则也会出现此问题。
最后,如果您使用加载器插件或匿名模块(调用define()而没有字符串ID的模块),但不使用RequireJS优化器将文件组合在一起,则可能会发生此错误。优化器知道如何正确命名匿名模块,以便它们可以与优化文件中的其他模块组合。
要避免错误:

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

ioekq8ef5#

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

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

不是最整洁的,但似乎工作,并已节省了大量的折射。

iyfjxgzm

iyfjxgzm6#

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

8i9zcol2

8i9zcol27#

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

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

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

它会做什么,它会在加载require.js后加载您的脚本

rkkpypqq

rkkpypqq8#

我也看到了基于require.js的项目的浏览器控制台上的相同错误。正如在https://requirejs.org/docs/errors.htmlMISMATCHED ANONYMOUS DEFINE() MODULES中所述,此错误有多种原因,在我的案例中有趣的一个是: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文件。

相关问题