Como conservar Nodo.configuração/ficheiros de configuração da implantação do js?

tenho trabalhado em alguns aplicativos de nós, e tenho procurado um bom padrão de armazenamento de configurações relacionadas com a implantação. No mundo Django( de onde eu venho), a prática comum seria ter um arquivo settings.py contendo as configurações padrão (timezone, etc), e então um local_settings.py para configurações específicas de implantação, ou seja. com que Base de dados falar, que socket memcache, endereço de E-mail para os administradores e assim por diante.

Tenho andado à procura de padrões semelhantes para o nó. Apenas uma configuração arquivo seria bom, então ele não tem que ser encravado com tudo o resto em {[[2]}, mas eu acho que é importante ter uma maneira de ter a configuração específica do servidor em um arquivo que não está no controle de código. O mesmo aplicativo poderia muito bem ser implantado em diferentes servidores com configurações muito diferentes, e ter que lidar com conflitos de fusão e tudo o que não é minha idéia de diversão.

Então, há algum tipo de framework/tool para isto, ou todos hackeiam algo juntos?

Author: mikl, 2011-05-03

23 answers

Uso um package.json para os meus pacotes e um config.js para a minha configuração, que se parece com:

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;

Carrego a configuração do meu projecto:

var config = require('./config');
E depois posso aceder às minhas coisas de config.db_host, config.db_port, etc... Isto permite-me usar parâmetros hardcoded, ou parâmetros armazenados em variáveis ambientais se eu não quiser armazenar senhas no controle de fonte.

Eu também gerar um package.json e inserir uma secção de dependências:

"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 clonei o projecto para a minha máquina local, Eu corro npm install para instalar os pacotes. Mais informações sobre isso aqui.

O projecto é armazenado no GitHub, com comandos adicionados para o meu servidor de produção.

 707
Author: noli, 2017-06-17 12:05:41

Pode necessitar de ficheiros JSON a partir do nó v0.5.x (referenciando esta resposta)

Config.json:
{
    "username" : "root",
    "password" : "foot"
}

App.js:

var config = require('./config.json');
log_in(config.username, config.password);
 221
Author: TinyTimZamboni, 2017-05-23 12:26:36
Muito mais tarde, encontrei um nó muito bom.módulo js para gerir a configuração: nconf .

Um exemplo simples:

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

Ele também suporta o armazenamento de Configurações em Redis , escrevendo arquivos de configuração, e tem uma API bastante sólida, e também é suportado por um dos nós mais respeitados.js shops, Nodejitsu , como parte da iniciativa-quadro Flatiron , por isso deve ser razoavelmente à prova do futuro.

Check out nconf at Github .

 188
Author: mikl, 2012-01-25 08:48:35
A minha solução é bastante simples.

Carregar a configuração do ambiente ./config / index.js

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

module.exports = cfg;

Define alguns valores por omissão ./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';

Sobrepõe os valores por omissão./config / config.teste.js

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

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

module.exports = config;

Usando-o dentro ./ models / user.js:

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

A correr a aplicação no ambiente de ensaio:

NODE_ENV=test node ./app.js
Isto é explicado em maior detalhe aqui.: http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/
 84
Author: chovy, 2012-11-26 23:20:00

Você também pode olhar para dotenv, que segue os princípios de um doze fator app.

Eu costumava usar o nó-config, mas criei o dotenv por essa razão. Foi completamente inspirado pela biblioteca de Ruby dootenv.

A utilização é bastante fácil:

var dotenv = require('dotenv');
dotenv.load();
Então, basta criar um .env file e coloque as suas configurações aí, Assim:
S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Isso é dotenv para os nodejs.

 30
Author: scottmotte, 2014-04-30 00:59:53

Estão a usar o npm para iniciar os vossos programas (env, etc) ?

Se usar os ficheiros .env pode incluí-los no seu package.json e use o npm para o código / iniciá-los.

Exemplo:

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

Execute então os programas do npm:

$ npm start-dev

Está descrito aqui https://gist.github.com/ericelliott/4152984 Todo o crédito ao Eric Elliot

 29
Author: lxx, 2016-01-27 16:28:52

Você também pode olhar para nó-config que carrega o arquivo de configuração, dependendo $HOST e $NODE_ENV variável (um pouco como o RoR) : documentação.

Isto pode ser bastante útil para diferentes configurações de implantação (development, test ou production).

 23
Author: ngryman, 2012-04-23 17:54:05

Basta fazer um simples settings.js com exports:

exports.my_password = 'value'

Então, no seu guião, faça um require:

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

Todas as suas configurações agora serão disponíveis via settings variável:

settings.my_password // 'value'
 20
Author: Vanuan, 2013-01-27 16:47:57

O Convict é outra opção que adiciona um esquema de validação. Como nconf, ele suporta configurações de carregamento de qualquer combinação de variáveis de ambiente, argumentos, arquivos e objetos json.

Exemplo do 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"
  }
});
[[2]}começar o artigo: configurações de Domamento com nó-condenado
 11
