Shim yapılandırmasının neden ve ne zaman kullanılacağını gerektirir


98

Requjs belgesini buradan okudum API

requirejs.config({
    shim: {
        'backbone': {
            //These script dependencies should be loaded before loading
            //backbone.js
            deps: ['underscore', 'jquery'],
            //Once loaded, use the global 'Backbone' as the
            //module value.
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                //Using a function allows you to call noConflict for
                //libraries that support it, and do other cleanup.
                //However, plugins for those libraries may still want
                //a global. "this" for the function will be the global
                //object. The dependencies will be passed in as
                //function arguments. If this function returns a value,
                //then that value is used as the module export value
                //instead of the object found via the 'exports' string.
                return this.Foo.noConflict();
            }
        }
    }
});

ama almıyorum pul onun bir parçası. neden shim kullanmalıyım ve nasıl yapılandırmalıyım, biraz daha açıklama alabilir miyim

lütfen herhangi biri neden ve ne zaman shim kullanmamız gerektiğini örnekle açıklayabilir. Teşekkürler.

Yanıtlar:


110

Shim'in birincil kullanımı, AMD'yi desteklemeyen kitaplıklardır, ancak bağımlılıklarını yönetmeniz gerekir. Örneğin, yukarıdaki Backbone ve Underscore örneğinde: Backbone'un Alt Çizgi gerektirdiğini biliyorsunuz, bu nedenle kodunuzu şu şekilde yazdığınızı varsayalım:

