¿Cómo almacenar la configuración de implementación de Node.js / los archivos de configuración?


640

He estado trabajando en algunas aplicaciones Node, y he estado buscando un buen patrón para almacenar configuraciones relacionadas con la implementación. En el mundo de Django (de donde vengo), la práctica común sería tener un settings.pyarchivo que contenga la configuración estándar (zona horaria, etc.) y luego una local_settings.pyconfiguración específica de implementación, es decir. con qué base de datos hablar, qué socket de memcache, dirección de correo electrónico para los administradores, etc.

He estado buscando patrones similares para Node. Solo un archivo de configuración sería bueno, por lo que no tiene que estar atascado con todo lo demás app.js, pero me parece importante tener una forma de tener una configuración específica del servidor en un archivo que no está en control de código fuente. La misma aplicación bien podría implementarse en diferentes servidores con configuraciones muy diferentes y tener que lidiar con conflictos de fusión y todo eso no es mi idea de diversión.

Entonces, ¿hay algún tipo de marco / herramienta para esto, o todos simplemente piratean algo juntos?


Me gusta mucho la forma en que la configuración se realiza en mean.js . Básicamente, la tienda de aplicaciones de configuración relevante en una especie seperat del módulo, en función de diferentes parámetros de cada entorno de aplicación (para la producción, desarrollo, pruebas) y que pasa a través de los detalles específicos de las variables de entorno de aplicaciones, como secretos etc.
Hinrich

Respuestas:


765

Utilizo a package.jsonpara mis paquetes y a config.jspara mi configuración, que se ve así:

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;

Cargo la configuración de mi proyecto:

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

y luego puedo acceder a mis cosas de config.db_host, config.db_port, etc ... Esto me permite ya sea hardcoded parámetros de uso, o parámetros almacenados en las variables ambientales si no desea almacenar las contraseñas en control de código fuente.

También genero package.jsonay inserto una sección de dependencias:

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

Cuando clono el proyecto en mi máquina local, corro npm installpara instalar los paquetes. Más información sobre eso aquí .

El proyecto se almacena en GitHub, con controles remotos agregados para mi servidor de producción.


32
¿Qué sucede cuando tienes diferentes configuraciones de configuración para dev vs. prod?
chovy

44
No lo he hecho, pero aquí hay una forma de hacerlo ... para cada env, establezca el nombre del env en una variable ENV. Luego, en este archivo, es solo javascript ... use un caso o una declaración if para cargar selectivamente las variables apropiadas. Incluso podría hacer un subfile de configuración separado para cada env, y en la instrucción if, vuelva a cargar el subfile aquí en un subconfig var, y exporte ese subconfig var a la configuración principal. Todo lo que estoy tratando de decir es que es solo js, para que puedas ser creativo
noli

44
que proceso.env? donde se ubica ¿Y cómo configurarlo?
Kiwi enojado

12
Estaba pensando "wow ... he estado mirando node.js durante unas horas y mi aplicación ya está funcionando ... por cierto, tal vez comparta este código aleatorio que se me ocurrió"
noli

3
¿Todavía no puedes usar variables de entorno para almacenar esas palabras de paso? ¿No es para eso para lo que sirve esta línea: config.twitter.password = process.env.TWITTER_PASSWORD || 'contraseña';
DMart

244

Puede requerir archivos JSON a partir del Nodo v0.5.x (haciendo referencia a esta respuesta )

config.json:

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

app.js:

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

40
No estoy tan impresionado con esa característica. Puede requerir ("./ config.js") y puede agregar comentarios a los archivos de configuración que considero muy importantes, y otros detalles. Si su configuración es solo propiedades y no hay código, no pierde nada mediante require (config.js) con su JSON con el prefijo
export.config

3
@teknopaul tienes razón, pero solía haber una gran discusión sobre la 'corrección' / usabilidad del uso de sistemas de plantillas tontos frente a inteligentes que me decían: (1) normalmente quieres un lenguaje declarativo / tonto para plantillas / opciones (2) es una mala idea reconstruir un "casi-PL" para hacer plantillas (o configuraciones), mejor para reutilizar su PL real existente con comportamientos conocidos. hasta ahora +1 para reciclar JS para hacer configuraciones de usuario; -1 por no seguir el enfoque declarativo. hemos visto algunas cosas de configuración bastante complejas hechas de forma declarativa; mi instinto me dice que este es el camino a seguir.
fluye el

