Eşleşmeyen anonim tanımla () modülü


129

Web uygulamama ilk kez göz attığımda bu hatayı alıyorum (genellikle önbelleği devre dışı bırakılmış bir tarayıcıda).

Hata: Eşleşmeyen anonim define () modülü: işlev (gerekli) {

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
    });
});

Bu hatanın ne anlama geldiğini ve neden olduğunu bilen var mı?

kaynak dosyası , github sorunları sayfasında bunun hakkında kısa bir tartışma

Yanıtlar:


142

AlienWebguy'un dediği gibi, belgelere göre, require.js, eğer

  • Kendi kod etiketinde anonim bir tanımlamanız (" dize kimliği olmadan define () çağıran modüller ") var (aslında küresel kapsamda herhangi bir yeri kastettiklerini varsayıyorum)
  • Çakışan adlara sahip modülleriniz var
  • Yükleyici eklentileri veya anonim modüller kullanıyorsunuz, ancak bunları paketlemek için require.js'nin optimize edicisini kullanmıyorsunuz

Require.js modüllerinin yanı sıra browsererify ile oluşturulmuş paketleri dahil ederken bu sorunu yaşadım. Çözüm şuydu:

A. Require.js yüklenmeden önce , need.js bağımsız paketlerini komut dosyası etiketlerine yükleyin veya

B. Required.js kullanarak bunları yükleyin (bir komut dosyası etiketi yerine)


2
çelişen isimler yaygın bir isim
Julio Marins

1
Diğer bir olası çözüm, anonim modüller ile bazı özel durumlarda, ardışık modülleri veya çalıştırılacak kodu durduran needjs tarafından atılan varsayılan hata istisnasını önlemek için requirejs.onError işlevinin üzerine yazmaktır.
xtrm

1
Tam olarak bu durumu rahatlatmak için bir çekme isteği ( github.com/requirejs/requirejs/pull/1763 ) ekledim . Bence bu günlerde çok yaygın bir sorun.
Bob S

1
Daha önce yüklememi söylediğin için teşekkürler! Bu ipucunun neden requirejs'in kendi belgelerinde olmadığını bilmiyorum ... Yığın işe yaradığı yer
Tobias Feil

14

Bu hatayı aldım çünkü requirejs dosyasını, doğrudan bir komut dosyası etiketine dahil edilen diğer kitaplıklarla birlikte ekledim. Bu kütüphaneler (lodash gibi), gereksinim tanımıyla çelişen bir tanımlama işlevi kullandılar. Requjs dosyası eşzamansız olarak yükleniyordu, bu yüzden gereksinim tanımının diğer kütüphaneler tanımlandıktan sonra tanımlandığından şüpheleniyorum, bu nedenle çakışma.

Hatayı gidermek için, needjs kullanarak diğer tüm js dosyalarınızı ekleyin.


Pek çok kütüphanenin böyle bir şey yaptığı veya en azından böyle bir işlevi kullandığı / dışa aktardığı ortaya çıktı. Herkese tavsiye edeceğim - eğer gerektirirlerse - gereken her şeyi içe aktarın :)
Andrey Popov

12

Reactjs ile başlarken sorunla karşılaştım ve yeni başlayan biri olarak dokümanlar Yunanca da yazılmış olabilir.

Karşılaştığım sorun, yeni başlayan örneklerin çoğunun "dize kimliği" kullanmanız gerektiğinde "anonim tanımlar" kullanmasıydı.

anonim tanımlar

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


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

dize kimliğiyle tanımla

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

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

Bir dizge kimliğiyle tanımla kullandığınızda, modülleri şu şekilde kullanmaya çalıştığınızda bu hatayı önleyeceksiniz:

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

Orada (kuşaklar için sadece not) vardır açıklanan Bu yaklaşıma bazı olumsuzlukları, docs : “define () çağrıları modülü için bir isim dahil ... normalde optimizasyon aracı ... nam tarafından oluşturulan [ing] modülleri kendin ... yapar modüller daha az taşınabilir… Modül için bir adla kodlamadan kaçınmak ve optimizasyon aracının modül adlarını yazmasına izin vermek normalde en iyisidir. " … Ve bu GitHub başlığında olduğu gibi . Bu, yeni başlayan örneklerde adın listelenmesinin hariç tutulmasının nedeni gibi görünüyor.
Mark

10

Başına docs :

Anonim define () çağrısıyla bir komut dosyası yüklemek için HTML'de bir komut dosyası etiketini manuel olarak kodlarsanız, bu hata oluşabilir.

