आवश्यकता के तर्क पारित करना (जब लोडिंग मॉड्यूल)


114

आवश्यकता का उपयोग करते हुए मॉड्यूल लोड करते समय क्या तर्क पारित करना संभव है?

मेरे पास मॉड्यूल, login.js है जो लॉगिन कार्यक्षमता प्रदान करता है। इसके लिए एक डेटाबेस कनेक्शन की आवश्यकता होती है, और मैं चाहता हूं कि मेरे सभी मॉड्यूल में एक ही डेटाबेस कनेक्शन का उपयोग किया जाए। अब मैं एक फंक्शन login.setDatabase (...) को निर्यात करता हूं जो मुझे एक डेटाबेस कनेक्शन निर्दिष्ट करने देता है, और यह ठीक काम करता है। लेकिन जब मैं मॉड्यूल को लोड करता हूं, तो मैं डेटाबेस और किसी भी अन्य आवश्यकताओं को पारित कर दूंगा।

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

मैं NodeJS के साथ बहुत नया हूं और आमतौर पर जावा और स्प्रिंग फ्रेमवर्क का उपयोग करके विकसित करता हूं, इसलिए हां ... यह एक निर्माता इंजेक्शन है :) क्या यह संभव है कि मैं ऊपर दिए गए कोड की तरह कुछ करूं?


मैं इस प्रश्न के उत्तर को देखने की भी सिफारिश करूंगा । जैसा कि मेरे जवाब में कहा गया है, एक सामान्य मुहावरा appआवश्यक वस्तु के लिए वस्तु को पास करना है ।
डेविड वेल्डन

यह सब तर्क db के लिए पास करने के बजाय, आप एक सिंगलटन कार्यान्वयन और db.getInstance () का उपयोग कर सकते हैं, जहाँ आवश्यकता हो।
wulfgarpro

जवाबों:


237

इस उत्तर में आपकी टिप्पणियों के आधार पर , मैं वही करता हूं जो आप इस तरह से करने की कोशिश कर रहे हैं:

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

मैं अपने सभी मॉड्यूल को बहुत पसंद करता हूं। मेरे लिए अच्छा काम करने लगता है।


क्या appतर्क आवश्यक है या क्या मैं इसका पालन कर सकता हूं? मेरा मॉड्यूल इस एप्लिकेशन तर्क का स्पष्ट उपयोग नहीं करेगा, लेकिन मुझे नहीं पता कि यह किसी आंतरिक चीज के लिए नोड.जेएस द्वारा आवश्यक है या नहीं। यदि यह ठीक है, तो मेरे मॉड्यूल की घोषणा इस तरह दिखाई देगी:module.exports = function (db) {
यूलिसिस अल्वेस

यह एक एक्सप्रेस ऐप के लिए विशिष्ट था, इसलिए निश्चित रूप से आवश्यक नहीं है।
floatingLomas

@floatingLomas अजगर में क्रमिक तंत्र को अचार कहा जाता है: stackoverflow.com/questions/11218477/…
सैडवेन

1
यदि आप कई बार मॉड्यूल का संदर्भ लेते हैं तो क्या होता है? पहले require(mymodule)(myargs)आपको काम करने के लिए एक मॉड्यूल देगा। हालाँकि यदि आप इसे किसी अन्य मॉड्यूल से कहीं और संदर्भित करते हैं ?? बुनियादी प्रणाली में एक कैश शामिल होना प्रतीत होता है, लेकिन इस प्रणाली में, कैश बाद में कॉल करने पर नंगे जनरेटर विधि को वापस कर देगा require(), और यदि आप पास हुए तो आपके पास require()(someargs)एक अलग मॉड्यूल वापस आ जाएगा ... शायद मैं गायब हूं। कुछ
टॉम एच

2
@TomH उस स्थिति में, आप इसे कैश करना चाहते हैं। ऐसा करने के लिए, आपके पास var module;निर्यात फ़ंक्शन के बाहर होगा, और फिर जैसे ही आप आते हैं आप जांचना चाहते हैं कि moduleक्या पहले से ही परिभाषित है, और यदि ऐसा है, तो बस इसे वापस करें (और यदि नहीं, तो इसे प्रारंभ करें)। क्या इसका कोई मतलब है?
floatingLomas

37

मुझे यकीन नहीं है कि यह अभी भी लोगों के लिए उपयोगी होगा, लेकिन ईएस 6 के साथ मेरे पास ऐसा करने का एक तरीका है जो मुझे साफ और उपयोगी लगता है।

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

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

और तब आपको अपना अपेक्षित व्यवहार मिलता है।

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

32

हाँ। अपने loginमॉड्यूल में, बस एक फ़ंक्शन को निर्यात करें जो dbइसके तर्क के रूप में लेता है। उदाहरण के लिए:

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

1
मैंने यह कोशिश की। Login.js में module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff } यह "अनाम" फ़ंक्शन को कॉल करता है appऔर और dbचर सेट करता है, लेकिन, ऐसा करने पर मेरे एप्लिकेशन को authफ़ंक्शन नहीं मिलेगा । मैं क्या गलत कर रहा हूं? यदि मैं अनाम फ़ंक्शन को हटाता हूं तो authफ़ंक्शन फिर से सुलभ हो जाता है।
एंड्रियास सेलेनवॉल