Author: hurrymaplelad, 2013-08-05 19:00:19

Pode usar O Konfig para ficheiros de configuração específicos do ambiente. Ele carrega arquivos de configuração JSON ou yaml automaticamente, ele tem o valor padrão e características de configuração dinâmica.

Um exemplo do Acordo de recompra do 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"
    }
}

Em desenvolvimento:

> config.app.port
3000

Em produção, suponha que começamos a aplicação com $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

Mais detalhes : https://github.com/vngrs/konfig

 11
Author: Ali Davut, 2014-02-03 12:20:32
Vou atirar o meu chapéu para o ringue porque nenhuma destas respostas aborda todos os componentes críticos que qualquer sistema precisa. Considerações:
  • configuração pública (que pode ser vista pela interface) vs configuração privada (guy mograbi acertou neste). E assegurar que estes sejam mantidos separados.
  • Segredos como chaves
  • predefinições vs substituições específicas do ambiente
  • pacotes Frontend
É assim que eu faço a minha configuração:
  • config.default.private.js - no controlo de versões, estas são opções de configuração predefinidas que só podem ser vistas pela sua infra-estrutura.
  • config.default.public.js - no controlo de versões, estas são as opções de configuração predefinidas que podem ser vistas pela infra-estrutura e frontend
  • config.dev.private.js - Se precisar de diferentes padrões privados para o dev.
  • Se precisar de diferentes padrões públicos para o dev.
  • config.private.js - não no controlo de versões, estas são específicas do ambiente opções que sobrepõem config.default.private.js
  • config.public.js - não no controlo de versões, estas são opções específicas do ambiente que sobrepõem config.default.public.js
  • Uma pasta onde cada ficheiro guarda um segredo diferente de algum tipo. Isto também não está sob controle de versão (chaves nunca devem estar sob controle de versão).

Uso ficheiros javascript simples para configuração, por isso tenho todo o poder do langauge javascript (incluindo comentários e a capacidade de fazer coisas como carregar o valor por omissão ficheiro de configuração no ficheiro específico do ambiente para que possam ser sobrepostos). Se você quiser usar variáveis de ambiente, você pode carregá - las dentro desses arquivos de configuração (tho eu recomendo contra o uso de vars env pela mesma razão que eu não recomendo o uso de arquivos json-você não tem o poder de uma linguagem de programação para construir sua configuração).

A razão pela qual cada chave está num ficheiro separado é para ser usada pelo instalador. Isto permite-lhe ter um instalador que cria as chaves na máquina e guarda-as na pasta das chaves. Sem isto, o seu instalador poderá falhar quando carregar o seu ficheiro de configuração que não consegue aceder às suas chaves. Desta forma você pode atravessar o diretório e carregar qualquer arquivo chave que estão nessa pasta sem ter que se preocupar com o que existe e o que não existe em qualquer versão dada do seu código.

