Node.js में फ़ाइलों के बीच चर साझा करें?


126

यहाँ 2 फाइलें हैं:

// main.js
require('./modules');
console.log(name); // prints "foobar"

// module.js
name = "foobar";

जब मेरे पास "var" नहीं है तो यह काम करता है। लेकिन जब मेरे पास है:

// module.js
var name = "foobar";

नाम main.js. में अपरिभाषित होगा

मैंने सुना है कि वैश्विक चर खराब हैं और आप संदर्भों से पहले "var" का बेहतर उपयोग करते हैं। लेकिन क्या यह ऐसा मामला है जहां वैश्विक चर अच्छे हैं?

जवाबों:


184

वैश्विक चर लगभग अच्छी चीज नहीं हैं (हो सकता है कि कोई अपवाद हो या दो वहाँ ...)। इस मामले में, ऐसा लगता है कि आप वास्तव में अपना "नाम" चर निर्यात करना चाहते हैं। उदाहरण के लिए,

// module.js
var name = "foobar";
// export it
exports.name = name;

फिर, main.js में ...

//main.js
// get a reference to your required module
var myModule = require('./module');

// name is a member of myModule due to the export above
var name = myModule.name;

1
वैश्विक चर खराब हैं - मैं इससे पूरी तरह सहमत हूं। लेकिन मैं हो सकता है, कि मॉड्यूल एक चर के लिए एक निर्भरता है। क्या आवश्यकता फ़ंक्शन के माध्यम से इस चर को अन्य जेएस-फ़ाइल में पारित करने का एक तरीका है?
appsthatmatter

1
@ jjoe64 मुझे यकीन नहीं है कि आपका मतलब क्या है। आप exportsऑब्जेक्ट के माध्यम से अपने इच्छित मूल्य को प्रभावी रूप से साझा कर सकते हैं ।
jmar777

7
ओपी पूछ रहा है कि क्या मुख्य चर में एक चर को परिभाषित किया जा सकता है, और फिर मॉड्यूल में उपयोग किया जा सकता है। मुझे उन रास्तों को परिभाषित करने की समान आवश्यकता है जो बार-बार उपयोग किए जाते हैं।
designermonkey

4
@Designermonkey उस मामले में आप शायद उन प्रकार के मानों के साथ एक कॉन्फिग ऑब्जेक्ट होने से बेहतर हैं जिन्हें किसी दिए गए फ़ाइल में भी () की आवश्यकता हो सकती है। ध्यान दें कि आप अभी कर सकते हैं global.foo = 'bar'और फिर fooकहीं भी पहुंच सकते हैं ... लेकिन जैसा मैंने अपने मूल उत्तर में कहा था, वह लगभग अच्छी बात नहीं है।
jmar777

इसके लिए धन्यवाद, मुझे पता चला कि ऐसा कैसे करना है, और यह एक इलाज का काम करता है। सत्यापित करने के लिए धन्यवाद मेरे पास सही विचार है :)
designermonkey

37

मैं ऐसा परिदृश्य नहीं खोज पा रहा हूं, जहां एक वैश्विक varविकल्प सबसे अच्छा हो, निश्चित रूप से आप एक हो सकते हैं, लेकिन इन उदाहरणों पर एक नज़र डालें और आप इसे पूरा करने का एक बेहतर तरीका पा सकते हैं:

परिदृश्य 1: कॉन्फ़िगर फ़ाइलों में सामान रखें

आपको आवेदन के दौरान समान मूल्य की आवश्यकता है, लेकिन यह पर्यावरण (उत्पादन, देव या परीक्षण), मेलर प्रकार उदाहरण के आधार पर बदलता है, आपको इसकी आवश्यकता होगी:

// File: config/environments/production.json
{
    "mailerType": "SMTP",
    "mailerConfig": {
      "service": "Gmail",
      ....
}

तथा

// File: config/environments/test.json
{
    "mailerType": "Stub",
    "mailerConfig": {
      "error": false
    }
}

(देव के लिए भी एक समान विन्यास बनाएं)

यह तय करने के लिए कि कौन सा कॉन्फिगर लोड किया जाएगा, एक मुख्य कॉन्फिग फाइल बनायेगा (इसका उपयोग पूरे एप्लिकेशन में किया जाएगा)

// File: config/config.js
var _ = require('underscore');

module.exports = _.extend(
    require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});

और अब आप इस तरह से डेटा प्राप्त कर सकते हैं :

// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));

परिदृश्य 2: एक स्थिरांक फ़ाइल का उपयोग करें

// File: constants.js
module.exports = {
  appName: 'My neat app',
  currentAPIVersion: 3
};

और इसे इस तरह से उपयोग करें

// File: config/routes.js

var constants = require('../constants');