require(['underscore', 'backbone']
, function( Underscore, Backbone ) {

    // do something with Backbone

}

RequireJS hem Alt Çizgi hem de Omurga için eşzamansız istekleri başlatır, ancak hangisinin önce geri geleceğini bilemezsiniz, bu nedenle Backbone yüklenmeden önce Alt Çizgi ile bir şeyler yapmaya çalışabilir.

NOT: Bu alt çizgi / omurga örneği, her iki kitaplık da AMD'yi desteklemeden önce yazılmıştır. Ancak bu ilke, günümüzde AMD'yi desteklemeyen tüm kütüphaneler için geçerlidir.

"İnit" kancası, diğer gelişmiş şeyleri yapmanızı sağlar, örneğin, bir kitaplık normalde iki farklı şeyi genel ad alanına aktarırsa, ancak bunları tek bir ad alanı altında yeniden tanımlamak istiyorsanız. Ya da, belki de yüklediğiniz kitaplıktaki bir yöntemde maymun yamaları yapmak istersiniz.

Daha fazla arka plan:


Örnek kod gibi, Underscoreve Backboneburada normal gibi kullanılır shim, bu durumda ne işe yarar ? Kullanabilir miyim require( function() { _.extend({}); })? Anlıyor _mu?
Stiger

"RequireJS, hem Alt Çizgi hem de Omurga için eşzamansız istekleri başlatacak" -> Kütüphane zaten yüklenmişse, bunu önlemek mümkün müdür?
Codii

1
@Codii doğru, eğer kütüphane zaten yüklüyse, başka bir sunucu isteğini başlatmaz, ancak RequireJS'nin amacı, kodunuzun bunun nasıl / nasıl olacağıyla ilgilenmesine gerek olmamasıdır. Belki de özel kullanım durumunuz için yeni bir soru başlatır mısınız?
48'de açıklayın

63

RequireJS API belgelerine göre, shim size

Bağımlılıkları bildirmek ve bir modül değeri ayarlamak için define () kullanmayan daha eski, geleneksel "tarayıcı globalleri" komut dosyaları için bağımlılıkları, dışa aktarmaları ve özel başlatmayı yapılandırın.

- Bağımlılıkları yapılandırma

Diyelim ki 2 javascript modülünüz var (modülA ve modülB) ve bunlardan biri (modülA) diğerine bağlı (modülB). Bunların her ikisi de kendi modülünüz için gereklidir, böylece bağımlılıkları require () veya define () içinde belirtirsiniz.

require(['moduleA','moduleB'],function(A,B ) {
    ...
}

Ancak AMD'yi takip etmeyi gerektirdiğinden, hangisinin erken getirileceğine dair hiçbir fikriniz yok. Shim'in kurtarmaya geldiği yer burasıdır.

require.config({
    shim:{
       moduleA:{
         deps:['moduleB']
        } 
    }

})

Bu, modül B'nin her zaman A modülü yüklenmeden önce getirilmesini sağlar.

- Dışa aktarımları yapılandırma

Shim export, RequireJS'e global nesnedeki hangi üyenin (tabii ki bir tarayıcıda olduğunuzu varsayarak pencere) gerçek modül değeri olduğunu söyler. Diyelim ki moduleA kendisini window'modA' olarak ekler (tıpkı jQuery ve alt çizginin sırasıyla $ ve _ gibi yaptığı gibi), o zaman dışa aktardığımız değeri 'modA' yaparız.

require.config({
    shim:{
       moduleA:{
         exports:'modA'
        } 
    }

RequireJS'e bu modüle yerel bir referans verecektir. Global modA hala sayfada var olacaktır.

-Daha eski "tarayıcı genel" komut dosyaları için özel başlatma

Bu muhtemelen shim yapılandırmasının en önemli özelliğidir ve bizim modülümüzde bağımlılıklar olarak 'tarayıcı global', 'AMD dışı' komut dosyalarını (modüler modeli takip etmeyen) eklememize izin verir.

Diyelim ki modülB sadece iki funcA () ve funcB () fonksiyonuna sahip eski bir javascript.

function funcA(){
    console.log("this is function A")
}
function funcB(){
    console.log("this is function B")
}

Bu işlevlerin her ikisi de pencere kapsamında mevcut olsa da, RequireJS, kafa karışıklıklarını önlemek için bunları küresel tanımlayıcıları / tanıtıcıları aracılığıyla kullanmamızı önerir. Yani şimi yapılandırmak

shim: {
    moduleB: {
        deps: ["jquery"],
        exports: "funcB",
        init: function () {
            return {
                funcA: funcA,
                funcB: funcB
            };
        }
    }
}

İnit işlevinin dönüş değeri, 'dışa aktarım' dizesi aracılığıyla bulunan nesne yerine modül dışa aktarma değeri olarak kullanılır. Bu, kendi modülümüzde funcB'yi şu şekilde kullanmamıza izin verecektir:

require(["moduleA","moduleB"], function(A, B){
    B.funcB()
})

Umarım bu yardımcı olmuştur.


3
Anlaması kolay! Bir soru: son örnekte, "ihracat" özelliği basitçe yok sayılıyor mu?
Niko Bellic

Hayır, göz ardı edilmiyor. Son örnekte "dışa aktarım" özelliği göz ardı edilmiş olsaydı, parametre olarak ilettiğiniz nesne (bu durumda "B") modül B AMD uyumlu olmadığından tanımsız olurdu ve RequireJS'nin kullanması için bir nesne döndürmezdi ( dolayısıyla 'B.funcB' çalışmayacaktır).
nalinc

Hmm. Gönderme değerinin init işlevinde döndürülen nesne tarafından geçersiz kılınacağını düşündüm. Dolayısıyla B parametresi, yalnızca kendi başına funcB değil, {funcA: funcA, funcB: funcB} nesnesi olacaktır. Bu doğru değil mi
Niko Bellic

4
Niko Bellic haklı, ihracat görmezden geliniyor (bunu biraz önce test ettim). Nesne B, 'init' bölümünde belirtilen işlev tarafından döndürülen nesnedir. 'İnit' bölümünü kaldırırsanız, B nesnesi funcB işlevi olur, bu nedenle B.funcB () yerine B () yaparsınız. Ve tabii ki funcA bu durumda erişilemez hale gelir.
user4205580

-2

Bildirmek için requirejs.config dosyasına yollar eklemelisiniz, örneğin:

requirejs.config({
    paths: {
          'underscore' : '.../example/XX.js' // your JavaScript file
          'jquery' : '.../example/jquery.js' // your JavaScript file
    }
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                return this.Foo.noConflict();
            }
        }
    }
});

1
Bu cevap, "shim config'in neden ve ne zaman kullanılacağını" açıklamak için hiçbir şey yapmayan bir kod dökümüdür. Cevabınızı bir açıklama sağlayacak şekilde düzenlerseniz, daha önceki cevapların kapsamına girmeyen yeni bir şey eklediğinizden emin olun
Louis

olumlu geribildirim olmadan kopyala yapıştır
william.eyidi

şimden önce virgül olmalıdır:
Scott
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.