Come archiviare le impostazioni di distribuzione / i file di configurazione di Node.js?


640

Ho lavorato su alcune app Node e ho cercato un buon modello di archiviazione delle impostazioni relative alla distribuzione. Nel mondo di Django (da dove vengo), la pratica comune sarebbe quella di avere un settings.pyfile contenente le impostazioni standard (fuso orario, ecc.) E quindi una local_settings.pyper le impostazioni specifiche della distribuzione, ad es. con quale database parlare, quale socket memcache, indirizzo e-mail per gli amministratori e così via.

Ho cercato modelli simili per Node. Solo un file di configurazione sarebbe carino, quindi non deve essere bloccato con tutto il resto app.js, ma trovo importante avere un modo per avere una configurazione specifica del server in un file che non è nel controllo del codice sorgente. La stessa app potrebbe essere distribuita su server diversi con impostazioni selvaggiamente diverse e dover affrontare conflitti di unione e tutto ciò non è la mia idea di divertimento.

Quindi esiste una sorta di framework / strumento per questo, o tutti fanno semplicemente qualcosa insieme?


Mi piace molto il modo in cui la configurazione viene fatta in mean.js . fondamentalmente, memorizzano la configurazione rilevante dell'app in una sorta di modulo separato, basato su impostazioni diverse per ambiente dell'app (per produzione, sviluppo, test) e passando dettagli specifici attraverso variabili di ambiente dell'app, come segreti ecc.
Hinrich

Risposte:


765

Uso a package.jsonper i miei pacchetti e a config.jsper la mia configurazione, che assomiglia a:

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;

Carico la configurazione dal mio progetto:

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

e quindi posso accedere alle mie cose da config.db_host, config.db_portecc. Questo mi permette di utilizzare parametri hardcoded o parametri memorizzati in variabili ambientali se non voglio archiviare le password nel controllo del codice sorgente.

Genero anche un package.jsone inserisco una sezione di dipendenze:

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

Quando clono il progetto sul mio computer locale, corro npm installper installare i pacchetti. Maggiori informazioni qui .

Il progetto è archiviato in GitHub, con telecomandi aggiunti per il mio server di produzione.


32
cosa succede quando si hanno diverse impostazioni di configurazione per dev vs. prod?
Chovy

4
Non ho ma ecco un modo per farlo .. per ogni env, impostare il nome env in una variabile ENV. Quindi in questo file, è solo javascript .. usa un'istruzione case o if per caricare selettivamente le variabili appropriate. Potresti persino creare un sottofile di configurazione separato per ogni env, e nell'istruzione if, ricaricare il file secondario qui in un subconfig var ed esportare quel subconfig var nella configurazione principale. Tutto quello che sto cercando di dire è che è solo js, così puoi essere creativo
noli,

4
che process.env? dove si trova? E come impostarlo?
kiwi arrabbiato,

12
Stavo pensando "wow .. sto guardando node.js da alcune ore e la mia app sta già funzionando .. a proposito, forse condividerò questo pezzetto di codice casuale che mi è venuto in mente"
noli

3
Non è ancora possibile utilizzare le variabili di ambiente per memorizzare quelle parole d'accesso? Non è questo lo scopo di questa riga: config.twitter.password = process.env.TWITTER_PASSWORD || 'parola d'ordine';
DMart,

244

È possibile richiedere file JSON a partire da Nodo v0.5.x (facendo riferimento a questa risposta )

config.json:

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

app.js:

var config = require('./config.json');
log_in(config.username, config.password);

40
Non così impressionato da quella funzione. Potresti richiedere ("./ config.js") e ottenere la possibilità di aggiungere commenti ai file di configurazione che ritengo molto importanti e ad altri campanelli e fischietti. Se si configura solo proprietà e nessun codice, non si perde nulla in base a un requisito (config.js) con il codice JSON prefissato da exports.config =
teknopaul,

