Node.js में मॉड्यूल.exports बनाम निर्यात


725

मैंने Node.js मॉड्यूल में निम्नलिखित अनुबंध पाया है:

module.exports = exports = nano = function database_module(cfg) {...}

मैं क्या के बीच अलग अलग आश्चर्य module.exportsऔर exportsऔर क्यों दोनों यहां किया जाता है।




6
अद्यतित 'के लिए पोस्टरिटी
Zeke

8
यह सभी संदर्भों के बारे में है। मॉड्यूल.एक्सपोर्ट्स की ओर इशारा करते हुए एक स्थानीय चर वस्तु की तरह निर्यात के बारे में सोचें। यदि आप निर्यात के मूल्य को ओवररिट करते हैं, तो आप मॉड्यूल के संदर्भ को खो देते हैं।
गेब्रियल लामास

14
त्वरित सारांश: दोनों exportsऔर module.exportsएक ही वस्तु को इंगित करें, जब तक कि आप एक को फिर से असाइन न करें। और अंत module.exportsमें वापस कर दिया जाता है। इसलिए यदि आपने exportsकिसी फ़ंक्शन को फिर से असाइन किया है, तो किसी फ़ंक्शन की अपेक्षा न करें क्योंकि यह वापस नहीं होने वाला है। हालाँकि अगर आपने फ़ंक्शन को इस तरह से असाइन किया है exports.func = function...तो परिणामी चीज के पास फंक्शन के साथ एक मान के रूप में संपत्ति होगी। क्योंकि आपने उस संपत्ति को उस वस्तु में जोड़ दिया जो exportsइशारा कर रही थी ..
मुहम्मद उमर

जवाबों:


426

सेटिंग module.exportsकरने पर database_moduleफ़ंक्शन को फ़ंक्शन की तरह कहा जा सकता है जब required। बस सेटिंग exportsफ़ंक्शन को निर्यात करने की अनुमति नहीं देगा क्योंकि नोड ऑब्जेक्ट module.exportsसंदर्भों को निर्यात करता है । निम्न कोड उपयोगकर्ता को फ़ंक्शन को कॉल करने की अनुमति नहीं देगा।

module.js

निम्नलिखित काम नहीं करेगा।

exports = nano = function database_module(cfg) {return;}

यदि module.exportsसेट किया गया है तो निम्न कार्य करेगा ।

module.exports = exports = nano = function database_module(cfg) {return;}

कंसोल

var func = require('./module.js');
// the following line will **work** with module.exports
func();

मूल रूप से नोड.जेएस उस वस्तु को निर्यात नहीं करता है जो exportsवर्तमान में संदर्भ देता है, लेकिन exportsमूल रूप से संदर्भ के गुणों का निर्यात करता है । यद्यपि Node.js ऑब्जेक्ट module.exportsसंदर्भों को निर्यात करता है , जिससे आप इसे फ़ंक्शन की तरह कॉल कर सकते हैं।


दूसरा कम से कम महत्वपूर्ण कारण

वे दोनों सेट करते हैं module.exportsऔर exportsयह सुनिश्चित exportsकरते हैं कि पूर्व निर्यात की गई वस्तु को संदर्भित नहीं किया जा रहा है। दोनों का उपयोग करके आप exportsएक आशुलिपि के रूप में उपयोग करते हैं और बाद में सड़क पर संभावित कीड़े से बचते हैं।

पात्रों exports.prop = true को module.exports.prop = trueसहेजने के बजाय उपयोग करना और भ्रम से बचता है।


8
@ajostergaard: यह सिर्फ पुस्तकालय का नाम है जो ओपी के उदाहरण से लिया गया था। मॉड्यूल में, यह लेखक को nano.version = '3.3'इसके बजाय चीजों को लिखने की अनुमति देता है module.exports.version = '3.3', जो थोड़ा अधिक स्पष्ट रूप से पढ़ता है। (ध्यान दें कि nanoएक स्थानीय वैरिएबल है, जिसे मॉड्यूल निर्यात सेट होने से थोड़ा पहले घोषित किया गया है ।)
josh3736

3
@ लाइम - थैंक्स - मुझे खुशी है कि यह काफी हद तक अप्रासंगिक है क्योंकि अगर ऐसा नहीं होता तो इसका मतलब यह होता कि मैं पूरी तरह से सब कुछ गलत समझ लेता। : - | :)
ostergaard

हे लाइम, यह एक बहुत पुराना उत्तर है, लेकिन मुझे आशा है कि आप कुछ स्पष्ट कर सकते हैं। मैं स्थापित करने के लिए थे, तो module.exportsलेकिन नहीं exports , मेरे कोड अभी भी काम करेंगे? किसी भी मदद के लिए धन्यवाद!
असद सईदुद्दीन

1
@Asad हाँ फ़ंक्शन ठीक से निर्यात करेगा बशर्ते आप सेट करेंmodule.exports
चूना

@ लियम बहुमूल्य उत्तर के लिए धन्यवाद। कुछ और प्रश्न - server.js के प्रवेश पर, मॉड्यूल.एक्सपोर्ट और एक्सपोर्ट के मान क्या होने की उम्मीद है? क्या मॉड्यूल.एक्सपोर्ट शून्य होने की उम्मीद है और निर्यात एक खाली वस्तु पर सेट है? क्या यह विरासत या निर्यात और मॉड्यूल के लिए कुछ वैध उपयोग का मामला है।
सुशील