Dado que provavelmente tem as chaves carregadas na sua configuração privada, você definitivamente não quer carregar a sua configuração privada em nenhum código de interface. Embora provavelmente estritamente mais ideal para separar completamente a sua base de código da sua infra-estrutura, muitas vezes que a PITA é uma barreira grande o suficiente para impedir que as pessoas façam isso, assim privado vs configuração pública. Mas há duas coisas que eu faço para evitar que config privado seja carregado na frente:

    Tenho um teste de unidade que garante que os meus pacotes frontend não contêm uma das chaves secretas que tenho na configuração privada. Tenho o meu código de interface numa pasta diferente da minha infra-estrutura. código, e tenho dois ficheiros diferentes chamados "config".js " - um para cada extremidade. Para infra-estrutura, config.o js carrega a configuração privada, para frontend, carrega a configuração pública. Então você sempre só precisa('config') e não se preocupe sobre de onde ele vem.

Uma última coisa:a sua configuração deve ser carregada no navegador através de um completamente separado de qualquer um dos seus outros códigos de interface. Se você agrupar o seu código de interface, a configuração pública deve ser construída como um um pacote completamente separado. Caso contrário, a sua configuração já não é realmente config - é apenas parte do seu código. Config precisa ser capaz de ser diferente em máquinas diferentes.

 11
Author: B T, 2017-03-02 01:59:04

Criarei uma pasta como configuração de um ficheiro com o nome config.js e, mais tarde, utilizarei este ficheiro onde for necessário, conforme abaixo

Exemplo de configuração.js

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

Então se eu quiser usar este ficheiro de configuração algures

Primeiro importarei como abaixo

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

E posso aceder aos valores abaixo

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
Author: Ron, 2018-01-25 04:12:46
Estou um pouco atrasado no jogo, mas não consegui encontrar o que precisava aqui - ou em qualquer outro lugar - por isso escrevi uma coisa.

Os meus requisitos para um mecanismo de configuração são os seguintes:

    Suporte frontal. Qual é o ponto se o front-end não pode usar a configuração?
  1. Suporte settings-overrides.js - que parece o mesmo, mas permite sobreposições de configuração em settings.js. A idéia aqui é modificar a configuração facilmente sem alterar o código. Eu encontro-o. útil para saas.
