2013-03-12 18 views
91

Otrzymuję ten błąd podczas przeglądania mojego webapp po raz pierwszy (zwykle w przeglądarce z wyłączoną pamięcią podręczną).Niedopasowane anonimowe moduł define()

Error: Mismatched anonymous define() module: 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 
    }); 
}); 

W każdym razie wiem, co dokładnie ten błąd oznacza i dlaczego jej dzieje?

source file, A short discussion o tym w stronę zagadnień GitHub

Odpowiedz

106

Jak AlienWebguy powiedział za docs, require.js can blow up jeśli

  • masz anonimowy define ("moduły, które wywołują metodę define() bez identyfikatora łańcucha") w osobnym skrypcie t tag (zakładam faktycznie oznaczają one nigdzie w zasięgu globalnym)
  • masz moduły, które mają sprzeczne nazwy
  • użyć wtyczek do załadunku lub anonimowych modułów, ale nie używaj optymalizatora require.js do bundle im

Miałem ten problem, włączając w to pakiety zbudowane z przeglądarką obok modułów require.js. Roztwór albo:

A. załadowania nie require.js wiązek jednostkowe w znacznikach skryptu przed require.js załadowaniu lub

B. załadować je za pomocą require.js (zamiast znacznik skryptu)

+0

nazwy będące w konflikcie są często spotykane –

+1

Innym możliwym rozwiązaniem, w niektórych szczególnych przypadkach z anonimowymi modułami, jest zastąpić funkcję requirejs.onError, aby zapobiec wyjątkowi wyjątków zgłaszanych przez requirejs, który zatrzymuje kolejne moduły lub kod do wykonania. – xtrm

8

Per docs:

If you manually code a script tag in HTML to load a script with an anonymous define() call, this error can occur.

Also seen if you manually code a script tag in HTML to load a script that has a few named modules, but then try to load an anonymous module that ends up having the same name as one of the named modules in the script loaded by the manually coded script tag.

Finally, if you use the loader plugins or anonymous modules (modules that call define() with no string ID) but do not use the RequireJS optimizer to combine files together, this error can occur. The optimizer knows how to name anonymous modules correctly so that they can be combined with other modules in an optimized file.

To avoid the error:

  • Be sure to load all scripts that call define() via the RequireJS API. Do not manually code script tags in HTML to load scripts that have define() calls in them.

  • If you manually code an HTML script tag, be sure it only includes named modules, and that an anonymous module that will have the same name as one of the modules in that file is not loaded.

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

+3

Czy to anonimowo zdefiniowany moduł? https://github.com/requirejs/example-multipage/blob/master/www/js/app/controller/c1.js – streetlight

10

Miałem ten błąd, ponieważ dodałem plik requirejs wraz z innymi librairies dołączonymi bezpośrednio do znacznika script. Te librairies (jak lodash) używały funkcji definiującej, która była sprzeczna z definicją require. Plik requirejs ładował się asynchronicznie, więc podejrzewam, że definicja wymagania została zdefiniowana po zdefiniowaniu innych bibliotek, stąd konflikt.

Aby pozbyć się błędu, dołącz wszystkie inne pliki js, używając requirejs.

+0

Okazało się, że wiele bibliotek robi coś takiego, lub przynajmniej używa/eksportuje taką funkcję. Doradzę wszystkim - jeśli będą wymagać - import ** wszystko ** z wymaganiem :) –

5

Należy pamiętać, że niektóre rozszerzenia przeglądarki mogą dodawać kod do stron. W moim przypadku miałem wtyczkę "Emmet we wszystkich textareas", która zepsuła moje wymagania. Upewnij się, że do dokumentu nie został dodany żaden dodatkowy kod, sprawdzając go w przeglądarce.

2

Istniejące odpowiedzi wyjaśniają problem dobrze, ale jeśli uwzględnienie plików skryptu przy użyciu lub przed wymaganiem JS nie jest łatwą opcją ze względu na starszy kod, nieco odstręczającym rozwiązaniem jest usunięcie wymagania z zakresu okna przed tagiem skryptu, a następnie przywrócenie go. posłowie.W naszym projekcie to jest owinięty za po stronie serwera wywołania funkcji, ale skutecznie przeglądarka widzi, co następuje:

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

Not neatest ale wydaje się działać i uratował wiele refractoring.

+4

Właściwie nigdy tego nie rób. To nie działa poprawnie w IE. – jcbdrn

+0

jakiś szczególny powód, dlaczego to nie działa w IE? –

+2

Okresowo w IE skrypty zawarte w requireJS miałyby zdefiniować brak w ich zasięgu, nawet gdy polecenie require pojawiło się po przywróceniu tych zmiennych. Nigdy nie udało nam się ustalić, dlaczego tak się stało, więc porzuciliśmy to hackowe rozwiązanie. – jcbdrn

6

Po uruchomieniu z reactjs wpadłem na ten problem i jako początkujący docs mógł równie dobrze zostać napisany w języku greckim.

Kwestią, na którą natknąłem się, było to, że większość przykładów dla początkujących używa "anonimowych definicji", kiedy powinieneś używać "id łańcucha".

anonimowy definiuje

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


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

określić z string id

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

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

Podczas korzystania określić z string id wtedy uniknąć tego błędu, gdy próbujesz użyć moduły takie jak:

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

(Tylko uwaga dla potomności) Istnieją * pewne wady tego podejścia, opisane [w dokumentacji] (http://requirejs.org/docs/api.html#modulename): "wywołania define(), które zawierają nazwa modułu ... jest zwykle generowana przez narzędzie optymalizacyjne ... samemu zamawiaj moduły ... sprawia, że ​​moduły są mniej przenośne ... Zazwyczaj najlepiej jest unikać kodowania w nazwie modułu i pozwolić, aby narzędzie optymalizacyjne paliło się w nazwach modułów . "... jak również w [tym wątku GitHub] (https://github.com/moment/moment/issues/1095). Wydaje się, że jest to powód, dla którego wpisanie nazwy jest wykluczone w przykładach dla początkujących. –

-1

ten sposób działa na mnie:

Uwzględnij inne javascipts przed tym require.js. bezpieczny sposób, aby to zrobić jest włączenie require.js poza tagu HTML:

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

To nie jest prawidłowy HTML, nie może być poprawnym rozwiązaniem. –

+0

W ten sposób html jest nieprawidłowy, ale ładowanie wymaga.js po reszcie jest właściwie dobrym rozwiązaniem. –