जावास्क्रिप्ट में सब कुछ की तरह, exportsएक वस्तु है। आप इसे (एकाधिक निर्यात) के लिए गुण प्रदान कर सकते हैं, या आप इसे एक मूल्य पर असाइन कर सकते हैं। ऐसा लगता है कि आपने किसी फ़ंक्शन को निर्यात असाइन किया है, लेकिन फिर आपके द्वारा निर्यात किए गए फ़ंक्शन की संपत्ति के रूप में असाइन किया गया है। इसलिए आपको वह करने की आवश्यकता होगी var auth = require("./login.js").authजो वह नहीं हो सकता है जो आप चाहते थे। यदि आप मूल प्रश्न से पैटर्न का उपयोग करना चाहते हैं, तो संभवत: यह एकल निर्यात मूल्य से चिपकना सबसे अच्छा है। अगर यह अभी भी समझ में नहीं आता है, तो मैं मुझे देखने के लिए एक जिस्ट पोस्ट करने की सलाह दूंगा।
डेविड वेल्डन

1
इसे फिर से पढ़ने के बाद, ऐसा लगता है कि आपने ऑब्जेक्ट authकी एक संपत्ति के रूप में असाइन किया है exports, और फिर बाद में मॉड्यूल में आपको exportsएक फ़ंक्शन सौंपा जा सकता है (इस प्रकार पिछले असाइनमेंट को ओवरराइड करना)। यदि आप असाइनमेंट के क्रम को उलट देते हैं, तो आपको authफ़ंक्शन को एक्सेस करने में सक्षम होना चाहिए जैसा कि आप अपेक्षा करते हैं। फिर से वास्तव में कोड देखे बिना बताना मुश्किल है।
डेविड वेल्डन

1
आपकी सहायता के लिए धन्यवाद। क्या मुझे एहसास नहीं था कि आप क्या आवश्यकता ('लॉगिन') के लिए लक्ष्य कर रहे थे। मैं हालांकि में कोई अंतर नहीं थे var login = require('login')और var login = require('login')(app), लेकिन वहाँ एक बहुत बड़ा अंतर है, वहाँ वापस आ गुमनाम समारोह में कोई जादू नहीं है, यह सिर्फ एक और समारोह / वस्तु है। एक होने के बजाय module.exports.auth, विसंगतिपूर्ण फ़ंक्शन अब ऑर्टिकल फ़ंक्शन (दूसरों के साथ) देता है, अर्थात return { auth: authFunction, login: loginFunction}। तो अब यह काम करता है। धन्यवाद।
एंड्रियास सेलेनवॉल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.