Cum pentru a stoca Node.js desfășurarea setări/configurare fișiere?

Am fost de lucru pe câteva Nod aplicații, și am'am fost în căutarea pentru un bun model de stocare de implementare legate de setări. În Django lume (de unde vin eu), comune în practică ar fi să avem un settings.py` fișier care conține setările standard (fus orar, etc), și apoi o local_settings.py pentru desfășurarea setări specifice, de exemplu. ce bază de date care să vorbești, ce memcache soclu, adresa de e-mail pentru administratori și așa mai departe.

Am fost în căutarea pentru modele similare pentru Nod. Doar un fișier de configurare ar fi frumos, așa că nu trebuie să fie blocată în cu totul altceva în app.js`, dar mi se pare important de a avea o modalitate de a avea specifice serverului de configurare într-un fișier care nu este în control sursă. Aceeași aplicație ar putea fi implementat pe diferite servere cu diferite salbatic setări, și având de a face cu îmbinare conflicte și cu toate că nu este ideea mea de distracție.

Deci, există un fel de cadru/instrument pentru acest lucru, sau nu doar toată lumea hack ceva împreună ei înșiși?

Comentarii la întrebare (1)

Eu folosesc un pachet.json pentru pachete și o config.js pentru configuratia mea, care arata ca:

var config = {};

config.twitter = {};
config.redis = {};
config.web = {};

config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;

module.exports = config;

Am încărca config din proiectul meu:

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

și atunci pot să am acces la lucruri din config.db_host, config.db_port, etc... Asta îmi permite să fie utilizați hardcoded parametri, sau parametrii stocate în variabile de mediu, dacă nu't vreau pentru a stoca parolele într-sursă control.

Am, de asemenea, de a genera un pachet.json și introduce o dependențe secțiune:

"dependencies": {
  "cradle": "0.5.5",
  "jade": "0.10.4",
  "redis": "0.5.11",
  "socket.io": "0.6.16",
  "twitter-node": "0.0.2",
  "express": "2.2.0"
}

Când am clona proiectul meu locale mașină, conduc npm install pentru a instala pachetele. Mai multe informatii pe care aici.

Proiectul este stocat în GitHub, cu telecomenzi adăugat pentru server de producție.

Comentarii (18)

Puteți solicita fișiere JSON fel de Nod v0.5.x (referire la acest raspuns)

config.json:

{
    "username" : "root",
    "password" : "foot"
}

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
Comentarii (3)
Soluția

Mult mai târziu, am găsit-o destul de bine Node.js modulul de management de configurare: nconf.

Un exemplu simplu:

var nconf = require('nconf');

// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();

// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });

// Provide default values for settings not provided above.
nconf.defaults({
    'http': {
        'port': 1337
    }
});

// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

Acesta susține, de asemenea, stocarea setările din Redis, scriere fișiere de configurare, și are o destul de solid API, și este, de asemenea, susținută de una dintre cele mai bine-respectat Node.js magazine, Nodejitsu, ca parte a Fier de călcat cadru de inițiativă, așa că ar trebui să fie destul de viitor.

Check out nconf la Github.

Comentarii (15)

Soluția mea este destul de simplă:

Încărcați mediu config în ./config/index.js

var env = process.env.NODE_ENV || 'development'
  , cfg = require('./config.'+env);

module.exports = cfg;

Definirea unor valori implicite în ./config/config.global.js

var config = module.exports = {};

config.env = 'development';
config.hostname = 'dev.example.com';

//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

Suprascrie setările implicite în ./config/config.test.js

var config = require('./config.global');

config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';

module.exports = config;

Folosind-o în ./models/user.js:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

Rulează aplicația în mediul de testare:

NODE_ENV=test node ./app.js

Acest lucru este explicat în detaliu aici: http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/

Comentarii (4)

S-ar putea uita, de asemenea, la dotenv care urmează principiile unei doisprezece-factor app.

Am folosit pentru a utiliza node-config, dar a creat dotenv pentru acest motiv. Acesta a fost complet inspirat de ruby's dotenv bibliotecă.

Utilizarea este destul de simplu:

var dotenv = require('dotenv');
dotenv.load();

Apoi, trebuie doar să creați un .env fișier și pune-ți setările de acolo astfel:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Ca's dotenv pentru nodejs.

Comentarii (4)

Sunteți folosind npm pentru a începe dvs. de script-uri (env etc) ?

Dacă utilizați .env fișierele puteți să le includă în pachet.json și de a folosi npm la sursă/start-le.

Exemplu:

{
  "name": "server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node test.js",
    "start-dev": "source dev.env; node test.js",
    "start-prod": "source prod.env; node test.js"
  },
  "dependencies": {
    "mysql": "*"
  }
}

apoi executați npm scripturi:

$ npm start-dev

Sale descrise aici https://gist.github.com/ericelliott/4152984 Toate de credit pentru Eric Elliot

Comentarii (4)

S-ar putea uita, de asemenea, la node-config care încarcă fișierul de configurare în funcție de $GĂZDUI și __$NODUL_MEDIU__ variabilă (un pic ca RoR) : documentație.

Acest lucru poate fi destul de util pentru diferite implementare setări ("dezvoltarea", "test" sau "producție").

Comentarii (0)

Nu doar un simplu `settings.js cu "exporturi":