3
@teknopaul hai ragione ma c'era una grande discussione in corso sulla "correttezza" / usabilità dell'uso di sistemi di templatura muti rispetto a quelli intelligenti che mi dicevano: (1) in genere vuoi un linguaggio dichiarativo / muto per il templating / opzioni (2) è una cattiva idea ricostruire un "quasi-PL" per fare semplicemente un modello (o configurazione), migliore per riutilizzare il tuo vero PL esistente con comportamenti noti. finora +1 per il riciclaggio di JS per eseguire le impostazioni dell'utente; -1 per non seguire l'approccio dichiarativo. abbiamo visto alcune cose di configurazione piuttosto complesse fatte in modo dichiarativo; il mio istinto mi dice che questa è la strada da percorrere.
flusso

1
Nessuna intelligenza intellettuale sugli oggetti dai file json in VScode (fine 2017). Intellisense completamente funzionante per oggetti da module.exports.
Romain Vincent,

199

Molto più tardi, ho trovato un modulo Node.js abbastanza buono per la gestione della configurazione: nconf .

Un semplice esempio:

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'));

Supporta anche la memorizzazione delle impostazioni in Redis , la scrittura di file di configurazione e ha un'API abbastanza solida, ed è supportato anche da uno dei negozi Node.js più rispettati, Nodejitsu , come parte dell'iniziativa del framework Flatiron , quindi dovrebbe essere abbastanza a prova di futuro.

Scopri nconf a Github .


2
Forse una domanda stupida ma non ho visto una spiegazione chiara: dove posso impostare le variabili di ambiente del nodo? Sto già usando nconf ma non è chiaro dove imposterò le variabili ambientali. È in nginx / apache? È un altro file di configurazione?
Civile,

91
Non credo che usare il file .json come config sia una buona idea, dato che i commenti non sono ammessi.
Frank Xu,

11
Questo sembra fantastico. Penso che sorprenderai molti Unixheads se il file di configurazione sovrascrive le opzioni della riga di comando e le variabili di ambiente. Siamo abituati al seguente ordine di precedenza crescente: file di configurazione, variabili di ambiente, opzioni della riga di comando.
sheldonh,

2
@sheldonh Aspetta di scoprire che le opzioni booleane sono sempre impostate su argv, quindi infrangono la precedenza ...: /
Daniel C. Sobral

@ DanielC.Sobral È un vero peccato. Oh, e LTNS! :-)
sheldonh,

94

La mia soluzione è abbastanza semplice:

Carica la configurazione dell'ambiente in ./config/index.js

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

module.exports = cfg;

Definire alcune impostazioni predefinite in ./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';

Sostituire i valori predefiniti in ./config/config.test.js

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

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

module.exports = config;

Usandolo in ./models/user.js:

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

Esecuzione dell'app in ambiente di test:

NODE_ENV=test node ./app.js

2
Preferisco questo. Come menzionato da altri, JSON non è una struttura di archiviazione preferita e questa stratificazione con i globuli è semplice ed efficace
Sebastian J.

L'unico motivo per cui preferirei questo a nconf è perché consente il formato .js per i file di configurazione (sviluppo, test e prod). permettendoci di documentare ogni opzione di configurazione che altrimenti non sarebbe possibile con il formato JSON.
Kunal Kapadia,

A proposito, l' NODE_ENVimpostazione predefinita è "sviluppo". Dovresti invece verificare "produzione".
Kevin Suttle,

5
Non sto verificando lo sviluppo. Lo sto inadempiendo. Non sono sicuro del motivo per cui avrei mai perso la produzione.
amorevole

39

Potresti anche guardare dotenv che segue i principi di un'app a dodici fattori .

Ero solito usare node-config, ma ho creato dotenv per questo motivo. È stato completamente ispirato dalla libreria dotenv di Ruby.

L'utilizzo è abbastanza semplice:

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

Quindi basta creare un file .env e inserire le impostazioni in questo modo:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Questo è dotenv per nodejs.


2
O semplicemente usa foreman run node xx.jsquesto leggerà automaticamente anche nel tuo file .env.
Simon,