Ayrıca, birkaç adlandırılmış modülü olan bir komut dosyasını yüklemek için HTML'de bir komut dosyası etiketini manuel olarak kodlarsanız, ancak ardından el ile yüklenen komut dosyasındaki adlandırılmış modüllerden biriyle aynı ada sahip olan anonim bir modülü yüklemeyi denerseniz de görülür. kodlanmış komut dosyası etiketi.

Son olarak, yükleyici eklentileri veya anonim modüller (dize kimliği olmadan define () öğesini çağıran modüller) kullanırsanız, ancak dosyaları bir araya getirmek için RequireJS optimize ediciyi kullanmazsanız, bu hata oluşabilir. İyileştirici, anonim modülleri, optimize edilmiş bir dosyadaki diğer modüllerle birleştirilebilmesi için doğru şekilde adlandırmayı bilir.

Hatayı önlemek için:

  • RequireJS API aracılığıyla define () çağıran tüm komut dosyalarını yüklediğinizden emin olun. İçlerinde define () çağrıları bulunan komut dosyalarını yüklemek için HTML'deki komut dosyası etiketlerini manuel olarak kodlamayın.

  • Bir HTML komut dosyası etiketini manuel olarak kodlarsanız, yalnızca adlandırılmış modülleri içerdiğinden ve bu dosyadaki modüllerden biriyle aynı ada sahip anonim bir modülün yüklenmediğinden emin olun.

  • Sorun, yükleyici eklentilerinin veya anonim modüllerin kullanılmasıysa, ancak RequireJS iyileştirici dosya gruplama için kullanılmıyorsa, RequireJS iyileştiricisini kullanın.


3
Bu anonim olarak tanımlanmış bir modül mü? github.com/requirejs/example-multipage/blob/master/www/js/app/…
streetlight

5

Bazı tarayıcı uzantılarının sayfalara kod ekleyebileceğini unutmayın. Benim durumumda, RequireJ'lerimi karıştıran bir "Tüm metin alanlarında Emmet" eklentim vardı. Tarayıcıda inceleyerek belgenize fazladan kod eklenmediğinden emin olun.


5

Mevcut yanıtlar sorunu iyi açıklar, ancak komut dosyası dosyalarınızı gerekli jS kullanarak veya daha önce dahil etmek kolay bir seçenek değilse, biraz karmaşık bir çözüm, komut dosyası etiketinizden önce pencere kapsamındaki gereksinimi kaldırmak ve ardından onu yeniden eski haline getirmektir. Projemizde bu, sunucu tarafındaki bir işlev çağrısının arkasına sarılmıştır, ancak tarayıcı etkili bir şekilde aşağıdakileri görür:

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

En temiz değil ama işe yarıyor gibi görünüyor ve çok fazla refraktörden tasarruf sağladı.


5
Aslında bunu asla yapma. IE'de düzgün çalışmıyor.
jcbdrn

2
Aralıklı olarak IE'de, requireJS'ye dahil edilen komut dosyaları, bu değişkenler geri yüklendikten sonra Require komutu gelse bile pencere kapsamlarında eksikleri tanımlar. Bunun neden olduğunu asla anlayamadık, bu yüzden bu hileli çözümü terk ettik.
jcbdrn

2
@jcbdrn Sadece IE'de değil. Bunun başka bir platformda olduğunu gördüm. Bunun nedeni, HTML spesifikasyonunun senkronize komut dosyalarının çalıştırılma sırasına ilişkin garantiler sunması, ancak yalnızca diğer senkronize komut dosyalarıyla ilişkili olmasıdır . Zaman uyumsuz betiklerin eşzamanlı olana göre (veya tam tersi) çalıştırılmasını garanti etmez . Yani buradaki cevapta gösterilen kodda, herhangi iki scripteleman arasında eşzamansız bir komut dosyasının çalıştırılması mümkündür .
Louis

İçe aktardığınız js paketini düzenleme olanağınız varsa, her şeyi şu şekilde sarmalayabilirsiniz:(function(){ var define = undefined; // the UMD registration code won't find the global 'define' anymore! // generated content goes here })()
Pete Thorne

2

Veya bu yaklaşımı kullanabilirsiniz.

  • Kod tabanınıza require.js ekleyin
  • sonra komut dosyanızı bu kod aracılığıyla yükleyin

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

Yapacağı şey, require.js'yi yükledikten sonra komut dosyanızı yükleyecektir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.