1
Sin intellisense en objetos de archivos json en VScode (finales de 2017). Intellisense totalmente funcional para objetos de module.exports.
Romain Vincent

199

Mucho después, encontré un módulo Node.js bastante bueno para administrar la configuración: nconf .

Un simple ejemplo:

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

También es compatible con el almacenamiento de configuraciones en Redis , escribir archivos de configuración, y tiene una API bastante sólida, y también está respaldado por una de las tiendas Node.js más respetadas, Nodejitsu , como parte de la iniciativa del marco Flatiron , por lo que debería ser bastante a prueba de futuro.

Echa un vistazo a nconf en Github .


2
Tal vez una pregunta tonta, pero no he visto una explicación clara: ¿Dónde configuro las variables de entorno del nodo? Ya estoy usando nconf pero no está claro dónde establecería las variables ambientales. ¿Está en nginx / apache? ¿Es otro archivo de configuración?
Civil

9191
No creo que usar el archivo .json como config sea una buena idea, ya que no se permiten comentarios.
Frank Xu

11
Esto se ve genial. Creo que sorprenderá a muchos Unixheads si el archivo de configuración anula las opciones de línea de comandos y las variables de entorno. Estamos acostumbrados al siguiente orden de precedencia ascendente: archivo (s) de configuración, variables de entorno, opciones de línea de comandos.
sheldonh

2
@sheldonh Espere hasta que descubra que las opciones booleanas siempre están configuradas en argv, por lo tanto, rompiendo la precedencia ...: /
Daniel C. Sobral

@ DanielC.Sobral Es una verdadera pena. Ah, y LTNS! :-)
sheldonh

94

Mi solución es bastante simple:

Cargue la configuración del entorno en ./config/index.js

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

module.exports = cfg;

Defina algunos valores predeterminados en ./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';

Anule los valores predeterminados en ./config/config.test.js

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

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

module.exports = config;

Utilizándolo en ./models/user.js:

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

Ejecutando su aplicación en entorno de prueba:

NODE_ENV=test node ./app.js

2
Prefiero éste. Como mencionan otros, JSON no es una estructura de almacenamiento preferida y esta estratificación con globales es simple y efectiva
Sebastian J.

La única razón por la que preferiría esto sobre nconf es porque permite el formato .js para los archivos de configuración (dev, test y prod). permitiéndonos documentar cada opción de configuración que de otra forma no sería posible con el formato JSON.
Kunal Kapadia

Por cierto, el valor NODE_ENVpredeterminado es "desarrollo". En su lugar, debe verificar la 'producción'.
Kevin Suttle

55
No estoy buscando desarrollo. Estoy incumpliendo con eso. No estoy seguro de por qué alguna vez pasaría a producción.
chovy

39

También puede buscar dotenv que sigue los principios de una aplicación de doce factores .

Solía ​​usar node-config, pero creé dotenv por esa razón. Fue completamente inspirado por la biblioteca dotenv de ruby.

El uso es bastante fácil:

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

Luego solo crea un archivo .env y coloca su configuración allí de la siguiente manera:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Eso es dotenv para nodejs.


2
O simplemente use foreman run node xx.jsesto también se leerá automáticamente en su archivo .env.
Simon

1
¿Usaría este enfoque para la producción también?
Lamour

1
@lamar no, los configuró en las variables env en el servidor real. Eso fue cada vez que implementa, están allí, pero no en el código fuente.
sidonaldson

@Lamar, sí puedes, como una alternativa más portátil para configurar las variables env en el servidor. El punto importante es no incluir el .envarchivo en el control de versiones o el proceso de implementación.
Josh Noe

31

¿Están usando npm para iniciar sus scripts (env, etc.)?

Si usa .envarchivos, puede incluirlos en su package.json y usar npm para obtenerlos / iniciarlos.

Ejemplo:

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

luego ejecute los scripts npm:

$ npm start-dev

Se describe aquí https://gist.github.com/ericelliott/4152984 Todo el crédito a Eric Elliot


2
¿Puedes explicar qué es "fuente"? Obtengosource : not found
JohnnyBizzle