1
utilizzerei questo approccio anche per la produzione?
Lamour,

1
@lamar no, li hai impostati nelle variabili env sul server attuale. Questo è stato ogni volta che si distribuiscono sono lì, ma non nel codice sorgente.
Sidonaldson,

@Lamar sì, puoi effettivamente, come alternativa più portatile all'impostazione delle variabili env sul server. Il punto importante è di non includere il .envfile nel controllo della versione o nel processo di distribuzione.
Josh Noe,

31

State usando npm per iniziare i vostri script (env ecc.)?

Se usi i .envfile puoi includerli nel tuo package.json e usare npm per procurarli / avviarli.

Esempio:

{
  "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": "*"
  }
}

quindi esegui gli script npm:

$ npm start-dev

È descritto qui https://gist.github.com/ericelliott/4152984 Tutto il merito a Eric Elliot


2
Puoi spiegare cos'è la "fonte"? Ricevosource : not found
JohnnyBizzle il

@JohnnyBizzle source(o semplicemente .) è un comando integrato nelle shell Unix (Bash, ecc.) Per leggere ed eseguire comandi dal file dato, nella shell corrente . Cioè, i comandi non vengono eseguiti in una sotto-shell. L'effetto di questo in questo esempio è che le variabili d'ambiente definite in prod.envvengono aggiunte alla shell corrente e quindi passate a qualsiasi processo figlio generato da questa shell. Sembra che tu stia utilizzando Windows CMD. Vedi questa domanda per maggiori dettagli.
Utku,

Vale la pena notare: l'app a 12 fattori consiglia di non creare dev.enve prod.env, ma avere un singolo .envfile per distribuzione.
Iiridayn

24

