2012-12-14 22 views
19

İnsanların js 'belgesinde ya da birçok öğreticide anlatılandan daha fazla js gerektiren alternatif bir "sözdizimi" tanımladığını gördüm.Neden alternatif gereksinimler kullanın: define (function (required) {...}

zamanki tanımlamak "sözdizimi":

define(['module/first'], function (firstModule) { 
    //Module code with a dependency on module/first goes here. 
}); 

alternatif "sözdizimi" define:

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

dosyası: config.js:

require.config({ 
    paths: { 
     jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

dosyası: app.js: bu alternatif "sözdizimi" kullanmanın avantajları ve dezavantajları nelerdir

define(function(require) { 
    var FirstModule = require('modules/first'); 
    //Module code with a dependency on module/first goes here. 

?

cevap

40

Sanırım açıklamanız biraz yanıltıcıdır: Her iki durumda da, farklı modüller gerektiren işlemi başlatmak için bir dosya belirten data-main özniteliğine sahip bir üst düzey require çağrınız olacaktır.

Yani tipik HTML'nizde bu olacak: Her iki durumda yılında Sonra

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

, yaptığında (HTML doğrudan bu yapabileceği halde) yapılandırmanızı ayarlayan bir dosyayı app/config olurdu ve daha da önemlisi modülleri require çağırır:

require.config({ 
    paths: { 
    jquery:  '../assets/js/libs/jquery' 
    } 
}); 
require(['app']); 

Şimdi, bu stilleri farklı bağımlılıkları olan modüller tanımlayan gidince bu kadar. Eğer bir dizi modül adları (yolları) geçmek AMD stil ve bağımsız değişkenler aynı sayıda alan bir fonksiyon olarak:

basitleştirilmiş CommonJS sözdiziminde

define(['module/first', 'module/second', 'module/third'], function (firstModule, secondModule, thirdModule) { 
    // use firstModule, secondModule, thirdModule here 
}); 

app.js, sadece define içine require geçmesi ve sonra satır içi ne gerekiyorsa modülleri gerektirir:

define(function(require) { 
    var firstModule = require('modules/first'); 
    var secondModule = require('modules/second'); 
    var thirdModule = require('modules/third'); 
    // use firstModule, secondModule, thirdModule here 

} 
app.js

Özgün soruya dönersek, CommonJS stilinin amd stili üzerindeki avantajları açık olmalıdır.

Geleneksel bir sözdizimi ile, bir çok şey gerekiyorsa, yanlış değişken adlarına yanlışlıkla modül atamak çok kolay çok kolaydır. Eğer biz bu listeye yeni bir modül eklediğinizde, biz karşılık gelen yeni fonksiyon argümanı doğru yerde göründüğünü çok dikkatli olmak zorunda olduğunu görüyoruz, ya da başka olabilir, Hemen

define(['jquery', 'underscore', 'backbone', 'modules/first', 'modules/second', 'modules/third', 'i18n', 'someOtherModule'], function ($, _, Backbone, first, second, third, I18n, someOtherModule) { 
    // ... 
}); 

: bu ortak durumu ele alalım jQuery Backbone, vb. atanmış olabilir. Bazı durumlarda bu, izlemesi zor olan çok ince hatalar oluşturabilir.

  1. değişken adına modülün eşleştirme çok açıktır: O

    define(function(require) { 
        var $ = require('jquery'); 
        var _ = require('underscore'); 
        var Backbone = require('backbone'); 
        var firstModule = require('modules/first'); 
        var secondModule = require('modules/second'); 
        var thirdModule = require('modules/third'); 
        var I18n = require('i18n'); 
        var someOtherModule = require('someOtherModule'); 
        // ... 
    } 
    

    Not:

    Şimdi CommonJS sözdizimi düşünün.

  2. Gereksinim ifadelerinin sırası önemli değildir, çünkü değişken adları bir dizi ve işlev arasında bir eşleme olarak değil, ayrı olarak eşleştirilir.
  3. Modüllerin önce atanmasına gerek yoktur. Modül kullanılmadan önce olduğu sürece herhangi bir yere atanabilirler.

Bunlar akla gelen birkaç nedendir, eminim başkaları da var. Temel olarak, bir ya da iki bağımlılığınız varsa, sözdizimi iyi olacaktır. Ancak, karmaşık bir modül bağımlılıkları ağınız varsa, CommonJS sözdizimi muhtemelen tercih edilir. RequireJS dokümanlarında, onlar this small caveat bahsedince

Not:

Tüm tarayıcılar() sonuçları kullanılabilir bir Function.prototype.toString verir. Ekim 2011 itibariyle, PS 3 ve daha eski Opera Mobile tarayıcıları kullanmıyor. Bu tarayıcıların, ağ/aygıt sınırlamaları için optimize edilmiş bir modüle sahip olmaları daha olasıdır, bu yüzden bu dosyaları RequireJS optimizer gibi normalleştirilmiş bağımlılık dizisi biçimine nasıl dönüştüreceğini bilen bir optimizer ile bir derleme yapın.

Ama bu büyük bir sorun değil: Bu toString destekleyemez tarayıcı sayısı yana

() tarama hepsi senin modülleri için bu şekerli formlarının kullanılması güvenlidir, çok küçük, Özellikle bağımlılık isimlerini, modül değerlerini tutacak değişkenlerle hizalamayı seviyorsanız.

+0

Commonjs stili avantajlarına katılıyorum. Amd stilinin öğreticilerde ve requirejs belgelerinde niçin tercih edildiğine dair herhangi bir fikrin veya fikrin var mı? Sonuç aynı ise, neden herkesi commonjs stilini kullanmasını önermiyoruz? "Küçük uyarı" nın tek nedeni mi? – joholo

+1

Gerçekten söyleyemem ama sanırım çoğunlukla tarihsel: amd formatı standart, basitleştirilmiş CommonJS ise bunun üzerinde bir "şeker" tabakası. Eğer RequireJS'yi öğretecekseniz, "şekerli" versiyonu daha basit ve tartışmasız daha iyi olsa bile, daha uzun bir geçmişe ve daha geniş bir evlat edinme biçimine sahip olan format ile gitmek anlamlıdır. Biliyorum, sadece burada sadece hipotez yapıyorum. –

+1

Ayrıca, tüm bağımlılıklarınızı bir modülün tepesinde (başka bir şeyden önce) tanımlamanızı zorlatarak, amd biçiminin bu bağımlılıkları bir bakışta daha kolay kavramasını sağladığını iddia edebilirsiniz. Her ne kadar CommonJS formatını kullanırsanız ve bağımlılıkları modülün en üstüne koyarak yapıştırırsanız, bu gerçekten bir sorun değildir. –