Node.js हर विशिष्ट के साथ उपयोग किए जाने वाले पर्यावरण विशिष्ट विन्यास की स्थापना करता है


117

मैं नोड .js + express.js + everyauth.js का उपयोग कर रहा हूं। मैंने अपने सभी हर तर्क को एक मॉड्यूल फ़ाइल में स्थानांतरित कर दिया है

var login = require('./lib/everyauthLogin');

इसके अंदर मैंने अपने oAuth config फाइल को कुंजी / गुप्त संयोजनों के साथ लोड किया:

var conf = require('./conf');
.....
twitter: {
    consumerKey: 'ABC', 
    consumerSecret: '123'
}

ये कोड अलग-अलग वातावरणों के लिए अलग-अलग हैं- विकास / स्टेजिंग / प्रोडक्शन क्योंकि कॉलबैक अलग-अलग यूआरएल के लिए हैं।

क्यू। मैं सभी मॉड्यूल्स के माध्यम से फ़िल्टर करने के लिए इनवायरमेंटल कॉन्फिगरेशन में कैसे सेट कर सकता हूँ या क्या मैं सीधे मॉड्यूल में रास्ता पार कर सकता हूँ?

Env में सेट करें:

app.configure('development', function(){
  app.set('configPath', './confLocal');
});

app.configure('production', function(){
  app.set('configPath', './confProduction');
});

var conf = require(app.get('configPath'));

उत्तीर्ण में

app.configure('production', function(){
  var login = require('./lib/everyauthLogin', {configPath: './confProduction'});
});

? आशा है कि समझ में आता है


एक ऐसा समाधान मिला जो नीचे दिए गए कुछ विचारों का उपयोग कर रहा है, किसी वस्तु के बजाय मॉड्यूल = फ़ंक्शन के द्वारा मैं process.env.NODE_ENV का मूल्यांकन कर सकता हूं और पर्यावरण के लिए सही वस्तु वापस कर सकता हूं। थोड़ा गन्दा लेकिन काम करता है।
andy t

बेशर्म आत्म-प्रचार को क्षमा करें, लेकिन मैंने नोड के लिए एक मॉड्यूल लिखा था। जेएस जो अलग-अलग फ़ाइलों और एक कमांड-लाइन स्विच के माध्यम से ऐसा करेगा: नोड-कॉन्फ़िगर
Randolpho

जवाबों:


192

मेरा समाधान,

एप्लिकेशन का उपयोग कर लोड करें

NODE_ENV=production node app.js

फिर config.jsएक वस्तु के बजाय एक फ़ंक्शन के रूप में सेटअप करें

module.exports = function(){
    switch(process.env.NODE_ENV){
        case 'development':
            return {dev setting};

        case 'production':
            return {prod settings};

        default:
            return {error or other settings};
    }
};

फिर जैन्स सॉल्यूशन के अनुसार फाइल को लोड करें और एक नया उदाहरण बनाएं जिसे हम जरूरत पड़ने पर पास कर सकते हैं, इस मामले process.env.NODE_ENVमें वैश्विक है इसलिए इसकी जरूरत नहीं है।

var Config = require('./conf'),
    conf = new Config();

तब हम पहले की तरह ही कॉन्फिडेंट ऑब्जेक्ट प्रॉपर्टीज एक्सेस कर सकते हैं

conf.twitter.consumerKey

2
आप यहाँ नया प्रयोग क्यों कर रहे हैं?
ब्लूहल्लु

5
मैं दूसरा @bluehallu। है newआवश्यक?
गायन चो

2
विंडोज में समतुल्य होगा NODE_ENV = विकास
मुजफ्फर

3
करने के बजाय new। मैं निम्नलिखित कार्य करता हूं config.js....Config = function(){...}; module.exports = Config()
अट्टू

क्या होगा अगर मेरे पास 50 वेब सर्वर हैं, जिस स्थिति में प्रत्येक सर्वर पर जाने के लिए स्क्रिप्ट को मैन्युअल रूप से शुरू करना मुश्किल है
Rajesh

60

आपके पास शीर्ष स्तर के रूप में NODE_ENV के साथ एक JSON फ़ाइल भी हो सकती है। IMO, कॉन्फ़िगरेशन सेटिंग्स को व्यक्त करने का यह एक बेहतर तरीका है (स्क्रिप्ट का उपयोग करने के लिए विरोध किया जाता है जो सेटिंग्स लौटाता है)।

var config = require('./env.json')[process.env.NODE_ENV || 'development'];

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