Potresti anche guardare a node-config che carica il file di configurazione a seconda della variabile $ HOST e $ NODE_ENV (un po 'come RoR): documentazione .

Questo può essere abbastanza utile per diverse impostazioni di distribuzione ( development, testo production).


22

Basta fare un semplice settings.jscon exports:

exports.my_password = 'value'

Quindi, nella tua sceneggiatura, fai un require:

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

Tutte le tue impostazioni ora saranno disponibili tramite settingsvariabile:

settings.my_password // 'value'

@backdesk ovviamente potresti creare un sistema di archiviazione segreta che crittograferebbe i segreti e limiterebbe l'accesso usando ip, alcuni token, ecc. Ma alla fine tutto si tratta di leggere solo alcuni file dal disco, sia esso crittografato o non.
Vanuan,

@backdesk Non ci sono problemi con l'esempio. È proprio questo: un esempio per spiegare qualcosa di concreto.
Emilio Grisolía,

14

Ho intenzione di gettare il mio cappello sul ring qui perché nessuna di queste risposte si rivolge a tutti i componenti critici che praticamente ogni sistema ha bisogno. considerazioni:

  • Configurazione pubblica (che può essere vista dal frontend) vs configurazione privata (guy mograbi ha capito bene). E assicurandoti che siano tenuti separati.
  • Segreti come chiavi
  • Valori predefiniti vs sostituzioni specifiche dell'ambiente
  • Fasci di frontend

Ecco come faccio la mia configurazione:

  • config.default.private.js - Nel controllo versione, si tratta di opzioni di configurazione predefinite che possono essere visualizzate solo dal back-end.
  • config.default.public.js- Nel controllo versione, si tratta di opzioni di configurazione predefinite che possono essere visualizzate da backend e frontend
  • config.dev.private.js - Se hai bisogno di impostazioni predefinite private diverse per dev.
  • config.dev.public.js - Se hai bisogno di impostazioni predefinite pubbliche diverse per dev.
  • config.private.js - Non nel controllo versione, si tratta di opzioni specifiche dell'ambiente che hanno la precedenza config.default.private.js
  • config.public.js - Non nel controllo versione, si tratta di opzioni specifiche dell'ambiente che hanno la precedenza config.default.public.js
  • keys/- Una cartella in cui ogni file contiene un segreto diverso di qualche tipo. Anche questo non è sotto controllo di versione (le chiavi non dovrebbero mai essere sotto controllo di versione).

Uso i semplici file javascript per la configurazione, quindi ho la piena potenza del javascript langauge (compresi i commenti e la possibilità di fare cose come caricare il file di configurazione predefinito nel file specifico dell'ambiente in modo che possano essere sovrascritti). Se si desidera utilizzare le variabili di ambiente, è possibile caricarle all'interno di quei file di configurazione (anche se sconsiglio di utilizzare env vars per lo stesso motivo per cui non consiglio di utilizzare i file json - non hai il potere di un linguaggio di programmazione per costruire la tua configurazione).

Il motivo per cui ciascuna chiave si trova in un file separato è per l'uso dell'installer. Ciò consente di disporre di un programma di installazione che crea le chiavi sul computer e le memorizza nella cartella chiavi. Senza questo, il programma di installazione potrebbe non riuscire quando si carica il file di configurazione che non può accedere alle chiavi. In questo modo è possibile attraversare la directory e caricare tutti i file chiave che si trovano in quella cartella senza doversi preoccupare di ciò che esiste e di ciò che non esiste in una determinata versione del codice.

Dato che probabilmente hai le chiavi caricate nella tua configurazione privata, sicuramente non vuoi caricare la tua configurazione privata in nessun codice frontend. Sebbene sia probabilmente il più strettamente ideale per separare completamente la base di codice del tuo frontend dal tuo backend, molte volte PITA è una barriera abbastanza grande da impedire alle persone di farlo, quindi configurazione privata vs pubblica. Ma ci sono due cose che faccio per evitare che la configurazione privata venga caricata nel frontend:

  1. Ho un unit test che assicura che i miei bundle frontend non contengano una delle chiavi segrete che ho nella configurazione privata.
  2. Ho il mio codice frontend in una cartella diversa rispetto al mio codice backend e ho due diversi file denominati "config.js", uno per ciascuna estremità. Per il backend, config.js carica la configurazione privata, per il frontend carica la configurazione pubblica. Quindi hai sempre bisogno di ('config') e non preoccuparti da dove viene.

Un'ultima cosa: la tua configurazione dovrebbe essere caricata nel browser tramite un file completamente separato rispetto a qualsiasi altro tuo codice frontend. Se si raggruppa il codice frontend, la configurazione pubblica dovrebbe essere creata come un bundle completamente separato. Altrimenti, la tua configurazione non è più la configurazione, è solo una parte del tuo codice. Config deve essere in grado di essere diverso su macchine diverse.


13

Convict è un'altra opzione che aggiunge uno schema per la convalida. Come nconf, supporta il caricamento delle impostazioni da qualsiasi combinazione di variabili di ambiente, argomenti, file e oggetti json.

Esempio dal 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"
  }
});

Articolo per iniziare: Configurazioni di addomesticamento con node-convict


12

Puoi usare Konfig per file di configurazione specifici dell'ambiente. Carica automaticamente i file di configurazione json o yaml, ha valore predefinito e funzionalità di configurazione dinamica.

Un esempio dal repository di Konfig:

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

In via di sviluppo:

> config.app.port
3000

In produzione, supponiamo di iniziare l'applicazione con $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

Maggiori dettagli: https://github.com/vngrs/konfig


9

Creerò una cartella come configura un nome di file come config.jse successivamente userò questo file dove richiesto come di seguito

Esempio di config.js

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

Quindi se voglio usare questo file di configurazione da qualche parte

Prima importerò come di seguito

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

e posso accedere ai valori come di seguito

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

6

Basta usare il npmmodulo config(oltre 300000 download)

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

Node-config organizza configurazioni gerarchiche per le distribuzioni delle tue app.

Consente di definire un set di parametri predefiniti e di estenderli per diversi ambienti di distribuzione (sviluppo, qa, gestione temporanea, produzione, ecc.).

$ 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

4

È meglio separare le configurazioni di "sviluppo" e "produzione" .