exports.my_password = 'value'

Apoi, în script-ul dvs., face o nevoie:

var settings = require('./settings.js');

Toate setările acum va fi la dispoziție, prin intermediul "setări" variabilă:

settings.my_password // 'value'
Comentarii (2)

Am'm de gând să arunce pălăria în ring aici pentru că nici unul dintre aceste răspunsuri adresa toate componentele critice care destul de mult orice sistem are nevoie. Considerente:

  • Publice de configurare (care poate fi văzut de frontend) vs privat de configurare (tip mograbi avut dreptate). Și asigurându-acestea sunt păstrate separat.
  • Secrete, cum ar fi chei
  • Implicite vs mediului specifice suprascrie
  • Interfață pachete

Aici's cum fac configuratia mea:

  • config.default.private.js - În versiunea de control, acestea sunt implicit opțiuni de configurare care poate fi văzută numai de dvs. backend.
  • config.default.public.js - În versiunea de control, acestea sunt implicit opțiuni de configurare care pot fi văzute de backend și frontend
  • `config.dev.private.js - Dacă ai nevoie de diferite privat implicite pentru dev.
  • `config.dev.public.js - Dacă ai nevoie de diferite publică implicite pentru dev.
  • config.private.js - Nu în versiunea de control, acestea sunt mediul opțiuni specifice care pot suprascrie config.default.private.js
  • config.public.js - Nu în versiunea de control, acestea sunt mediul opțiuni specifice care pot suprascrie config.default.public.js
  • cheile/` - Un dosar în care fiecare fișier stochează un alt secret de-un fel. Acest lucru este, de asemenea, nu se află sub controlul versiunii (tastele nu ar trebui să fie sub control de versiune).

Eu folosesc simplu-vechi javascript fișiere de configurare, așa că am avea puterea deplină de javascript langauge (inclusiv comentarii și capacitatea de a face lucruri cum ar fi load default config în mediul de fișier specifice astfel încât acestea pot fi apoi înlocuite). Dacă doriți să utilizați variabile de mediu, puteți să încărcați-le în interiorul acestor fișiere de configurare (tho recomand utilizarea env var pentru același motiv pentru care nu't recomandăm să utilizați fișiere json - nu't au puterea de un limbaj de programare pentru a construi dvs. de configurare).

Motivul pentru fiecare cheie este într-un fișier separat pentru instalare utilizare. Acest lucru vă permite să aveți un program de instalare, care creează cheile de la mașină și le stochează în cheile folder. Fără acest lucru, installer ar putea eșua atunci când încărcați fișier de configurare care poate't de acces cheile. În acest fel puteți traversa director și încărca orice fișiere cheie care sunt în acel dosar, fără a fi nevoie să vă faceți griji despre ceea ce există și ceea ce nu't în orice versiune de cod.

Din moment ce, probabil au cheile încărcate în privat de configurare, te siguranță nu't doriți să încărcați privat config în orice frontend cod. În timp ce, probabil, strict mai ideal pentru a separa complet frontend codebase din backend dvs., de multe ori, asta PITA este o destul de mare bariera pentru a preveni oamenii de la a face, astfel, privat vs public config. Dar nu's două lucruri pe care le fac pentru a preveni privat config fi încărcate în interfața:

  1. Am o unitate de testare care asigură mea frontend pachete don't să conțină una din cheile secrete am în privat config.
  2. Am frontend cod într-un alt folder decât backend cod, și am două fișiere diferite nume "config.js" - cate unul pentru fiecare parte. Pentru backend, config.js încarcă privat config, pentru frontend, se încarcă publice config. Atunci ai nevoie de('config') si don't vă faceți griji despre de unde vine.

Un ultim lucru: configuratia ta ar trebui să fie încărcate în browser-ul prin intermediul unui complet fișier separat decât orice alte frontend cod. Daca ai pachet de interfață cod, publicul de configurare ar trebui să fie construit ca un pachet complet separate. În caz contrar, config e't într-adevăr config mai - doar o parte din cod. Config trebuie să fie capabil de a fi diferit pe diferite masini.

Comentarii (2)

Condamna este o altă opțiune care adaugă o schema pentru validare. Ca nconf, se sprijină de încărcare setări din orice combinație de variabile de mediu, argumente, fișiere și obiecte json.

Exemplu din README:

var convict = require('convict');
var conf = convict({
  env: {
    doc: "The applicaton environment.",
    format: ["production", "development", "test"],
    default: "development",
    env: "NODE_ENV"
  },
  ip: {
    doc: "The IP address to bind.",
    format: "ipaddress",
    default: "127.0.0.1",
    env: "IP_ADDRESS",
  },
  port: {
    doc: "The port to bind.",
    format: "port",
    default: 0,
    env: "PORT"
  }
});

Noțiuni de bază articolul: Îmblânzirea Configurații cu node-convict

Comentarii (0)

Puteți utiliza Konfig pentru mediu specifice fișiere de configurare. Se încarcă json sau yaml config fișiere în mod automat, acesta are implicit valoarea și configurare dinamică caracteristici.

Un exemplu de Konfig repo:

File: config/app.json
----------------------------
{
    "default": {
        "port": 3000,
        "cache_assets": true,
        "secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
    },

    "development": {
        "cache_assets": false
    },

    "test": {
        "port": 3001
    },

    "staging": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    },

    "production": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    }
}

În dezvoltare:

> config.app.port
3000

În producție, presupune să începem aplicarea cu $ NODE_ENV=producția PORT=4567 nod app.js

> config.app.port
4567

Mai multe detalii : https://github.com/vngrs/konfig

Comentarii (0)

Voi crea un folder config ca o denumire fișier ca `config.js și mai târziu, voi folosi acest fișier oriunde este necesar ca mai jos