{
    "development": {
        "MONGO_URI": "mongodb://localhost/test",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    },
    "production": {
        "MONGO_URI": "mongodb://localhost/production",
        "MONGO_OPTIONS": { "db": { "safe": true } }
    }
}

नमस्ते, क्या आप यह समझा सकते हैं कि आपको क्यों लगता है कि यह कॉन्फ़िगरेशन सेटिंग्स को व्यक्त करने का बेहतर तरीका है (जैसा कि सेटिंग्स लौटाने वाली स्क्रिप्ट का उपयोग करने के विपरीत)। ?
वेंकट कोटरा

14
मुझे लगता है कि इससे बहुत ज्यादा फर्क नहीं पड़ता। मानसिक रूप से, जब मैं JSON देखता हूं तो मुझे लगता है कि जब मैं JS फाइल देखता हूं तो मुझे 'स्टेटिक डेटा' बनाम, मुझे लगता है कि इसके अंदर कुछ तर्क है। इसके अलावा, .json प्रकार का उपयोग करने का एक और लाभ यह है कि अन्य भाषाएं एक ही फ़ाइल आयात कर सकती हैं।
18

1
@VenkatKotra कॉन्फ़िगरेशन को आमतौर पर स्थिर माना जाता है, और इसलिए सबसे अच्छी तरह से घोषित किया जाता है जैसे कि json, yaml, ini, इत्यादि जैसी चीजों के साथ। अनिवार्य रूप से, एक स्क्रिप्ट के साथ, जो उस राज्य को पैदावार देता है, सॉर्टोफ़ का अर्थ है कि कुछ गतिशील हो रहा है, जो खराब होगा।
अधिकतम

9
ज्ञात रहे कि यह विधि स्रोत नियंत्रण में साख को उजागर करती है।
पियर-ल्यूक गेंड्रेउ

मैं स्टेजिंग और उत्पादन के लिए diffrence url बना सकता हूं?
एलेक्स

34

एक बहुत ही उपयोगी समाधान कॉन्फ़िगरेशन मॉड्यूल का उपयोग करता है ।

मॉड्यूल स्थापित करने के बाद:

$ npm install config

आप एक default.json कॉन्फ़िगरेशन फ़ाइल बना सकते हैं । (आप एक्सटेंशन .json5 का उपयोग करके JSON या JS ऑब्जेक्ट का उपयोग कर सकते हैं)

उदाहरण के लिए

$ vi config/default.json

{
  "name": "My App Name",
  "configPath": "/my/default/path",
  "port": 3000
}

यह डिफ़ॉल्ट कॉन्फ़िगरेशन पर्यावरण कॉन्फ़िगरेशन फ़ाइल या स्थानीय विकसित वातावरण के लिए स्थानीय कॉन्फ़िगरेशन फ़ाइल द्वारा ओवरराइड किया जा सकता है:

production.json हो सकता है:

{
  "configPath": "/my/production/path",
  "port": 8080
}

development.json हो सकता है:

{
  "configPath": "/my/development/path",
  "port": 8081
}

आपके स्थानीय पीसी में आपके पास एक local.json हो सकता है जो सभी वातावरण को ओवरराइड करता है, या आपके पास एक विशिष्ट स्थानीय कॉन्फ़िगरेशन हो सकता है जैसे कि स्थानीय-प्रोडक्शनjson या स्थानीय-विकासjson

लोड ऑर्डर की पूरी सूची

आपके ऐप के अंदर

आपके ऐप में आपको केवल कॉन्फिग और आवश्यक विशेषता की आवश्यकता है।