Uso il seguente modo: Ecco il mio file config / index.js :

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 : ""
        }
    }
} 

Per richiedere la configurazione utilizzare quanto segue:

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

Quindi puoi usare il tuo oggetto di configurazione:

const ip_address = config.ip_address;
const port = config.port;

inoltre puoi utilizzare l'utente module.exports = config;alla fine del config/index.jsfile
mapmalith,

3

Sono un po 'in ritardo nel gioco, ma non sono riuscito a trovare quello di cui avevo bisogno qui o in qualsiasi altro luogo, quindi ho scritto qualcosa da solo.

I miei requisiti per un meccanismo di configurazione sono i seguenti:

  1. Supporto front-end. Qual è il punto se il front-end non può usare la configurazione?
  2. Supporto settings-overrides.js- che ha lo stesso aspetto ma consente l'override della configurazione in settings.js. L'idea qui è di modificare facilmente la configurazione senza cambiare il codice. Lo trovo utile per saas.

Anche se mi preoccupo meno degli ambienti di supporto, spiegherò come aggiungerlo facilmente alla mia soluzione

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;

Spiegazione

  • undefined significa che questa proprietà è obbligatoria
  • null significa che è facoltativo
  • meConf- attualmente il codice è indirizzato a un file in app. meConfsono i file di override a cui è destinato conf/dev- che sono ignorati dal mio vcs.
  • publicConfiguration - sarà visibile da front-end e back-end.
  • privateConfiguration - sarà visibile solo dal back-end.
  • sendPublicConfiguration- una route che esporrà la configurazione pubblica e la assegnerà a una variabile globale. Ad esempio il codice seguente esporrà la configurazione pubblica come variabile globale myConf nel front-end. Per impostazione predefinita utilizzerà il nome della variabile globale conf.

    app.get ("/ backend / conf", request ("conf"). sendPublicConfiguration);

Logica delle sostituzioni

  • privateConfiguration viene unito a publicConfiguration e quindi a meConf.
  • publicConfiguration controlla ogni chiave se ha una sostituzione e usa quella sostituzione. In questo modo non stiamo esponendo nulla di privato.

Aggiunta del supporto ambientale

Anche se non trovo utile un "supporto ambientale", forse qualcuno lo farà.

Per aggiungere il supporto ambientale è necessario modificare l'istruzione meConf request in qualcosa del genere (pseudocodice)

if (environment == "production") {meConf = richiedono ("../ conf / dev / meConf"). production; }

if (environment == "development") {meConf = require ("../ conf / dev / meConf"). development; }

Allo stesso modo puoi avere un file per ambiente

 meConf.development.js
 meConf.production.js

e importa quello giusto. Il resto della logica rimane lo stesso.


non terribilmente ovvio che in undefinedrealtà significa "richiesto" e nullsignifica "facoltativo". quindi il cestino giallo è per la plastica e il blu per la carta straccia? bene, ma ho dovuto leggere il manuale prima di gettare quella lettiera.
flusso

Non è necessario utilizzare questa convenzione. Lo trovo utile e chiedo al mio team di usarlo, ma puoi ovviamente rimuovere questa funzione.
guy mograbi,

3

un altro esempio che ho appena usato perché volevo maggiore flessibilità rispetto a un tipico file .json ma non volevo che fosse estratto in una libreria che richiederebbe una dipendenza è qualcosa di simile. Fondamentalmente, l'esportazione di una funzione richiamata immediatamente che ha restituito un oggetto con valori che volevo impostare. Offre molta flessibilità.

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

C'è una spiegazione molto migliore con l'esempio completo qui. Utilizzo dei file di configurazione in Node.js


3

So che questo è un post davvero vecchio. Ma voglio condividere il mio modulo per la configurazione delle variabili di ambiente, penso che sia una soluzione molto flessibile. Ecco il modulo json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '<%= baseUrl %>/users',
    'accounts': '<%= baseUrl %>/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 

Quindi è possibile utilizzare process.env.NODE_ENVper ottenere tutte le variabili per il proprio ambiente.