504

हालांकि प्रश्न का उत्तर दिया गया है और बहुत पहले स्वीकार कर लिया गया है, मैं सिर्फ अपने 2 सेंट साझा करना चाहता हूं:

आप सोच सकते हैं कि आपकी फ़ाइल की शुरुआत में कुछ ऐसा है (केवल स्पष्टीकरण के लिए):

var module = new Module(...);
var exports = module.exports;

यहां छवि विवरण दर्ज करें

इसलिए आप जो कुछ भी करते हैं, उसे ध्यान में रखें module.exportsऔर exportsजब आप उस मॉड्यूल को कहीं और से लाना चाहते हैं तो आपके मॉड्यूल से वापस नहीं किया जाएगा।

तो जब आप कुछ ऐसा करते हैं:

exports.a = function() {
    console.log("a");
}
exports.b = function() {
    console.log("b");
}

आप 2 फ़ंक्शन aऔर bऑब्जेक्ट को जोड़ रहे हैं module.exports, जिस पर बिंदु भी हैं, इसलिए typeofरिटर्निंग परिणाम एक होगा object:{ a: [Function], b: [Function] }

बेशक, यह वही परिणाम है जो आपको मिलेगा यदि आप module.exportsइसके बजाय इस उदाहरण में उपयोग कर रहे हैं exports

यह वह मामला है जहां आप चाहते हैं कि आपके module.exportsनिर्यात किए गए मूल्यों के कंटेनर की तरह व्यवहार करें। जबकि, यदि आप केवल एक निर्माता समारोह निर्यात करना चाहते हैं तो आप किसी चीज़ का उपयोग कर के बारे में पता होना चाहिए है module.exportsया exports(फिर से याद रखें कि; module.exportsलौटा दी जाएगी जब आप कुछ की आवश्यकता होती है, नहीं export)।

module.exports = function Something() {
    console.log('bla bla');
}

अब typeofलौटने का परिणाम है 'function'और आपको इसकी आवश्यकता हो सकती है और तुरंत आह्वान
var x = require('./file1.js')();करना चाहिए : क्योंकि आप एक परिणाम होने के लिए रिटर्निंग परिणाम को ओवरराइट करते हैं।

हालाँकि, exportsआप कुछ का उपयोग नहीं कर सकते हैं जैसे:

exports = function Something() {
    console.log('bla bla');
}
var x = require('./file1.js')(); //Error: require is not a function

क्योंकि exports, संदर्भ उस बिंदु की ओर संकेत नहीं करता जहां module.exportsबिंदु है, इसलिए अब exportsऔर बीच का संबंध module.exportsनहीं है। इस मामले में module.exportsअभी भी खाली वस्तु को इंगित करता है {}जिसे वापस कर दिया जाएगा।

दूसरे विषय से स्वीकृत उत्तर में भी मदद करनी चाहिए: क्या जावास्क्रिप्ट संदर्भ से गुजरती है?


2
अच्छी व्याख्या लेकिन मुझे अभी भी समझ में नहीं आया है कि आप module.exportsएक मॉड्यूल से पूरी तरह से कैसे npm
हट

4
@ इमरजेंसी यहाँ है: क्या जावास्क्रिप्ट संदर्भ से गुजरता है? exports.a = function(){}; works, exports = function(){} doesn't work
19

29
oooo आखिरकार इस जवाब को समझाता है। मूल रूप से निर्यात एक ऐसी वस्तु को संदर्भित करता है, जिसमें आप गुण जोड़ सकते हैं, लेकिन यदि आप इसे कार्य करने के लिए फिर से असाइन करते हैं, तो आप उस मूल वस्तु के लिए कोई संपत्ति संलग्न नहीं करते हैं। अब निर्यात का संदर्भ लें जबकि मॉड्यूल .exports अभी भी उस ऑब्जेक्ट की ओर इशारा कर रहा है और चूंकि यह वापस आ गया है। आप कह सकते हैं कि निर्यात मूल रूप से कचरा एकत्र किया गया है।
मुहम्मद उमर

5
तो फिर, क्या उपयोग करने की बात है exports? module.exportsयदि यह केवल एक चर पुनर्मूल्यांकन है तो हमेशा इसका उपयोग क्यों न करें ? मुझे भ्रमित करने लगता है।
jedd.ahyoung 16

1
@ jedd.ahyoung यह लिखने के exports.somethingबजाय कम बोझिल हैmodule.exports.something
Srle

209

मूल रूप से उत्तर में निहित है कि वास्तव में क्या होता है जब requireबयान के माध्यम से एक मॉड्यूल की आवश्यकता होती है । यह मानते हुए कि पहली बार मॉड्यूल की आवश्यकता है।

उदाहरण के लिए:

var x = require('file1.js');

file1.js की सामग्री:

module.exports = '123';

जब उपरोक्त कथन निष्पादित किया जाता है, तो एक Moduleऑब्जेक्ट बनाया जाता है। इसका निर्माण कार्य है:

function Module(id, parent) {
    this.id = id;
    this.exports = {};
    this.parent = parent;
    if (parent && parent.children) {
        parent.children.push(this);
    }

    this.filename = null;
    this.loaded = false;
    this.children = [];
}

