Gereken argümanlar iletiliyor (modül yüklenirken)


114

Require kullanarak bir modül yüklerken argümanlar iletmek mümkün müdür?

Oturum açma işlevselliği sağlayan login.js modülüm var. Bir veritabanı bağlantısı gerektirir ve tüm modüllerimde aynı veritabanı bağlantısının kullanılmasını istiyorum. Şimdi bir veritabanı bağlantısı belirlememe izin veren login.setDatabase (...) işlevini dışa aktarıyorum ve bu gayet iyi çalışıyor. Ancak modülü yüklediğimde veritabanını ve diğer gereksinimleri geçmeyi tercih ederim.

var db = ...
var login = require("./login.js")(db);

NodeJS konusunda oldukça yeniyim ve genellikle Java ve Spring Framework kullanarak geliştiriyorum, yani evet ... bu bir yapıcı enjeksiyonu :) Yukarıda verdiğim kod gibi bir şey yapmak mümkün mü?


Bu sorunun yanıtlarına da bakmanızı tavsiye ederim . Cevabımda belirtildiği gibi, ortak bir deyim, appnesneyi gerekli modüllere geçirmektir .
David Weldon

Tüm bu argümanı db için geçirmek yerine, bir tekil uygulama kullanabilir ve gerektiğinde db.getInstance () 'i çağırabilirsiniz.
wulfgarpro

Yanıtlar:


237

Bu yanıttaki yorumlarınıza dayanarak, yapmaya çalıştığınız şeyi şöyle yapıyorum:

module.exports = function (app, db) {
    var module = {};

    module.auth = function (req, res) {
        // This will be available 'outside'.
        // Authy stuff that can be used outside...
    };

    // Other stuff...
    module.pickle = function(cucumber, herbs, vinegar) {
        // This will be available 'outside'.
        // Pickling stuff...
    };

    function jarThemPickles(pickle, jar) {
        // This will be NOT available 'outside'.
        // Pickling stuff...

        return pickleJar;
    };

    return module;
};

Hemen hemen tüm modüllerimi böyle yapılandırıyorum. Benim için iyi çalışıyor gibi görünüyor.


appargüman gerekli veya bunu ommit edebilir? Modülüm bu uygulama bağımsız değişkenini açıkça kullanmayacak, ancak bazı dahili şeyler için node.js tarafından gerekli olup olmadığını bilmiyorum. Tamamsa, modül bildirimim şöyle görünecektir:module.exports = function (db) {
Ulysses Alves

Bu bir Express uygulamasına özeldi, bu yüzden kesinlikle gerekli değil.
FloatingLomas

@floatingLomas Python'daki serileştirme mekanizmasına turşu adı verilir: stackoverflow.com/questions/11218477/…
SadSeven

1
Peki modüle birkaç kez başvurursanız ne olur? İlki require(mymodule)(myargs)size üzerinde çalışabileceğiniz bir modül verecektir. Ancak, başka bir modülden başka bir yere referans verirseniz ?? temel sistemde ilgili bir önbellek var gibi görünüyor, ancak bu sistemde, önbellek sonraki çağrılarda çıplak jeneratör yöntemini döndürecek require()ve size argümanlar iletirseniz require()(someargs)farklı bir modül geri alacaksınız ... belki de eksik bir şey
Tom H

2
@TomH Bu durumda, önbelleğe almak istersiniz. Bunu yapmak için var module;, dışa aktarım işlevinin dışına çıkmış olursunuz ve sonra gelir gelmez module, önceden tanımlanmış olup olmadığını kontrol etmek istersiniz ve eğer öyleyse, sadece geri verin (ve değilse, başlatın). bu mantıklı mı?
FloatingLomas

37

Bunun insanlar için hala yararlı olup olmayacağından emin değilim, ancak ES6 ile bunu temiz ve yararlı bulduğum bir yolum var.

class MyClass { 
  constructor ( arg1, arg2, arg3 )
  myFunction1 () {...}
  myFunction2 () {...}
  myFunction3 () {...}
}

module.exports = ( arg1, arg2, arg3 ) => { return new MyClass( arg1,arg2,arg3 ) }

Ve sonra beklenen davranışınızı elde edersiniz.

var MyClass = require('/MyClass.js')( arg1, arg2, arg3 )

32

Evet. Senin içinde loginmodül, sadece götüren bir tek işlevi ihraç dbonun argüman olarak. Örneğin:

module.exports = function(db) {
  ...
};

1
Bunu denedim. Login.js'de module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff } "anonim" işlevi çağırır ve appve dbdeğişkenlerini ayarlar , ancak bunu yaparken uygulamam authişlevi bulamaz . Neyi yanlış yapıyorum? Anonim işlevi kaldırırsam, authişleve yeniden erişilebilir hale gelir.
Andreas Selenwall

JavaScript'teki her şey gibi exports, bir nesnedir. Özellik atayabilir (çoklu dışa aktarma) veya bir değere atayabilirsiniz. Görünüşe göre bir işleve dışa aktarımlar atamışsınız, ancak daha sonra dışa aktarmaya atadığınız işlevin bir özelliği olarak yetkiyi atamışsınız. Yani yapmak istediğiniz şey var auth = require("./login.js").autholmayabilir. Orijinal sorudaki kalıbı kullanmak istiyorsanız, muhtemelen tek bir dışa aktarma değerine bağlı kalmak en iyisidir. Bu hala mantıklı gelmiyorsa, bakmam için bir özet göndermenizi tavsiye ederim.
David Weldon

1
Bunu tekrar okuduktan sonra auth, exportsnesnenin bir özelliği olarak atamışsınız ve daha sonra modülde exportsbir işlevi atamışsınız (böylece önceki atamayı geçersiz kılmışsınız) geliyor. Atamanın sırasını tersine çevirirseniz, authişleve beklediğiniz gibi erişebilmeniz gerekir . Yine kodu görmeden söylemek zor.
David Weldon

1
Yardımın için çok teşekkürler. Fark etmediğim şey, tam olarak neyi amaçladığınızdı ('giriş'). Auth. Hiçbir fark yoktu olsa var login = require('login')ve var login = require('login')(app)fakat çok büyük bir fark var, döndü anonim işlevinde sihirli yoktur, sadece başka fonksiyon / nesnedir. module.exports.authA'ya sahip olmak yerine , anomimous işlev artık auth işlevini (diğerleriyle birlikte) döndürür, yani return { auth: authFunction, login: loginFunction}. Şimdi işe yarıyor. Teşekkürler.
Andreas Selenwall
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.