Apesar de me importar menos com os ambientes de suporte, o will explica como adicioná-los facilmente à minha solução.
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ção

  • undefined significa que esta propriedade é necessária
  • null significa que é opcional
  • meConf - actualmente, o código é alvo de um ficheiro em app. meConf são os ficheiros de substituições que são direccionados para {[[9]} - que são ignorados pelos meus vcs.
  • publicConfiguration - será visível da frente e traseira.
  • - Só será visível de trás para a frente.
  • sendPublicConfiguration - uma rota que irá expor a configuração pública e atribuí-la a uma variável global. Por exemplo, o código abaixo irá expor a configuração pública como variável global myConf no front-end. Por omissão, irá usar o nome da variável global conf.

    App.get ("/backend/conf", require ("conf").sendPublicConfiguration);

Lógica de sobrepõe

  • a configuração privada funde-se com a configuração pública e depois meConf.
  • a configuração pública verifica cada tecla se tem uma anulação, e usa essa anulação. Assim não vamos expor nada privado.

Adicionar suporte ao ambiente

Apesar de não achar útil um "suporte ambiental", talvez alguém o faça.

Para adicionar suporte de ambiente você precisa mudar o meConf precisa de declaração para algo como isto (pseudocode)

If ( Ambiente = "Produção") { meConf = require("../ conf / dev / meConf").producao; }

If (ambiente = "desenvolvimento" ) { meConf = require("../ conf / dev / meConf").desenvolvimento; }

Da mesma forma, você pode ter um arquivo por Ambiente

 meConf.development.js
 meConf.production.js
E importar o direito. O resto da lógica permanece a mesma.
 3
Author: guy mograbi, 2013-10-01 09:20:21
Um exemplo alternativo que usei porque queria mais flexibilidade do que um típico .JSON file but didn't want it abstract away into a library which would require a dependency is something like this. Basicamente, exportar uma função invocada imediatamente que devolveu um objeto com valores que eu queria definir. Dá muita flexibilidade.
     module.exports = function(){
       switch(node_env){
         case 'dev':
           return
           { var1 = 'development'};
         }
    }();
Há uma explicação muito melhor com um exemplo completo. a usar ficheiros de configuração no nó.js
 3
Author: captainavi, 2014-10-20 05:22:29
Eu sei que este é um post muito antigo. Mas eu quero compartilhar meu módulo para configurar variáveis de ambiente, Eu acho que é uma solução muito flexível. Aqui está o Módulo configurador json
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 

Então você pode usar process.env.NODE_ENV para obter todas as variáveis para o seu ambiente.

 3
Author: Christian, 2016-01-27 16:30:29

Além do nconf módulo mencionado no esta resposta, e nó-config mencionado no esta resposta, existem também nó-iniparser e IniReader, que parecem ser mais simples .analisadores de ficheiros de configuração ini.

 1
Author: Wingman4l7, 2017-05-23 10:31:37

Acabei de lançar um pequeno módulo para carregar qualquer tipo de ficheiros de configuração. É muito em frente, podes verificar em https://github.com/flesler/config-node

 1
Author: Ariel Flesler, 2014-03-26 19:32:41

Pode utilizar pconf: https://www.npmjs.com/package/pconf

Exemplo:

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

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

}
 1
Author: Per Henrik Jakobsson, 2017-03-29 14:51:36

É melhor separar as configurações 'desenvolvimento' e 'Produção'.

Eu uso da seguinte forma: Aqui está a minha configuração / índice .Js ficheiro:

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

Para requerer a configuração, utilize o seguinte:

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

Do que pode usar o seu objecto de configuração:

const ip_address = config.ip_address;
const port = config.port;
 1
Author: Aram Manukyan, 2018-08-18 10:24:45
Para aqueles que estão visitando este velho tópico aqui é um pacote que eu acho bom.

Https://www.npmjs.org/package/config

 0
Author: Venkat Kotra, 2014-10-14 13:01:52
Eu testei algumas das soluções sugeridas aqui, mas não estava sattizado com elas, então eu criei meu próprio módulo. Ele é chamado {[[0]} e a principal diferença é que ele honra a Convenção sobre a configuração, então você pode apenas exigir o módulo e começar a usá-lo.

Você guarda a sua configuração em ficheiros js simples ou json da pasta /config. Primeiro carrega o ficheiro default.js, Depois todos os outros ficheiros da pasta /config, depois carrega a configuração específica do ambiente com base em $NODE_ENV variavel.

Também permite sobrepor esta configuração para o desenvolvimento local com {[5] } ou com o ambiente específico /config/env/$NODE_ENV.local.js.

Pode dar uma vista de olhos aqui.

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

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

 0
Author: Martin Adámek, 2017-04-17 10:19:02
Durante muito tempo, usei a abordagem mencionada na solução. No entanto, há uma preocupação com a segurança dos segredos em texto claro. Você pode usar outro pacote em cima de config para que os bits de segurança sejam tratados. Olha para isto.https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/
 0
Author: Rahul Soni, 2017-06-13 10:43:18

Basta utilizar npm Módulo config (mais de 300000 downloads)

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

O nó-Configuração organiza configurações hierárquicas para as suas aplicações.

Permite-lhe definir um conjunto de parâmetros predefinidos e alargá-los para diferentes ambientes de implantação (desenvolvimento, qa, encenação, produção, 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
 0
Author: аlex dykyі, 2018-08-30 09:27:11