जैसा कि आप देखते हैं प्रत्येक मॉड्यूल वस्तु में नाम के साथ एक संपत्ति होती है exports। यह वही है जो अंततः के हिस्से के रूप में वापस आ गया है require

आवश्यकता का अगला चरण नीचे की तरह एक अनाम फ़ंक्शन में file1.js की सामग्री को लपेटना है:

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
});

और यह अनाम फ़ंक्शन निम्न तरीके से लागू किया गया है, moduleयहां Moduleपहले बनाई गई ऑब्जेक्ट को संदर्भित करता है ।

(function (exports, require, module, __filename, __dirname) { 
    //contents from file1.js
    module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");

जैसा कि हम फ़ंक्शन के अंदर देख सकते हैं, exportsऔपचारिक तर्क को संदर्भित करता है module.exports। संक्षेप में यह मॉड्यूल प्रोग्रामर को प्रदान की जाने वाली सुविधा है।

हालांकि इस सुविधा का ध्यान रखने की जरूरत है। किसी भी मामले में अगर निर्यात के लिए एक नई वस्तु निर्दिष्ट करने की कोशिश कर रहा है तो हम इसे इस तरह से सुनिश्चित करते हैं।

exports = module.exports = {};

यदि हम इसे गलत तरीके से करते हैं , तब module.exportsभी मॉड्यूल उदाहरण के हिस्से के रूप में बनाई गई वस्तु की ओर इशारा करेगा।

exports = {};

परिणामस्वरूप उपरोक्त निर्यात वस्तु में कुछ भी जोड़ने से मॉड्यूल.एक्सपोर्ट ऑब्जेक्ट पर कोई प्रभाव नहीं पड़ेगा और आवश्यकता के भाग के रूप में कुछ भी निर्यात या वापस नहीं किया जाएगा।


8
मुझे यहाँ खो दियाexports = module.exports = {};
विशाल एलक

2
मुझे लगता है कि यह सबसे अच्छा उत्तर होना चाहिए, यह बताता है कि क्यों func()@ विलियम के उत्तर में विफल रहता है!
कछुआ

2
मुझे exports = module.exports = app;कोड की अंतिम पंक्ति में जोड़ने के लिए कोई लाभ नहीं दिख रहा है । ऐसा लगता है कि module.exportsनिर्यात हो जाएगा और हम कभी उपयोग नहीं करेंगे exports, क्योंकि फिर से यह कोड की अंतिम पंक्ति में है। तो, हम सिर्फ इसलिए नहीं जोड़ते हैंmodule.exports = app;
lvarayut

79

प्रारंभ में module.exports=exports, और requireफ़ंक्शन रिटर्न ऑब्जेक्ट को module.exportsसंदर्भित करता है।

यदि हम ऑब्जेक्ट में संपत्ति जोड़ते हैंexports.a=1 , तो कहते हैं , तो मॉड्यूल। निर्यात और निर्यात अभी भी उसी ऑब्जेक्ट को संदर्भित करते हैं। इसलिए यदि हम एक चर को मॉड्यूल की आवश्यकता और असाइन करते हैं, तो चर में एक संपत्ति होती है और इसका मूल्य 1 होता है;

लेकिन अगर हम उनमें से एक को ओवरराइड करते हैं, उदाहरण के लिए, exports=function(){}तो वे अब अलग हैं: निर्यात एक नई वस्तु को संदर्भित करता है और मॉड्यूल.एक्सपोर्ट मूल वस्तु को संदर्भित करता है। और अगर हमें फ़ाइल की आवश्यकता होती है, तो यह नई वस्तु को वापस नहीं करेगा, क्योंकि मॉड्यूल.एक्सपोर्ट नई वस्तु का संदर्भ नहीं है।

मेरे लिए, मैं नई संपत्ति जोड़ता रहूंगा, या उन दोनों को एक नई वस्तु पर ओवरराइड करूंगा। बस एक ओवरराइड सही नहीं है। और ध्यान रखें कि module.exportsअसली बॉस है।


1
हाँ, यह वास्तव में असली जवाब है। यह संक्षिप्त और स्पष्ट है। अन्य लोग सही हो सकते हैं लेकिन फैंसी शब्दों से भरे हुए हैं और इस प्रश्न के उत्तर पर बिल्कुल ध्यान केंद्रित नहीं करते हैं।
खोआ

यह अब तक का सबसे स्पष्ट उत्तर है! यदि आप इसे बुकमार्क करना चाहते हैं, तो यह सटीक लिंक है: stackoverflow.com/questions/7137397/…
lambdarookie

56

exportsऔर module.exportsजब तक आप exportsअपने मॉड्यूल के भीतर पुन: असाइन नहीं करते, तब तक वही हैं ।

इसके बारे में सोचने का सबसे आसान तरीका, यह सोचना है कि यह रेखा प्रत्येक मॉड्यूल के शीर्ष पर निहित है।

var exports = module.exports = {};

यदि, आपके मॉड्यूल के भीतर, आप पुन: असाइन करते हैं exports, तो आप इसे अपने मॉड्यूल के भीतर पुन: असाइन करते हैं और यह अब बराबर नहीं होता है module.exports। यही कारण है कि, यदि आप एक फ़ंक्शन निर्यात करना चाहते हैं, तो आपको करना चाहिए:

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

यदि आप आसानी से अपना काम सौंप function() { ... }देते हैं exports, तो आप फिर exportsसे संकेत नहीं करेंगे module.exports

यदि आप module.exportsहर बार अपने कार्य को संदर्भित नहीं करना चाहते हैं , तो आप कर सकते हैं:

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

ध्यान दें कि module.exportsसबसे बाईं ओर तर्क है।

गुणों को संलग्न exportsकरना समान नहीं है क्योंकि आप इसे पुन: असाइन नहीं कर रहे हैं। इसलिए यह काम करता है

exports.foo = function() { ... }

9
सभी उत्तरों में से यह समझना सबसे आसान था!
आदर्श कोंचडी

2
अच्छा और सीधा
फायबोनो

1
इस सुविधा को समझने का सरल और आसान तरीका।
फिलीपानाट्टो

27

जावास्क्रिप्ट एक संदर्भ की प्रतिलिपि द्वारा वस्तुओं को पारित करता है

जावास्क्रिप्ट में संदर्भ द्वारा वस्तुओं को जिस तरह से पारित किया जाता है, उसके साथ करना एक सूक्ष्म अंतर है।

exportsऔर module.exportsदोनों एक ही वस्तु की ओर इशारा करते हैं। exportsएक चर है और module.exportsमॉड्यूल ऑब्जेक्ट की एक विशेषता है।

कहो मैं कुछ इस तरह लिखता हूं:

exports = {a:1};
module.exports = {b:12};

exportsऔर module.exportsअब विभिन्न वस्तुओं की ओर इशारा करते हैं। निर्यात को संशोधित करना अब मॉड्यूल.एक्सपोर्ट को संशोधित नहीं करता है।

जब आयात फ़ंक्शन निरीक्षण करता है तो module.exportsयह हो जाता है{b:12}


6
सबसे अच्छा जवाब imho!
श्री एजे

1
"जावास्क्रिप्ट संदर्भ से गुजरता है" - नहीं
xehpuk

13

मैं बस कुछ परीक्षण करता हूं, यह पता चला है कि, नोडज के मॉड्यूल कोड के अंदर, इसे कुछ इस तरह होना चाहिए:

var module.exports = {};
var exports = module.exports;

इसलिए:

1:

exports = function(){}; // this will not work! as it make the exports to some other pointer
module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.

2:

exports.abc = function(){}; // works!
exports.efg = function(){}; // works!

3: लेकिन, इस मामले में

module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports.
module.exports.a = 'value a'; // works
exports.b = 'value b'; // the b will nerver be seen cause of the first line of code we have do it before (or later)

लीमन, इसलिए module.exports'वास्तविक सौदा' की तरह है कि नोड के बंद हो जाता है लेकिन कुछ बिंदु पर आप सभी जोड़ने की आवश्यकता होगी आपके exportsलिए module.exportsजब तक आप एक प्रयोग कर रहे हैं exports.namespace(उपरोक्त मामले 2), उस मामले में की तरह प्रतीत हो रहा है जो नोड ने ऑब्जेक्ट के extends(module.exports, exports);सभी 'नामस्थान' को जोड़ exportsदिया module.exports? दूसरे शब्दों में, यदि आप उपयोग कर रहे हैं exportsतो आप शायद इस पर गुण स्थापित करना चाहते हैं?
कोड़ी

11

यहाँ मैनिंग प्रकाशन से एक्शन बुक में नोड नोड्स के बारे में एक अच्छा विवरण लिखा गया है। अंततः आपके एप्लिकेशन में जो निर्यात किया जाता है वह मॉड्यूल है। निर्यात निर्यात केवल मॉड्यूल.एक्सपोर्ट के वैश्विक संदर्भ के रूप में स्थापित किया गया है , जिसे शुरू में एक खाली वस्तु के रूप में परिभाषित किया गया है जिसे आप गुणों को जोड़ सकते हैं। इसलिए export.myFunc मॉड्यूल . exports.myFunc के लिए शॉर्टहैंड है । नतीजतन, यदि निर्यात किसी और चीज के लिए सेट है , तो यह मॉड्यूल.एक्सपोर्ट और निर्यात के बीच के संदर्भ को तोड़ता है । क्योंकि मॉड्यूल



क्या वास्तव में निर्यात किया जाता है, निर्यात अब अपेक्षा के अनुरूप काम नहीं करेगा - यह संदर्भ मॉड्यूल का निर्यात नहीं करता है। यदि आप उस लिंक को बनाए रखना चाहते हैं, तो आप निम्न प्रकार से फिर से मॉड्यूल.exports संदर्भ निर्यात कर सकते हैं :

module.exports = exports = db;

8

मैं कुछ परीक्षणों से गुज़रा और मुझे लगता है कि इस विषय पर कुछ प्रकाश डाला जा सकता है ...

app.js:

var ...
  , routes = require('./routes')
  ...;
...
console.log('@routes', routes);
...

के संस्करण /routes/index.js:

exports = function fn(){}; // outputs "@routes {}"

exports.fn = function fn(){};  // outputs "@routes { fn: [Function: fn] }"

module.exports = function fn(){};  // outputs "@routes function fn(){}"

module.exports.fn = function fn(){};  // outputs "@routes { fn: [Function: fn] }"

मैंने नई फाइलें भी जोड़ीं:

./routes/index.js:

module.exports = require('./not-index.js');
module.exports = require('./user.js');

./routes/not-index.js:

exports = function fn(){};

./routes/user.js:

exports = function user(){};

हमें आउटपुट "@routes {}" मिलता है


./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');

./routes/not-index.js:

exports = function fn(){};

./routes/user.js:

exports = function user(){};

हमें आउटपुट "@routes {fn: {}, उपयोगकर्ता: {}}" मिलता है


./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');

./routes/not-index.js:

exports.fn = function fn(){};

./routes/user.js:

exports.user = function user(){};

हमें आउटपुट "@routes {उपयोगकर्ता: [समारोह: उपयोगकर्ता]}" मिलता है, यदि हम बदलते user.jsहैं { ThisLoadedLast: [Function: ThisLoadedLast] }, तो हम आउटपुट प्राप्त करते हैं "@routes {ThisLoadedLast: [समारोह: ThisLoadedLast]}"।


लेकिन अगर हम संशोधित ./routes/index.js...

./routes/index.js:

module.exports.fn = require('./not-index.js');
module.exports.ThisLoadedLast = require('./user.js');

./routes/not-index.js:

exports.fn = function fn(){};

./routes/user.js:

exports.ThisLoadedLast = function ThisLoadedLast(){};

... हमें "@routes {fn: {fn: [फंक्शन: fn]}}, थेलोडेडस्टैस्ट: {ThisLoadedLast: [फंक्शन: ThisLoadedLast]}}"

इसलिए मेरा सुझाव है कि हमेशा module.exportsअपने मॉड्यूल परिभाषाओं में उपयोग करें।

मुझे पूरी तरह से समझ नहीं आ रहा है कि नोड के साथ आंतरिक रूप से क्या हो रहा है, लेकिन कृपया टिप्पणी करें कि क्या आप इस बारे में अधिक समझ बना सकते हैं क्योंकि मुझे यकीन है कि यह मदद करता है।

- हैप्पी कोडिंग


मुझे लगता है कि वे अनावश्यक रूप से जटिल और भ्रमित हैं। यह पारदर्शी और सहज होना चाहिए।
ngungo

मैं सहमत हूँ। यह नाम रखने के लिए उपयोगी हो सकता है कुछ परिस्थितियां हैं, लेकिन आम तौर पर कुछ भी बनाने या तोड़ने के लिए नहीं जा रहा है।
कोड़ी

4

यह दिखाता है कि कैसे require()अपने सरलतम रूप में काम करता है, एलोकेंट जावास्क्रिप्ट के अंश

समस्या यह एक मॉड्यूल के लिए सीधे निर्यात वस्तु के अलावा एक मूल्य निर्यात करने के लिए संभव नहीं है, जैसे कि एक फ़ंक्शन। उदाहरण के लिए, एक मॉड्यूल केवल उसी प्रकार के निर्माता को निर्यात करना चाहता है जो इसे परिभाषित करता है। अभी, यह ऐसा नहीं कर सकता क्योंकि आवश्यकता हमेशा उस exportsवस्तु का उपयोग करता है जो निर्यातित मूल्य के रूप में बनाता है।

समाधान एक अन्य चर के साथ मॉड्यूल प्रदान करें module, जो कि एक संपत्ति है exports। यह संपत्ति शुरू में आवश्यकता द्वारा बनाई गई खाली वस्तु पर इंगित करती है लेकिन कुछ और निर्यात करने के लिए एक और मूल्य के साथ ओवरराइट किया जा सकता है।

function require(name) {
  if (name in require.cache)
    return require.cache[name];
  var code = new Function("exports, module", readFile(name));
  var exports = {}, module = {exports: exports};
  code(exports, module);
  require.cache[name] = module.exports;
  return module.exports;
}
require.cache = Object.create(null);

मुझे इसे नोड में फिर से बनाना था और कुछ चीजों का परीक्षण करना था जब तक कि मुझे नहीं मिला, मैं चूसता हूं। मूल रूप से, मॉड्यूल के लिए बनाया गया आंतरिक फ़ंक्शन कभी भी निर्यात वस्तु को वापस नहीं करता है। तो "निर्यात" ऑब्जेक्ट वास्तव में मॉड्यूल में पुन: असाइन नहीं किया जाता है, उदाहरण के लिए यदि आप निर्यात लिखने की कोशिश करते हैं = "यह अब सीधे एक स्ट्रिंग है"। ऑब्जेक्ट केवल एक संदर्भ के रूप में मौजूद है। यह वह व्यवहार है जो मुझे नहीं लगता कि मैं वास्तव में अब तक ठीक से उठा पाया हूं।
danielgormly

4

यहाँ का परिणाम है

console.log("module:");
console.log(module);

console.log("exports:");
console.log(exports);

console.log("module.exports:");
console.log(module.exports);

यहां छवि विवरण दर्ज करें

इसके अलावा:

if(module.exports === exports){
    console.log("YES");
}else{
    console.log("NO");
}

//YES

नोट: कॉमनजेएस विनिर्देश केवल निर्यात चर का उपयोग सार्वजनिक सदस्यों को उजागर करने की अनुमति देता है। इसलिए, नामित निर्यात पैटर्न एकमात्र ऐसा है जो कॉमनजेस विनिर्देश के साथ वास्तव में संगत है। मॉड्यूल.एक्सपोर्ट का उपयोग मॉड्यूल परिभाषा परिभाषा पैटर्न की एक विस्तृत श्रृंखला का समर्थन करने के लिए Node.js द्वारा प्रदान किया गया एक एक्सटेंशन है।


4
var a = {},md={};

// सबसे पहले, निर्यात और मॉड्यूल.एक्सपोर्ट उसी खाली ऑब्जेक्ट को इंगित करते हैं

exp = a;//exports =a;
md.exp = a;//module.exports = a;

exp.attr = "change";

console.log(md.exp);//{attr:"change"}

// यदि आप बिंदु के बजाय अन्य वस्तु की ओर इशारा करते हैं, तो यह अन्य वस्तु के लिए संपत्ति है। Md.exp खाली वस्तु होगी {}

var a ={},md={};
exp =a;
md.exp =a;

exp = function(){ console.log('Do nothing...'); };

console.log(md.exp); //{}

4

से डॉक्स

निर्यात चर एक मॉड्यूल की फ़ाइल-स्तरीय गुंजाइश के भीतर उपलब्ध है, और मॉड्यूल का मूल्यांकन करने से पहले मॉड्यूल का मूल्य असाइन किया गया है।

यह एक ऐसा शॉर्टकट की अनुमति देता है, ताकि module.exports.f = ... लिखा जा सकता है और अधिक संक्षेप exports.f के रूप में = .... हालांकि, ध्यान रखें किसी भी चर की तरह, अगर एक नया मान निर्यात करने के लिए सौंपा गया है, यह है कि हो सकता है अब mod.exports के लिए बाध्य नहीं है:

यह मॉड्यूल.एक्सपोर्ट्स की ओर इशारा करते हुए एक चर है।


4

उपरोक्त प्रश्न का उत्तर देने के लिए मुझे यह लिंक उपयोगी लगी।

http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/

अन्य पदों में जोड़ने के लिए नोड में मॉड्यूल सिस्टम करता है

var exports = module.exports 

अपना कोड निष्पादित करने से पहले। इसलिए जब आप निर्यात करना चाहते हैं = फू, तो आप शायद मॉड्यूल करना चाहते हैं। निर्यात = निर्यात = फू लेकिन निर्यात का उपयोग करते हुए। फू = फू ठीक होना चाहिए


गिट लिंक टूट गया है
जेसी हट्टाबो

लिंक अब तय हो गया है।
पावेल गोइस्की

3

"यदि आप चाहते हैं कि आपके मॉड्यूल के निर्यात की जड़ें एक फ़ंक्शन (जैसे कि एक निर्माता) हों या यदि आप एक समय में एक संपत्ति बनाने के बजाय एक असाइनमेंट में एक पूरी वस्तु निर्यात करना चाहते हैं, तो इसके बजाय मॉड्यूल के लिए असाइन करें। निर्यात। " - http://nodejs.org/api/modules.html


3

module.exports तथा exports मॉड्यूल का मूल्यांकन करने से पहले दोनों एक ही वस्तु को इंगित करते हैं।

module.exports जब आप अपने मॉड्यूल को requireस्टेटमेंट का उपयोग करके किसी अन्य मॉड्यूल में उपयोग करते हैं, तो आप जो भी वस्तु जोड़ेंगे, वह उपलब्ध होगी । exportsउसी चीज़ के लिए उपलब्ध कराया गया एक शॉर्टकट है। उदाहरण के लिए:

module.exports.add = (a, b) => a+b

लिखने के बराबर है:

exports.add = (a, b) => a+b

तो यह तब तक ठीक है जब तक आप exportsवैरिएबल को नया मान नहीं देते । जब आप ऐसा कुछ करते हैं:

exports = (a, b) => a+b 

जैसा कि आप exportsइसे एक नया मान दे रहे हैं, अब निर्यात की गई वस्तु का संदर्भ नहीं है और इस प्रकार आपके मॉड्यूल के लिए स्थानीय रहेगा।

यदि आप module.exportsउपलब्ध कराए गए प्रारंभिक ऑब्जेक्ट में नए गुणों को जोड़ने के बजाय एक नया मान असाइन करने की योजना बना रहे हैं , तो आपको संभवतः नीचे दिए गए अनुसार करने पर विचार करना चाहिए:

module.exports = exports = (a, b) => a+b

Node.js वेबसाइट में इसकी बहुत अच्छी व्याख्या है।


2

1.
निर्यात -> सिंगलटन उपयोगिता के रूप में उपयोग करें । मॉड्यूल-निर्यात -> तार्किक वस्तुओं जैसे सेवा, मॉडल आदि के रूप में उपयोग करें


2

चलो 2 तरीकों से एक मॉड्यूल बनाते हैं:

एक रास्ता

var aa = {
    a: () => {return 'a'},
    b: () => {return 'b'}
}

module.exports = aa;

दूसरा तरीका

exports.a = () => {return 'a';}
exports.b = () => {return 'b';}

और इस तरह मॉड्यूल की आवश्यकता होगी।

पहला तरीका:

function require(){
    module.exports = {};
    var exports = module.exports;

    var aa = {
        a: () => {return 'a'},
        b: () => {return 'b'}
    }
    module.exports = aa;

    return module.exports;
}

दूसरा तरीका

function require(){
    module.exports = {};
    var exports = module.exports;

    exports.a = () => {return 'a';}
    exports.b = () => {return 'b';}

    return module.exports;
}

2

यहाँ दोनों का उपयोग क्यों किया जाता है

मेरा मानना है कि वे सिर्फ स्पष्ट होना चाहता हूँ कि module.exports, exportsहै, और nanoएक ही कार्य करने के लिए बिंदु - आप फ़ाइल के भीतर समारोह कॉल करने के लिए या तो चर का उपयोग करने की इजाजत दी। nanoफ़ंक्शन क्या करता है कुछ संदर्भ प्रदान करता है।

exports निर्यात नहीं किया जाएगा (केवल module.exports ), तो क्यों कि साथ ही ओवरराइटिंग को परेशान करें?

वर्बोसिटी व्यापार-बंद भविष्य के बग के जोखिम को सीमित करता है, जैसे कि फ़ाइल exportsके module.exportsभीतर का उपयोग करना। इसमें यह भी प्रावधान स्पष्टीकरण कि module.exportsऔर exportsतथ्य यह है एक ही मूल्य की ओर इशारा करते रहे हैं।


module.exports बनाम exports

जब तक आप पुन: असाइन नहीं करते हैं ( module.exportsया exportsइसके बजाय वे दोनों को संदर्भित ऑब्जेक्ट में मान जोड़ते हैं), आपके पास कोई समस्या नहीं है।exports से अधिक संक्षिप्त होने के लिए ।

जब आप किसी गैर-ऑब्जेक्ट को असाइन करते हैं, तो वे अब अलग-अलग स्थानों की ओर इशारा कर रहे हैं, जो तब तक भ्रमित हो सकते हैं जब तक आप जानबूझकर नहीं चाहते module.exports कुछ विशिष्ट नहीं होना (जैसे कि फ़ंक्शन)।

exportsएक गैर-ऑब्जेक्ट पर सेट करने का कोई मतलब नहीं है क्योंकि आपको module.exports = exportsइसे अन्य फ़ाइलों में उपयोग करने में सक्षम होने के लिए अंत में सेट करना होगा।

let module = { exports: {} };
let exports = module.exports;

exports.msg = 'hi';
console.log(module.exports === exports); // true

exports = 'yo';
console.log(module.exports === exports); // false

exports = module.exports;
console.log(module.exports === exports); // true

module.exports = 'hello';
console.log(module.exports === exports); // false

module.exports = exports;
console.log(module.exports === exports); // true

क्यों module.exportsएक समारोह के लिए असाइन करें?

अधिक संक्षिप्त! तुलना करें कि दूसरा उदाहरण कितना छोटा है:

helloWorld1.js: module.exports.hello = () => console.log('hello world');

app1.js: let sayHello = require('./helloWorld1'); sayHello.hello; // hello world

helloWorld2.js: module.exports = () => console.log('hello world');

app2.js: let sayHello = require('./helloWorld2'); sayHello; // hello world


2

यहां छवि विवरण दर्ज करें

आपके द्वारा बनाई गई प्रत्येक फ़ाइल एक मॉड्यूल है। मॉड्यूल एक वस्तु है। इसमें ऐसी संपत्ति होती है जिसे exports : {}डिफ़ॉल्ट रूप से खाली वस्तु कहा जाता है।

आप फ़ंक्शंस / बिचौलिये बना सकते हैं और इस खाली निर्यात ऑब्जेक्ट में जोड़ सकते हैं जैसे कि exports.findById() => { ... } तब requireआपके ऐप और उपयोग में कहीं भी ...

नियंत्रक / user.js

exports.findById = () => {
    //  do something
}

मार्गों का उपयोग करने की आवश्यकता है।

const {findyId} = './controllers/user'

2

मतभेदों को समझने के लिए, आपको सबसे पहले यह समझना होगा कि Node.js रनटाइम के दौरान हर मॉड्यूल को क्या करता है। Node.js प्रत्येक मॉड्यूल के लिए एक आवरण फ़ंक्शन बनाता है:

 (function(exports, require, module, __filename, __dirname) {

 })()

ध्यान दें पहला परम exportsएक खाली वस्तु है, और तीसरा परम moduleकई गुणों वाली एक वस्तु है, और गुणों में से एक का नाम है exports। यह क्या exportsहै और क्या से module.exportsआता है। पहले वाला एक परिवर्तनशील वस्तु है, और बाद वाला एक संपत्ति हैmodule वस्तु का ।

मॉड्यूल के भीतर, Node.js स्वचालित रूप से शुरुआत में इस बात को करता है: module.exports = exportsऔर अंततः लौटता है module.exports

तो आप देख सकते हैं कि यदि आप कुछ मान को फिर से असाइन करते हैं exports, तो इसका कोई प्रभाव नहीं पड़ेगा module.exports। (केवल इसलिए exportsकि एक और नई वस्तु की ओर इशारा करता है, लेकिन module.exportsअभी भी पुराना है exports)

let exports = {};
const module = {};
module.exports = exports;

exports = { a: 1 }
console.log(module.exports) // {}

लेकिन अगर आप के गुणों को अपडेट करते हैं exports, तो निश्चित रूप से इसका प्रभाव पड़ेगा module.exports। क्योंकि वे दोनों एक ही वस्तु की ओर इशारा करते हैं।

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports.b = 2;
console.log(module.exports) // { a: 1, b: 2 }

यह भी ध्यान दें कि यदि आप किसी अन्य मान को module.exportsफिर से असाइन करते हैं , तो यह exportsअपडेट के लिए अर्थहीन लगता है । हर अपडेट exportsको अनदेखा कर दिया जाता है क्योंकि module.exportsकिसी अन्य ऑब्जेक्ट की ओर इशारा करता है।

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports = {
  hello: () => console.log('hello')
}
console.log(module.exports) // { hello: () => console.log('hello')}

0

नोड js मॉड्यूल में .js फ़ाइल का उपयोग करने के लिए उपयोग किया जाता है मॉड्यूल। लोड प्रणाली। हर समय जब नोड एक फ़ाइल को निष्पादित करता है तो यह आपके जेएस फ़ाइल सामग्री को निम्नानुसार लपेटता है

'(function (exports, require, module, __filename, __dirname) {',+
     //your js file content
 '\n});'

इस वजह से उर जेएस स्रोत कोड के अंदर लपेटने से आप निर्यात, आवश्यकता, मॉड्यूल आदि का उपयोग कर सकते हैं। इस दृष्टिकोण का उपयोग किया जाता है क्योंकि जेएस फाइल पर दूसरे में लिखी गई कार्यक्षमता को प्राप्त करने का कोई अन्य तरीका नहीं है।

तब नोड इस लिपटे फ़ंक्शन को c ++ का उपयोग करके निष्पादित करता है। उस क्षण निर्यात वस्तु जो इस फ़ंक्शन में पारित हुई है, भर जाएगी।

आप इस फ़ंक्शन पैरामीटर निर्यात और मॉड्यूल के अंदर देख सकते हैं। वास्तव में निर्यात मॉड्यूल कंस्ट्रक्टर फ़ंक्शन का एक सार्वजनिक सदस्य है।

निम्नलिखित कोड को देखो

इस कोड को b.js में कॉपी करें

console.log("module is "+Object.prototype.toString.call(module));
console.log("object.keys "+Object.keys(module));
console.log(module.exports);
console.log(exports === module.exports);
console.log("exports is "+Object.prototype.toString.call(exports));
console.log('----------------------------------------------');
var foo = require('a.js');
console.log("object.keys of foo: "+Object.keys(foo));
console.log('name is '+ foo);
foo();

इस कोड को a.js पर कॉपी करें

exports.name = 'hello';
module.exports.name = 'hi';
module.exports.age = 23;
module.exports = function(){console.log('function to module exports')};
//exports = function(){console.log('function to export');}

अब नोड का उपयोग करके चलाएं

यह आउटपुट है

module is [object Object]
object.keys id,exports,parent,filename,loaded,children,paths
{}
true

निर्यात [वस्तु वस्तु] है

वस्तु। foo का नाम: नाम फलन है () {कंसोल.लॉग ('फंक्शन टू मॉड्यूल एक्सपोर्ट')} फंक्शन टू मॉड्यूल एक्सपोर्ट्स

अब a.js में टिप्पणी लाइन को हटा दें और उस लाइन के ऊपर की लाइन पर टिप्पणी करें और b.js की अंतिम लाइन को हटा दें और चलाएं।

जावास्क्रिप्ट दुनिया में आप उस वस्तु को फिर से असाइन नहीं कर सकते हैं जो पैरामीटर के रूप में पारित हुई है लेकिन आप फ़ंक्शन के सार्वजनिक सदस्य को तब बदल सकते हैं जब उस फ़ंक्शन का ऑब्जेक्ट किसी अन्य फ़ंक्शन के पैरामीटर के रूप में सेट हो।

की याद हैं

मॉड्यूल का उपयोग करें। केवल और जब आप कीवर्ड का उपयोग करना चाहते हैं तो आप एक फ़ंक्शन प्राप्त करना चाहते हैं। ऊपर के उदाहरण में हम var foo = आवश्यकता (a.js); आप देख सकते हैं कि हम फू को फंक्शन कह सकते हैं;

इस प्रकार नोड डॉक्यूमेंटेशन यह समझाता है "निर्यात वस्तु मॉड्यूल सिस्टम द्वारा बनाई गई है। कभी-कभी यह स्वीकार्य नहीं होता है, कई चाहते हैं कि उनका मॉड्यूल कुछ वर्ग का उदाहरण हो। ऐसा करने के लिए वांछित निर्यात वस्तु को मॉड्यूल ।exports को असाइन करें।"


0
  1. दोनों module.exportsऔर exportsएक ही तरफ इशारा करते हैं function database_module(cfg) {...}

    1| var a, b;
    2| a = b = function() { console.log("Old"); };
    3|     b = function() { console.log("New"); };
    4|
    5| a(); // "Old"
    6| b(); // "New"

    आप bलाइन 3 से बदल सकते हैं a, आउटपुट रिवर्स है। निष्कर्ष यह है:

    aऔर bस्वतंत्र हैं।

  2. तो module.exports = exports = nano = function database_module(cfg) {...}इसके बराबर है:

    var f = function database_module(cfg) {...};
    module.exports = f;
    exports = f;

    ऊपर मान लिया गया है module.js, जिसकी आवश्यकता है foo.js। के लाभ module.exports = exports = nano = function database_module(cfg) {...}अब स्पष्ट है:

    • में foo.js, चूंकि module.exportsहै require('./module.js'):

      var output = require('./modules.js')();
    • में moduls.js: आप के exportsबजाय का उपयोग कर सकते हैं module.exports

इसलिए, जब आप दोनों अगर खुश हो जाएगा exportsऔर module.exportsएक ही बात की ओर इशारा करते।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.