@JohnnyBizzle source(o simplemente .) es un comando incorporado en shells de Unix (Bash, etc.) para leer y ejecutar comandos del archivo dado, en el shell actual . Es decir, los comandos no se ejecutan en un sub-shell. El efecto de eso en este ejemplo es que las variables de entorno definidas en prod.envse agregan al shell actual y, por lo tanto, se pasan a cualquier proceso secundario generado por este shell. Parece que estás usando Windows CMD. Vea esta pregunta para más detalles.
Utku

Vale la pena señalar: la aplicación de 12 factores recomienda no crear dev.envy prod.envtener un solo .envarchivo por implementación.
Iiridayn

24

También puede buscar la configuración de nodo que carga el archivo de configuración dependiendo de la variable $ HOST y $ NODE_ENV (un poco como RoR): documentación .

Esto puede ser muy útil para diferentes valores de despliegue ( development, testo production).


22

Solo haz un simple settings.jscon exports:

exports.my_password = 'value'

Luego, en tu guión, haz un require:

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

Todos sus ajustes ahora estarán disponibles a través de la settingsvariable:

settings.my_password // 'value'

@backdesk, por supuesto, podría configurar un sistema de almacenamiento secreto que cifraría secretos y limitaría el acceso mediante ip, algunos tokens, etc. Pero al final del día, todo se trata de leer algunos archivos del disco, ya sea cifrado o no.
Vanuan

@backdesk No hay problema con el ejemplo. Es solo eso: un ejemplo para explicar algo concreto.
Emilio Grisolía

14

Voy a lanzar mi sombrero al ring aquí porque ninguna de estas respuestas aborda todos los componentes críticos que prácticamente cualquier sistema necesita. Consideraciones:

  • Configuración pública (que se puede ver en la interfaz de usuario) frente a configuración privada (Guy Mograbi lo hizo bien). Y asegurando que estos se mantengan separados.
  • Secretos como llaves
  • Valores predeterminados frente a anulaciones específicas del entorno
  • Paquetes frontend

Así es como hago mi configuración:

  • config.default.private.js - En el control de versiones, estas son opciones de configuración predeterminadas que solo puede ver su backend.
  • config.default.public.js- En el control de versiones, estas son opciones de configuración predeterminadas que pueden verse en el backend y la interfaz
  • config.dev.private.js - Si necesita diferentes valores predeterminados privados para dev.
  • config.dev.public.js - Si necesita diferentes valores predeterminados públicos para dev.
  • config.private.js - No en el control de versiones, estas son opciones específicas del entorno que anulan config.default.private.js
  • config.public.js - No en el control de versiones, estas son opciones específicas del entorno que anulan config.default.public.js
  • keys/- Una carpeta donde cada archivo almacena un secreto diferente de algún tipo. Esto tampoco está bajo control de versión (las claves nunca deben estar bajo control de versión).

Utilizo archivos javascript antiguos para la configuración, así que tengo todo el poder del lenguaje javascript (incluidos los comentarios y la capacidad de hacer cosas como cargar el archivo de configuración predeterminado en el archivo específico del entorno para que luego se puedan anular). Si desea utilizar variables de entorno, puede cargarlas dentro de esos archivos de configuración (aunque recomiendo no usar env vars por la misma razón que no recomiendo usar archivos json: no tiene el poder de un lenguaje de programación para construir su configuración).

La razón por la que cada clave está en un archivo separado es para uso del instalador. Esto le permite tener un instalador que crea claves en la máquina y las almacena en la carpeta de claves. Sin esto, su instalador podría fallar cuando carga su archivo de configuración que no puede acceder a sus claves. De esta manera, puede recorrer el directorio y cargar cualquier archivo de clave que se encuentre en esa carpeta sin tener que preocuparse por lo que existe y lo que no existe en ninguna versión de su código.

Como probablemente tenga claves cargadas en su configuración privada, definitivamente no desea cargar su configuración privada en ningún código de interfaz. Si bien es probable que sea estrictamente más ideal separar completamente la base de código de su interfaz de su back-end, muchas veces PITA es una barrera lo suficientemente grande como para evitar que las personas lo hagan, por lo tanto, configuración privada vs pública. Pero hay dos cosas que hago para evitar que la configuración privada se cargue en la interfaz:

  1. Tengo una prueba unitaria que garantiza que mis paquetes frontend no contengan una de las claves secretas que tengo en la configuración privada.
  2. Tengo mi código de front-end en una carpeta diferente que mi código de back-end, y tengo dos archivos diferentes llamados "config.js", uno para cada extremo. Para el backend, config.js carga la configuración privada, para el frontend, carga la configuración pública. Entonces siempre solo necesita ('config') y no se preocupe por su origen.

