javascript - Väärin kohdattu anonyymi define() -moduuli
Saan tämän virheen, kun selailen web-sovellustani ensimmäistä kertaa (yleensä selaimessa, jossa välimuisti on pois käytöstä).
Virhe: Virheellinen nimettömän define()-moduulin vastaavuus: 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
});
});
Tiedätkö joku tarkalleen, mitä tämä virhe tarkoittaa ja miksi se tapahtuu?
lähdetiedosto, lyhyt keskustelu siitä Githubin issues-sivulla
Vastaus #1
Kuten AlienWebguy sanoi, ohjeiden mukaan, require.js voi räjähtää jos
- Sinulla on anonyymi define ("moduulit, jotka kutsuvat define() ilman merkkijono-ID:tä") omassa script-tägissään (olen olettanut, että he oikeasti tarkoittavat missä tahansa globaalissa skoopissa)
- Sinulla on moduuleja, joilla on ristiriitaiset nimet
- Käytät loader-laajennuksia tai nimettömiä moduuleja, mutta et käytä require.js:n optimointiohjelmaa niiden paketoimiseen
Minulla oli tämä ongelma, kun liitin Browserifyllä rakennettuja paketteja Require.js-moduulien rinnalle. Ratkaisu oli joko:
A. lataa non-require.js erilliset paketit skriptitägeissä ennen kuin require.js ladataan, tai
B. lataa ne käyttämällä require.js:ää (script-tagin sijaan)
Vastaus #2
Aloittaessani require.js:n kanssa kohtasin ongelman, ja aloittelijana dokumentaatiot olisivat yhtä hyvin voineet olla kirjoitettu kreikaksi.
Ongelma, johon törmäsin, oli se, että useimmat aloittelijaesimerkit käyttävät 'anonyymejä määritelmiä', kun sinun pitäisi käyttää 'merkkijonotunnusta'.
anonyymi määrittelee
define(function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define(function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
määritä merkkijonon tunnuksella
define('moduleOne',function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define('moduleTwo', function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
Kun käytät define-merkkijono-ID:n kanssa, vältät tämän virheen, kun yrität käyttää moduuleja seuraavasti:
require([ "moduleOne", "moduleTwo" ], function(moduleOne, moduleTwo) {
moduleOne.helloWorld();
moduleTwo.helloWorld2();
});
Vastaus #3
Minulla oli tämä virhe, koska sisällytin requirejs-tiedoston muiden suoraan script-tagin kautta sisällytettyjen kirjastojen kanssa. Nämä kirjastot (kuten lodash) käyttivät define-funktiota, joka oli ristiriidassa require:n define-funktion kanssa. Requirejs-tiedosto latautui asynkronisesti, joten epäilen, että require:n define määriteltiin muiden kirjastojen define-funktion jälkeen, mistä seurasi ristiriita.
Poistaaksesi virheen, sisällytä kaikki muut js-tiedostosi käyttämällä requirejs:iä.
Vastaus #4
Dokumenttien mukaan:
Jos kirjoitat HTML:ään käsin script-tagin ladataksesi skriptin anonyymilla define()-kutsulla, tämä virhe voi ilmetä.
Nähty myös, jos manuaalisesti kirjoitat HTML:ään script-tagin ladataksesi skriptin, jolla on muutama nimetty moduuli, mutta yrität sitten ladata anonyymin moduulin, joka päätyy saamaan saman nimen kuin yksi manuaalisesti koodatun script-tagin lataaman skriptin nimetystä moduulista.
Lopuksi, jos käytät latauslaajennuksia tai anonyymejä moduuleja (moduuleja, jotka kutsuvat define() ilman merkkijono-ID:tä) mutta et käytä RequireJS-optimointia yhdistääksesi tiedostoja, tämä virhe voi ilmetä. Optimointiohjelma tietää, miten nimetä anonyymit moduulit oikein, jotta ne voidaan yhdistää muiden moduulien kanssa optimoidussa tiedostossa.
Välttääksesi virheen:
Varmista, että lataat kaikki skriptit, jotka kutsuvat define()-funktiota, RequireJS API:n kautta. Älä lisää käsin script-tageja HTML:ään ladataksesi skriptejä, joissa on define()-kutsuja.
Jos koodaat HTML-skriptitunnisteen manuaalisesti, varmista, että se sisältää vain nimettyjä moduuleja, eikä anonyymiä moduulia, jolla olisi sama nimi kuin yhdellä tuon tiedoston moduuleista, ladata.
Jos ongelmana on latausohjelman lisäosien tai anonyymien moduulien käyttö, mutta RequireJS-optimointia ei käytetä tiedostojen yhdistämiseen, käytä RequireJS-optimointia.
Vastaus #5
Nykyiset vastaukset selittävät ongelman hyvin, mutta jos skriptitiedostojasi ei ole helppo sisällyttää käyttäen requireJS:ää tai ennen sitä perintökoodin vuoksi, hieman hämääräinen kiertotapa on poistaa require ikkunan scopeista ennen skriptiä ja palauttaa se sen jälkeen. Projektissamme tämä on kääritty palvelinpuolen funktiokutsun taakse, mutta käytännössä selain näkee seuraavan:
<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>
Ei siistein, mutta vaikuttaa toimivan ja on säästänyt paljon uudelleenkirjoittamista.