2

Oltre al modulo nconf menzionato in questa risposta , e node-config menzionato in questa risposta , ci sono anche node-iniparser e IniReader , che sembrano essere più semplici parser di file di configurazione .ini.


non c'è modo di tornare ai file win-ini ... questo iniparsersottolinea con orgoglio il fatto che sanno analizzare le sezioni nella configurazione ... nel 2013 ... se hai bisogno di un annidamento più profondo, dici [foo/bar]? [foo\bar]? bar.baz=42? bar/baz=42? bar\baz=42? bar:baz=42? come si dice 42è un numero? potrebbe essere un testo a tutte le cifre! - lancia XML, lancia YAML, lancia WIN.INI, abbraccia JSON, le preoccupazioni sono sparite.
flusso


1

È possibile usare pconf: https://www.npmjs.com/package/pconf

Esempio:

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

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

}

1

Ecco un approccio pulito ispirato a questo articolo . Non richiede alcun pacchetto aggiuntivo tranne l'onnipresente pacchetto lodash . Inoltre, consente di gestire le impostazioni predefinite nidificate con sovrascritture specifiche dell'ambiente.

Innanzitutto, crea una cartella di configurazione nel percorso principale del pacchetto che assomigli a questo

package
  |_config
      |_ index.js
      |_ defaults.json
      |_ development.json
      |_ test.json
      |_ production.json

ecco il file index.js

const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);

Ora supponiamo di avere un default.json in questo modo

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value3",
    "confKey4": "value4"
  }
}

e development.json in questo modo

{
  "confKey2": {
    "confKey3": "value10",
  }
}

se fai config = require('./config')qui è quello che otterrai

{
  "confKey1": "value1",
  "confKey2": {
    "confKey3": "value10",
    "confKey4": "value4"
  }
}

Si noti che si ottengono tutti i valori predefiniti ad eccezione di quelli definiti in file specifici dell'ambiente. Quindi puoi gestire una gerarchia di configurazione. L'uso defaultsDeepassicura che sia possibile avere anche impostazioni predefinite nidificate.



0

Ho provato alcune delle soluzioni suggerite qui, ma non ne sono rimasto soddisfatto, quindi ho creato il mio modulo. È chiamatomikro-config e la differenza principale è che onora la convenzione sulla configurazione, quindi puoi semplicemente richiedere il modulo e iniziare a usarlo.

Memorizzi la tua configurazione in semplici file js o json dalla /configcartella. Prima carica il default.jsfile, quindi tutti gli altri file dalla /configdirectory, quindi carica la configurazione specifica dell'ambiente basata su$NODE_ENV variabile.

Inoltre, consente di ignorare questa configurazione per lo sviluppo locale local.jso specifico per l'ambiente/config/env/$NODE_ENV.local.js .

Puoi dare un'occhiata qui:

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

https://github.com/B4nan/mikro-config


0

Per molto tempo ho usato l'approccio menzionato nella soluzione qui. Esiste tuttavia una preoccupazione per la sicurezza dei segreti in chiaro. Puoi usare un altro pacchetto sopraconfig modo che i bit di sicurezza siano curati.

Dai un'occhiata a: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/


Perché dovrei anche abbonarmi ad Azure per pagare per questo servizio? Perché non usare ansible-vault? Un'altra cosa: penso che nessuno pubblicherà un file di configurazione con credenziali di testo chiare nel repository di origine. Utilizzare le variabili di ambiente o inserire i dati segreti in un file con autorizzazione di sola lettura.
Yasser Sinjab,

Se riesci a leggerlo da una posizione di terze parti e decodificarlo e fare in modo che il tuo servizio utilizzi quei dati top secret, sarà possibile che un hacker faccia esattamente lo stesso se accede al tuo computer. È più lavoro (richiede più tempo) ma alla fine non ti protegge. Se il tuo server è penetrato, immagina che tutto ciò che hai su di esso sia ora pubblico.
Alexis Wilke,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.