Una última cosa: su configuración debe cargarse en el navegador a través de un archivo completamente separado que cualquiera de sus otros códigos frontend. Si agrupa su código de interfaz, la configuración pública debe construirse como un paquete completamente separado. De lo contrario, su configuración ya no es realmente configuración, es solo parte de su código. Config necesita poder ser diferente en diferentes máquinas.


13

Condenar es otra opción que agrega un esquema para la validación. Al igual que nconf, admite la configuración de carga de cualquier combinación de variables de entorno, argumentos, archivos y objetos json.

Ejemplo de 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"
  }
});

Artículo de inicio: Configuraciones de domesticación con nodo-convicto


12

Puede usar Konfig para archivos de configuración específicos del entorno. Carga archivos de configuración json o yaml automáticamente, tiene un valor predeterminado y características de configuración dinámica.

Un ejemplo del repositorio de 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"
    }
}

En desarrollo:

> config.app.port
3000

En producción, supongamos que comenzamos la aplicación con $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

Más detalles: https://github.com/vngrs/konfig


9

Crearé una carpeta como config un nombre de archivo como config.jsy luego usaré este archivo siempre que sea necesario como se muestra a continuación

Ejemplo de config.js

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

Entonces, si quiero usar este archivo de configuración en alguna parte

Primero importaré como a continuación

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

y puedo acceder a los valores de la siguiente manera

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

Solo use el npmmódulo config(más de 300000 descargas)

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

Node-config organiza configuraciones jerárquicas para las implementaciones de su aplicación.

Le permite definir un conjunto de parámetros predeterminados y extenderlos para diferentes entornos de implementación (desarrollo, qa, puesta en escena, producción, 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

4

Es mejor separar las configuraciones de 'desarrollo' y 'producción' .

Utilizo la siguiente manera: Aquí está mi archivo 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 : ""
        }
    }
} 

Para requerir la configuración use lo siguiente:

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

Entonces puedes usar tu objeto de configuración:

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

También puede usuario module.exports = config;al final del config/index.jsarchivo
mapmalith

3

Llegué un poco tarde en el juego, pero no pude encontrar lo que necesitaba aquí, ni en ningún otro lado, así que escribí algo yo mismo.

Mis requisitos para un mecanismo de configuración son los siguientes:

  1. Soporte front-end. ¿Cuál es el punto si el front-end no puede usar la configuración?
  2. Soporte settings-overrides.js: que se ve igual pero permite anular la configuración en settings.js. La idea aquí es modificar la configuración fácilmente sin cambiar el código. Lo encuentro útil para saas.

Aunque me preocupo menos por los entornos de soporte, explicaré cómo agregarlo fácilmente a mi solución

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;

Explicación

  • undefined significa que esta propiedad es requerida
  • null significa que es opcional
  • meConf- actualmente el código está dirigido a un archivo debajo app. meConfson los archivos de anulación a los que está dirigido conf/dev, lo cual es ignorado por mis vcs.
  • publicConfiguration - será visible desde el front-end y el back-end.
  • privateConfiguration - será visible solo desde el back-end.
  • sendPublicConfiguration- una ruta que expondrá la configuración pública y la asignará a una variable global. Por ejemplo, el siguiente código expondrá la configuración pública como variable global myConf en el front-end. Por defecto usará el nombre de la variable global conf.

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

Lógica de anulaciones

  • privateConfiguration se fusiona con publicConfiguration y luego meConf.
  • publicConfiguration comprueba cada clave si tiene una anulación y la usa. De esta manera no estamos exponiendo nada privado.

Agregar compatibilidad con el entorno

Aunque no encuentro útil un "soporte ambiental", tal vez alguien lo haga.

Para agregar compatibilidad con el entorno, debe cambiar la declaración de requerimiento meConf a algo como esto (pseudocódigo)

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

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

Del mismo modo, puede tener un archivo por entorno

 meConf.development.js
 meConf.production.js

e importar el correcto. El resto de la lógica permanece igual.