module.exports = function(app, passport, auth) {
  var apiroot = '/api/v' + constants.currentAPIVersion;
...
  app.post(apiroot + '/users', users.create);
...

परिदृश्य 3: डेटा प्राप्त / सेट करने के लिए एक सहायक फ़ंक्शन का उपयोग करें

इसका एक बड़ा प्रशंसक नहीं है, लेकिन कम से कम आप 'नाम' (ओपी के उदाहरण का हवाला देते हुए) के उपयोग को ट्रैक कर सकते हैं और मान्यताओं को लागू कर सकते हैं।

// File: helpers/nameHelper.js

var _name = 'I shall not be null'

exports.getName = function() {
  return _name;
};

exports.setName = function(name) {
  //validate the name...
  _name = name;
};

और इसका उपयोग करें

// File: controllers/users.js

var nameHelper = require('../helpers/nameHelper.js');

exports.create = function(req, res, next) {
  var user = new User();
  user.name = req.body.name || nameHelper.getName();
  ...

एक उपयोग मामला हो सकता है जब वैश्विक होने के अलावा कोई अन्य समाधान नहीं होता है var, लेकिन आमतौर पर आप अपने ऐप में इन परिदृश्यों में से एक का उपयोग करके डेटा साझा कर सकते हैं, यदि आप नोड का उपयोग करना शुरू कर रहे हैं। जेएस (जैसा कि मैं कुछ समय पहले था) जिस तरह से आप डेटा को वहां संभालते हैं उसे व्यवस्थित करने के लिए क्योंकि यह वास्तव में जल्दी गड़बड़ हो सकता है।


मुझे परिदृश्य 2 पसंद आया, लेकिन क्या हम निर्माण के बाद इन मूल्यों को बदल सकते हैं? सबसे अधिक बार हम करते हैं, npm रन बिल्ड। या क्या आप जानते हैं कि निर्माण के बाद मूल्यों को बदलने में सक्षम होने का कोई तरीका है?
काशिफ उल्ला

@ काशिफुल्लाह को यकीन नहीं है कि अगर मैं आपकी टिप्पणी का जवाब सिर्फ दी गई जानकारी के साथ दे पा रहा हूं, तो आप साइट में एक नया सवाल जोड़ना चाह सकते हैं
फेलिप परेरा

16

अगर हमें कई चर साझा करने की आवश्यकता है तो नीचे दिए गए प्रारूप का उपयोग करें

//module.js
   let name='foobar';
   let city='xyz';
   let company='companyName';

   module.exports={
    name,
    city,
    company
  }

प्रयोग

  // main.js
    require('./modules');
    console.log(name); // print 'foobar'

2
बस एक त्वरित नोट भ्रम को छोड़ दिया है जो पहले स्थान पर उत्पन्न हो सकता है: मॉड्यूल.एक्सपोर्ट वह है जिसका उपयोग किया जाना चाहिए! जो भी आपकी js फ़ाइल कहलाती है (उदा: Global.js)। मॉड्यूल एक नोड ऑब्जेक्ट है जो वैश्विक दायरे में मौजूद है! [so Global.js के भीतर हम मॉड्यूल का उपयोग करते हैं। निर्यात = .....]
मोहम्मद

यदि आप 'लेट' को हटा देते हैं, तो यह सफल हो जाएगा, और "mod.exports .." की कोई आवश्यकता नहीं है
अहमद

6

किसी भी वैरिएबल को सेव करें जिसे एक ऑब्जेक्ट के रूप में साझा किया जाना है। फिर इसे लोड किए गए मॉड्यूल से पास करें ताकि यह ऑब्जेक्ट संदर्भ के माध्यम से चर तक पहुंच सके।

// main.js
var myModule = require('./module.js');
var shares = {value:123};

// Initialize module and pass the shareable object
myModule.init(shares);

// The value was changed from init2 on the other file
console.log(shares.value); // 789

दूसरी फाइल पर ..

// module.js
var shared = null;

function init2(){
    console.log(shared.value); // 123
    shared.value = 789;
}

module.exports = {
    init:function(obj){
        // Save the shared object on current module
        shared = obj;

        // Call something outside
        init2();
    }
}

1

वैरिएबल के साथ या उसके बिना घोषित एक वैरिएबल ग्लोबल ऑब्जेक्ट से जुड़ा हुआ है। यह नोड में वैरिएबल के बिना वैरिएबल घोषित करके वैश्विक चर बनाने का आधार है। जबकि चर के साथ घोषित चर एक मॉड्यूल के लिए स्थानीय रहते हैं।

इस लेख को और समझने के लिए देखें - https://www.hacksparrow.com/global-variables-in-node-js.html


3
क्या ये टुकड़े विरोधाभासी हैं? 1) "वैरिएबल के साथ या उसके बिना घोषित एक वैरिएबल ग्लोबल ऑब्जेक्ट से जुड़ा हुआ है।" और 2) "वेरिएबल के साथ घोषित चर एक मॉड्यूल के लिए स्थानीय रहते हैं।"
21

1

एक अलग राय के साथ, मुझे लगता है कि globalअगर आप अपना कोड प्रकाशित करने जा रहे हैं तो चर सबसे अच्छा विकल्प हो सकता है npm, क्यूज़ आप यह सुनिश्चित नहीं कर सकते कि सभी पैकेज आपके कोड के एक ही रिलीज़ का उपयोग कर रहे हैं। इसलिए यदि आप किसी singletonऑब्जेक्ट को एक्सपोर्ट करने के लिए फाइल का उपयोग करते हैं , तो यह यहां समस्या का कारण बनेगा।

आप चुन सकते हैं global, require.mainया कोई भी अन्य ऑब्जेक्ट जो फ़ाइलों में साझा किए गए हैं।

कृपया बताएं कि क्या कुछ बेहतर उपाय हैं।

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