var conf = require('config'); // it loads the right file
var login = require('./lib/everyauthLogin', {configPath: conf.get('configPath'));

App लोड करें

एप्लिकेशन का उपयोग करके लोड करें:

NODE_ENV=production node app.js

या हमेशा या pm2 के साथ सही वातावरण सेट करना

सदैव:

NODE_ENV=production forever [flags] start app.js [app_flags]

PM2 (शेल के माध्यम से):

export NODE_ENV=staging
pm2 start app.js

PM2 (थ्रू .json):

process.json

{
   "apps" : [{
    "name": "My App",
    "script": "worker.js",
    "env": {
      "NODE_ENV": "development",
    },
    "env_production" : {
       "NODE_ENV": "production"
    }
  }]
}

और तब

$ pm2 start process.json --env production

यह समाधान बहुत साफ है और यह उत्पादन / मंचन / विकास पर्यावरण के लिए और स्थानीय सेटिंग के लिए भी आसान विभिन्न विन्यास फाइल बनाता है।


npm स्थापित कॉन्फ़िगर --save, यह बेहतर नहीं है?
स्टैकडैव

14

संक्षेप में

इस तरह का एक सेटअप सरल और सुरुचिपूर्ण है:

env.json

{
  "development": {
      "facebook_app_id": "facebook_dummy_dev_app_id",
      "facebook_app_secret": "facebook_dummy_dev_app_secret",
  }, 
  "production": {
      "facebook_app_id": "facebook_dummy_prod_app_id",
      "facebook_app_secret": "facebook_dummy_prod_app_secret",
  }
}

common.js

var env = require('env.json');

exports.config = function() {
  var node_env = process.env.NODE_ENV || 'development';
  return env[node_env];
};

app.js

var common = require('./routes/common')
var config = common.config();

var facebook_app_id = config.facebook_app_id;
// do something with facebook_app_id

उत्पादन मोड में चलाने के लिए: $ NODE_ENV=production node app.js


विस्तार से

यह समाधान इस प्रकार है: http://himanshu.gilani.info/blog/2012/09/26/bootstraping-a-node-dot-js-app-for-dev-slash-prod-environment/ , इसकी जांच करें ज्यादा जानकारी।


5

जिस तरह से हम ऐसा करते हैं वह पर्यावरण के साथ ऐप शुरू करने में एक तर्क पारित करके है। उदाहरण के लिए:

node app.js -c dev

App.js में हम फिर dev.jsहमारी कॉन्फ़िगरेशन फ़ाइल के रूप में लोड करते हैं। आप इन विकल्पों को ऑप्टपर्स-जेएस के साथ पार्स कर सकते हैं ।

अब आपके पास कुछ कोर मॉड्यूल हैं जो इस कॉन्फ़िगरेशन फ़ाइल पर निर्भर करते हैं। जब आप उन्हें इस तरह लिखते हैं:

var Workspace = module.exports = function(config) {
    if (config) {
         // do something;
    }
}

(function () {
    this.methodOnWorkspace = function () {

    };
}).call(Workspace.prototype);

और आप इसे तब app.jsपसंद कर सकते हैं:

var Workspace = require("workspace");
this.workspace = new Workspace(config);

मैं app.js app.configure('developmentकोड के अंदर सभी तर्क रखना चाहूंगा , लेकिन यह देखने के लिए कि क्या मैं इसके साथ इस समाधान का उपयोग कर सकता हूं
andy t

इस उत्तर पर अपडेट करें: आर्किटेक्ट एक निर्भरता प्रबंधन ढांचा है जो इसे एक तरह से अच्छे तरीके से हल करता है।
जान जोंगबोम १ong

5

एक सुरुचिपूर्ण तरीका .envस्थानीय स्तर पर उत्पादन सेटिंग्स को ओवरराइड करने के लिए फ़ाइल का उपयोग करना है। कमांड लाइन स्विच की कोई आवश्यकता नहीं है। एक config.jsonफ़ाइल में उन सभी अल्पविराम और कोष्ठक की आवश्यकता नहीं है । मेरा जवाब यहां देखें

उदाहरण: मेरी मशीन पर .envफ़ाइल यह है:

NODE_ENV=dev
TWITTER_AUTH_TOKEN=something-needed-for-api-calls

मेरा स्थानीय .envकिसी भी पर्यावरण चर को ओवरराइड करता है। लेकिन मंचन या उत्पादन सर्वरों पर (शायद वे heroku.com पर हैं) पर्यावरण चर मंच NODE_ENV=stageया उत्पादन के लिए पूर्व निर्धारित हैं NODE_ENV=prod


4

परिनियोजन सर्वर में पर्यावरण चर सेट करें (उदा: NODE_ENV = उत्पादन की तरह)। आप अपने पर्यावरण चर को process.env.NODE_ENV के माध्यम से एक्सेस कर सकते हैं। वैश्विक सेटिंग्स के लिए निम्न कॉन्फ़िग फ़ाइल खोजें

const env = process.env.NODE_ENV || "development"

const configs = {
    base: {
        env,
        host: '0.0.0.0',
        port: 3000,
        dbPort: 3306,
        secret: "secretKey for sessions",
        dialect: 'mysql',
        issuer : 'Mysoft corp',
        subject : 'some@user.com',
    },
    development: {
        port: 3000,
        dbUser: 'root',
        dbPassword: 'root',

    },
    smoke: {
        port: 3000,
        dbUser: 'root',
    },
    integration: {
        port: 3000,
        dbUser: 'root',
    },
    production: {
        port: 3000,
        dbUser: 'root',
    }
};

const config = Object.assign(configs.base, configs[env]);

module.exports= config;

आधार में सभी वातावरणों के लिए सामान्य विन्यास है।

फिर जैसे अन्य मॉड्यूल में आयात करें

const config =  require('path/to/config.js')
console.log(config.port)

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


3

नोडज-कॉन्फिग मॉड्यूल के साथ बहुत अधिक सुरुचिपूर्ण तरीके से यह करने के बारे में कैसे ।

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

उदाहरण के लिए मान लें कि आपके पास PC1 और PC2 नाम की दो विकास मशीनें हैं और PC3 नामक एक उत्पादन मशीन है। जब आप PC1 या pc2 में अपने कोड में कॉन्फ़िगरेशन मानों का अनुरोध करते हैं, तो आपको "विकास" पर्यावरण कॉन्फ़िगरेशन प्राप्त करना होगा और pc3 में आपको "उत्पादन" पर्यावरण कॉन्फ़िगरेशन प्राप्त करना होगा। इसे इस तरह हासिल किया जा सकता है:

  1. कॉन्फ़िगरेशन निर्देशिका में आधार कॉन्फ़िगरेशन फ़ाइल बनाएं, "app.json" को कहने दें और इसमें आवश्यक कॉन्फ़िगरेशन जोड़ें।
  2. अब बस इस स्थिति "विकास" और "उत्पादन" में, आपके पर्यावरण के नाम से मेल खाने वाली कॉन्फ़िगरेशन निर्देशिका के भीतर फ़ोल्डर्स बनाएं।
  3. अगला, उन कॉन्फ़िगरेशन फ़ाइलों को बनाएं जिन्हें आप ओवरराइड करना चाहते हैं और पर्यावरण निर्देशिकाओं में प्रत्येक वातावरण के लिए विकल्प निर्दिष्ट करें (ध्यान दें कि आपको प्रत्येक विकल्प को निर्दिष्ट करने की आवश्यकता नहीं है जो आधार कॉन्फ़िगरेशन फ़ाइल में है, लेकिन केवल वे विकल्प जिन्हें आप ओवरराइड करना चाहते हैं।) पर्यावरण विन्यास फाइल बेस फाइलों पर "कैस्केड" करेगी।)

अब सिंटैक्स के साथ नया कॉन्फिग उदाहरण बनाएं।

var config = require('nodejs-config')(
   __dirname,  // an absolute path to your applications 'config' directory
   {
      development: ["pc1", "pc2"],
      production: ["pc3"],

   }
);

अब आप इस तरह पर्यावरण के बारे में चिंता किए बिना किसी भी विन्यास मूल्य प्राप्त कर सकते हैं:

config.get('app').configurationKey;

0

यह जवाब कुछ नया नहीं है। यह @andy_t के समान है। लेकिन मैं नीचे दिए गए पैटर्न का उपयोग दो कारणों से करता हूं।

  1. कोई बाहरी एनपीएम निर्भरता के साथ स्वच्छ कार्यान्वयन

  2. डिफ़ॉल्ट कॉन्फ़िगरेशन सेटिंग्स को पर्यावरण आधारित सेटिंग्स के साथ मर्ज करें।

जावास्क्रिप्ट कार्यान्वयन

const settings = {
    _default: {
       timeout: 100
       baseUrl: "http://some.api/",
    },
    production: {
       baseUrl: "http://some.prod.api/",
    },
}
// If you are not using ECMAScript 2018 Standard
// https://stackoverflow.com/a/171256/1251350
module.exports = { ...settings._default, ...settings[process.env.NODE_ENV] }

मैं आमतौर पर अपने नोड प्रोजेक्ट में टाइपस्क्रिप्ट का उपयोग करता हूं। नीचे मेरा वास्तविक कार्यान्वयन कॉपी-पेस्ट किया गया है।

टाइपस्क्रिप्ट कार्यान्वयन

const settings: { default: ISettings, production: any } = {
    _default: {
        timeout: 100,
        baseUrl: "",
    },
    production: {
        baseUrl: "",
    },
}

export interface ISettings {
    baseUrl: string
}

export const config = ({ ...settings._default, ...settings[process.env.NODE_ENV] } as ISettings)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.