no es terriblemente obvio que undefinedrealmente significa 'requerido' y nullsignifica 'opcional'. ¿Entonces el contenedor amarillo es para plásticos y el azul para papel de desecho? bien, pero tuve que leer el manual antes de tirar la basura.
fluye el

No tienes que usar esta convención. Lo encuentro útil y le indico a mi equipo que lo use, pero obviamente puede eliminar esta función.
Guy Mograbi

3

un ejemplo alternativo que acabo de usar porque quería más flexibilidad que un archivo .json típico pero no quería que se abstrajera en una biblioteca que requeriría una dependencia es algo como esto. Básicamente, exportando una función invocada inmediatamente que devolvió un objeto con los valores que quería establecer. Da mucha flexibilidad.

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

Hay una explicación mucho mejor con un ejemplo completo aquí. Uso de archivos de configuración en Node.js


3

Sé que esta es una publicación muy antigua. Pero quiero compartir mi módulo para configurar variables de entorno, creo que es una solución muy flexible. Aquí está el módulo 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 

Luego puede usar process.env.NODE_ENVpara obtener todas las variables para su entorno.


2

Además del módulo nconf mencionado en esta respuesta , y node-config mencionado en esta respuesta , también hay node-iniparser e IniReader , que parecen ser analizadores de archivos de configuración .ini más simples.


no hay forma de volver a los archivos win-ini ... eso iniparserresalta con orgullo el hecho de que saben cómo analizar secciones en la configuración ... en 2013 ... si necesita un anidamiento más profundo, ¿dices [foo/bar]? [foo\bar]? bar.baz=42? bar/baz=42? bar\baz=42? bar:baz=42? ¿Cómo sabes que 42es un número? ¡podría ser un texto de todos los dígitos! —por ejemplo, XML, tirar YAML, tirar WIN.INI, abrazar a JSON, las preocupaciones se han ido.
fluye el



1

Aquí hay un enfoque ordenado inspirado en este artículo . No requiere ningún paquete adicional, excepto el omnipresente paquete lodash . Además, le permite administrar los valores predeterminados anidados con sobrescrituras específicas del entorno.

Primero, cree una carpeta de configuración en la ruta raíz del paquete que tenga este aspecto

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

aquí está el archivo index.js

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

Ahora supongamos que tenemos valores predeterminados.

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

y desarrollo.json así

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

si haces config = require('./config')aquí es lo que obtendrás

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

Observe que obtiene todos los valores predeterminados, excepto los definidos en archivos específicos del entorno. Para que pueda administrar una jerarquía de configuración. El uso defaultsDeepasegura que incluso puede tener valores predeterminados anidados.



0

Probé algunas de las soluciones sugeridas aquí, pero no estaba satisfecho con ellas, así que creé mi propio módulo. Se llamamikro-config y la principal diferencia es que respeta la convención sobre la configuración, por lo que solo puede requerir el módulo y comenzar a usarlo.

Usted almacena su configuración en archivos js simples o json de la /configcarpeta. Primero carga el default.jsarchivo, luego todos los demás archivos del /configdirectorio, luego carga la configuración específica del entorno basada en la $NODE_ENVvariable.

También permite anular esta configuración para el desarrollo local con un local.jsentorno específico /config/env/$NODE_ENV.local.js.

Puedes echarle un vistazo aquí:

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

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


0

Durante mucho tiempo, solía usar el enfoque mencionado en la solución aquí. Sin embargo, existe una preocupación sobre la seguridad de los secretos en texto claro. Puedes usar otro paquete encima deconfig para que se cuiden los bits de seguridad.

Mira esto: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/


¿Por qué debería incluso suscribirme a Azure para pagar este servicio? ¿Por qué no usar ansible-vault? Otra cosa: creo que nadie publicará un archivo de configuración con credenciales de texto claro en el repositorio de origen. Utilice variables de entorno o ponga sus datos secretos en un archivo con permiso de solo lectura.
Yasser Sinjab

Si puede leerlo desde una ubicación de terceros y decodificarlo y hacer que su servicio use esos datos de alto secreto, será posible que un pirata informático haga exactamente lo mismo si obtiene acceso a su computadora. Es más trabajo (lleva más tiempo) pero al final no te protege. Si su servidor es penetrado, imagine que todo lo que tiene ahora es público.
Alexis Wilke
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.