Exemplu de config.js

module.exports = {
    proxyURL: 'http://url:port',
    TWITTER: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    GOOGLE: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    },
    FACEBOOK: {
        consumerkey: 'yourconsumerkey',
        consumerSecrete: 'yourconsumersecrete'
    }
}

Apoi, dacă vreau să folosesc acest config undeva

Voi primul import de mai jos

var config = necesită('./config');

și nu am acces la valorile de mai jos

const oauth = OAuth({
    consumer: {
        key: config.TWITTER.consumerkey,
        secret: config.TWITTER.consumerSecrete
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
});
Comentarii (0)

Doar folosi npmmoduleconfig` (mai mult de 300.000 de descărcări)

https://www.npmjs.com/package/config

Node-config organizează ierarhic configurații pentru aplicația dvs. implementări.

Acesta vă permite să definiți un set de parametri implicite, și le extinde pentru diferite implementare medii (de dezvoltare, de asigurare a calității, de intermediere, de producție, etc.).

$ npm install config
$ mkdir config
$ vi config/default.json

{
      // Customer module configs
      "Customer": {
        "dbConfig": {
          "host": "localhost",
          "port": 5984,
          "dbName": "customers"
        },
        "credit": {
          "initialLimit": 100,
          // Set low for development
          "initialDays": 1
        }
      }
}

$ vi config/production.json

{
  "Customer": {
    "dbConfig": {
      "host": "prod-db-server"
    },
    "credit": {
      "initialDays": 30
    }
  }
}

$ vi index.js

var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);

if (config.has('optionalFeature.detail')) {
  var detail = config.get('optionalFeature.detail');
  //...
}

$ export NODE_ENV=production
$ node index.js
Comentarii (0)

L's mai bine să se separe 'dezvoltarea' și 'producție' configs.

Eu folosesc după cum urmează: Aici este meu config/index.js file:

const config = {
    dev : {
        ip_address : '0.0.0.0',
        port : 8080,
        mongo :{
            url : "mongodb://localhost:27017/story_box_dev",
            options : ""
        }
    },
    prod : {
        ip_address : '0.0.0.0',
        port : 3000,
        mongo :{
            url : "mongodb://localhost:27017/story_box_prod",
            options : ""
        }
    }
} 

Pentru necesită configurare, utilizați următoarele opțiuni:

const config = require('../config')[process.env.NODE_ENV];

Decât vă puteți folosi config obiect:

const ip_address = config.ip_address;
const port = config.port;
Comentarii (1)

Eu sunt un pic mai târziu în joc, dar nu puteam't găsi ceea ce am nevoie aici - sau oriunde altundeva - așa că am scris ceva.

Cerințele mele pentru un mecanism de configurare sunt următoarele:

  1. Suport de front-end. Ce este punctul în cazul în front-end nu se poate folosi de configurare?
  2. Suport settings-overrides.js - care arată la fel, dar vă permite de relevare a informațiilor de configurare de la settings.js`. Ideea aici este de a modifica configurația cu ușurință, fără a schimba codul. Mi se pare util pentru saas.

Chiar dacă îmi pasă mai puțin despre susținerea medii - va explica cum să adăugați cu ușurință la soluția mea

var publicConfiguration = {
    "title" : "Hello World"
    "demoAuthToken" : undefined, 
    "demoUserId" : undefined, 
    "errorEmail" : null // if null we will not send emails on errors. 

};

var privateConfiguration = {
    "port":9040,
    "adminAuthToken":undefined,
    "adminUserId":undefined
}

var meConf = null;
try{
    meConf = require("../conf/dev/meConf");
}catch( e ) { console.log("meConf does not exist. ignoring.. ")}

var publicConfigurationInitialized = false;
var privateConfigurationInitialized = false;

function getPublicConfiguration(){
    if (!publicConfigurationInitialized) {
        publicConfigurationInitialized = true;
        if (meConf != null) {
            for (var i in publicConfiguration) {
                if (meConf.hasOwnProperty(i)) {
                    publicConfiguration[i] = meConf[i];
                }
            }
        }
    }
    return publicConfiguration;
}

function getPrivateConfiguration(){
    if ( !privateConfigurationInitialized ) {
        privateConfigurationInitialized = true;

        var pubConf = getPublicConfiguration();

        if ( pubConf != null ){
            for ( var j in pubConf ){
                privateConfiguration[j] = pubConf[j];
            }
        }
        if ( meConf != null ){
              for ( var i in meConf ){
                  privateConfiguration[i] = meConf[i];
              }
        }
    }
    return privateConfiguration;

}

exports.sendPublicConfiguration = function( req, res ){
    var name = req.param("name") || "conf";

    res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
};

var prConf = getPrivateConfiguration();
if ( prConf != null ){
    for ( var i in prConf ){
        if ( prConf[i] === undefined ){

            throw new Error("undefined configuration [" + i + "]");
        }
        exports[i] = prConf[i];
    }
}

return exports;

Explicație

  • "nedefinit" înseamnă această proprietate este necesară
  • null înseamnă că este optional
  • meConf - în prezent, codul este ținta într-un fișier sub "app". meConf este suprascrie fișierele care se adreseaza conf/dev - care este ignorat de catre mea vcs.
  • publicConfiguration - va fi vizibil de la front-end și back-end.
  • privateConfiguration - va fi vizibil din back-end numai.
  • sendPublicConfiguration - un traseu care va expune public de configurare și atribuiți-l la o variabilă globală. De exemplu, codul de mai jos va expune public de configurare ca variabilă globală myConf în front-end. În mod implicit se va folosi variabila globală numele conf.

app.ia("/backend/conf", avea nevoie("conf").sendPublicConfiguration);

<script src="/backend/conf?name=myConf" type="javascript/text">

Logica suprascrie

  • privateConfiguration este fuzionat cu publicConfiguration și apoi meConf.
  • publicConfiguration verifică fiecare cheie dacă acesta are o suprascrie, și folosește prototipul. În acest fel nu suntem expunerea ceva privat.

Adăugând mediu de sprijin

Chiar dacă eu nu't găsi un "mediu" util, poate cineva o va face.

Pentru a adăuga mediului sprijinul de care aveți nevoie pentru a schimba meConf nevoie de declarație la ceva de genul asta (pseudocod)

dacă ( mediu == "producție" ) { meConf = necesită("../conf/dev/meConf").de producție; }

dacă ( mediu == "dezvoltare" ) { meConf = necesită("../conf/dev/meConf").de dezvoltare; }

În mod similar, puteți avea un fișier per mediu

 meConf.development.js
 meConf.production.js

și de import de cea dreapta. Restul de logica rămâne aceeași.

Comentarii (2)

un alt exemplu am folosit pentru că am vrut mai multă flexibilitate decât un tipic .fișier json dar nu't vreau captate într-o bibliotecă care ar necesita o dependență este ceva de genul asta. Practic, exportul de o funcție invocat imediat care a returnat un obiect cu valori am vrut stabilit. Oferă o mulțime de flexibilitate.

     module.exports = function(){
       switch(node_env){
         case 'dev':
           return
           { var1 = 'development'};
         }
    }();

Există o mult mai bună explicație cu deplină exemplu aici. Folosind Fișiere de Configurare în Node.js

Comentarii (0)

Știu că acest lucru este un foarte vechi post. Dar vreau să-mi împărtășesc modul pentru configurarea variabilelor de mediu, cred că este foarte flexibilă soluție. Aici este modul json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '/users',
    'accounts': '/accounts'
    },
  foo: 'bar',
  foobar: 'foobar',
  $prod_foo: 'foo in prod',
  $test_foo: 'foo in test',
  deep:{
    veryDeep: {
      publicKey: 'abc',
      secret: 'secret',
      $prod_secret: 'super secret'
    }
  }
};

var config = require('json-configurator')(configJson, 'prod');

console.log(config.deep.veryDeep.secret) 
// super secret 

console.log(config.endpoints.users)
// https://prod.com/users 

Apoi, puteți utiliza proces.env.NODE_ENV pentru a obține toate variabilele pentru mediul dumneavoastră.

Comentarii (1)

În plus față de nconf modul menționat în acest răspuns, node-config menționat în acest răspuns, există, de asemenea, nod-iniparser și IniReader, care par a fi mai simple .ini fișier de configurare interpretoare.

Comentarii (1)

Recent am lansat un modul mic de a încărca orice tip de fișiere de configurare. L's destul de straight-forward, puteți verifica la https://github.com/flesler/config-node

Comentarii (0)

Puteți utiliza pconf: https://www.npmjs.com/package/pconf

Exemplu:

var Config = require("pconf");
var testConfig = new Config("testConfig");
testConfig.onload = function(){

  testConfig.setValue("test", 1);
  testConfig.getValue("test");
  //testConfig.saveConfig(); Not needed

}
Comentarii (0)