Comment stocker les paramètres de déploiement / fichiers de configuration de Node.js?

640

J'ai travaillé sur quelques applications Node et je cherchais un bon modèle de stockage des paramètres liés au déploiement. Dans le monde Django (d'où je viens), la pratique courante serait d'avoir un settings.pyfichier contenant les paramètres standard (fuseau horaire, etc.), puis un local_settings.pypour les paramètres spécifiques au déploiement, c'est-à-dire. à quelle base de données parler, à quel socket memcache, adresse e-mail pour les administrateurs, etc.

Je cherchais des modèles similaires pour Node. Juste un fichier de configuration serait bien, donc il n'a pas besoin d'être brouillé avec tout le reste app.js, mais je trouve important d'avoir un moyen d'avoir une configuration spécifique au serveur dans un fichier qui n'est pas en contrôle de source. La même application pourrait bien être déployée sur différents serveurs avec des paramètres extrêmement différents, et avoir à gérer des conflits de fusion et tout cela n'est pas mon idée du plaisir.

Existe-t-il une sorte de cadre / outil pour cela, ou est-ce que tout le monde pirate quelque chose ensemble?

mikl
la source
Je aime vraiment la façon dont la configuration se fait en mean.js . Fondamentalement, ils stockent la configuration pertinente de l'application dans une sorte de module séparé, basé sur différents paramètres par environnement d'application (pour la production, le développement, les tests) et en transmettant des détails spécifiques via des variables d'environnement d'application, comme des secrets, etc.
Hinrich

Réponses:

765

J'utilise un package.jsonpour mes packages et un config.jspour ma configuration, qui ressemble à:

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;

Je charge la config de mon projet:

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

et puis je peux accéder à mes affaires config.db_host,config.db_port etc ... Cela me permet d' utiliser soit des paramètres ou des paramètres hardcoded stockés dans les variables environnementales si je ne veux pas stocker les mots de passe dans le contrôle source.

Je génère également un package.jsonet insère une section de dépendances:

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

Lorsque je clone le projet sur ma machine locale, je cours npm installpour installer les packages. Plus d'informations à ce sujet ici .

Le projet est stocké dans GitHub, avec des télécommandes ajoutées pour mon serveur de production.

noli
la source
32
que se passe-t-il lorsque vous avez différents paramètres de configuration pour dev vs prod?
chovy
4
Je ne l'ai pas fait mais voici une façon de le faire .. pour chaque env, définissez le nom env dans une variable ENV. Ensuite, dans ce fichier, c'est juste javascript .. utilisez une instruction case ou if pour charger sélectivement les variables appropriées. Vous pouvez même créer un sous-fichier de configuration distinct pour chaque env, et dans l'instruction if, rechargez le sous-fichier ici dans une var de sous-configuration et exportez cette var de sous-configuration dans la configuration principale. Tout ce que j'essaie essentiellement de dire, c'est que c'est juste js, donc vous pouvez être créatif
noli
4
quel process.env? où se situe-t-il? Et comment le régler?
kiwi en colère
12
Je pensais "wow .. je regarde node.js depuis quelques heures et mon application fonctionne déjà .. btw, je vais peut-être partager ce morceau de code aléatoire que j'ai trouvé"
noli
3
Ne pouvez-vous pas encore utiliser des variables d'environnement pour stocker ces mots de passe? N'est-ce pas à cela que sert cette ligne: config.twitter.password = process.env.TWITTER_PASSWORD || 'mot de passe';
DMart
244

Vous pouvez exiger des fichiers JSON à partir de Node v0.5.x ( référençant cette réponse )

config.json:

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

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
TinyTimZamboni
la source
40
Pas tellement impressionné par cette fonctionnalité. Vous pourriez avoir besoin ("./ config.js") et vous avez la possibilité d'ajouter des commentaires aux fichiers de configuration que je considère très importants, ainsi que d'autres cloches et sifflets. Si votre configuration n'est que des propriétés et aucun code, vous ne perdez rien par require (config.js) avec votre JSON préfixé par exports.config =
teknopaul
3
@teknopaul vous avez raison, mais il y avait une grande discussion en cours sur la `` justesse '' / l'utilité d'utiliser des systèmes de modèles stupides contre des modèles intelligents qui m'ont dit: (1) vous voulez généralement un langage déclaratif / stupide pour les modèles / options (2) c'est une mauvaise idée de reconstruire un "presque-PL" pour faire juste des modèles (ou une configuration) - mieux pour réutiliser votre PL réel existant avec des comportements connus. jusqu'à présent +1 pour le recyclage de JS pour effectuer les réglages utilisateur; -1 pour ne pas avoir adopté l'approche déclarative. nous avons vu des choses de configuration assez complexes faites de manière déclarative; mon instinct me dit que c'est la voie à suivre.
flow
1
Pas d'intellisense sur les objets des fichiers json dans VScode (fin 2017). Intellisense entièrement fonctionnel pour les objets de module.exports.
Romain Vincent
199

Beaucoup plus tard, j'ai trouvé un assez bon module Node.js pour gérer la configuration: nconf .

Un exemple simple:

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

Il prend également en charge le stockage des paramètres dans Redis , l'écriture de fichiers de configuration, et dispose d'une API assez solide, et est également soutenu par l'une des boutiques Node.js les plus respectées, Nodejitsu , dans le cadre de l' initiative de framework Flatiron , il devrait donc être assez évolutif.

Découvrez nconf sur Github .

mikl
la source
2
Peut-être une question stupide, mais je n'ai pas vu d'explication claire: où dois-je définir les variables d'environnement de nœud? J'utilise déjà nconf mais il n'est pas clair où je définirais les variables environnementales. Est-ce dans nginx / apache? Est-ce un autre fichier de configuration?
Civilian
91
Je ne pense pas que l'utilisation du fichier .json comme configuration soit une bonne idée, car les commentaires ne sont pas autorisés.
Frank Xu
11
Ça a l'air génial. Je pense que vous surprendrez beaucoup d'Unixheads si le fichier de configuration remplace les options de ligne de commande et les variables d'environnement. Nous sommes habitués à l'ordre de priorité croissant suivant: fichier (s) de configuration, variables d'environnement, options de ligne de commande.
sheldonh
2
@sheldonh Attendez de découvrir que les options booléennes sont toujours définies sur argv, cassant ainsi la priorité ...: /
Daniel C. Sobral
@ DanielC.Sobral C'est vraiment dommage. Oh, et LTNS! :-)
sheldonh
94

Ma solution est assez simple:

Chargez la configuration de l'environnement dans ./config/index.js

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

module.exports = cfg;

Définissez quelques valeurs par défaut dans ./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';

Remplacez les valeurs par défaut dans ./config/config.test.js

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

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

module.exports = config;

L'utiliser dans ./models/user.js:

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

Exécution de votre application dans un environnement de test:

NODE_ENV=test node ./app.js
chovy
la source
2
Je préfère celui-ci. Comme mentionné par d'autres, JSON n'est pas une structure de stockage préférée et cette superposition avec des globaux est simple et efficace
Sebastian J.
La seule raison pour laquelle je préférerais cela à nconf est qu'il permet le format .js pour les fichiers de configuration (dev, test et prod). nous permettant de documenter chaque option de configuration qui autrement ne serait pas possible avec le format JSON.
Kunal Kapadia du
BTW, par NODE_ENVdéfaut «développement». Vous devriez plutôt vérifier la «production».
Kevin Suttle
5
Je ne vérifie pas le développement. Je suis en défaut. Je ne sais pas pourquoi je serais par défaut en production.
chovy
39

Vous pouvez également consulter dotenv qui suit les principes d'une application à douze facteurs .

J'avais l'habitude d'utiliser node-config, mais j'ai créé dotenv pour cette raison. Il a été complètement inspiré par la bibliothèque dotenv de ruby.

L'utilisation est assez simple:

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

Ensuite, il vous suffit de créer un fichier .env et d'y mettre vos paramètres comme ceci:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

C'est dotenv pour nodejs.

scottmotte
la source
2
Ou utilisez-le également, foreman run node xx.jsil sera automatiquement lu dans votre fichier .env.
Simon
1
utiliserais-je également cette approche pour la production?
Lamour
1
@lamar non, vous les définissez dans les variables env sur le serveur réel. C'était à chaque fois que vous déployez, ils sont là mais pas dans le code source.
sidonaldson
@Lamar oui, vous pouvez réellement, comme une alternative plus portable à la définition de variables env sur le serveur. L'important est de ne pas inclure le .envfichier dans votre processus de contrôle de version ou de déploiement.
Josh Noe
31

Utilisez-vous npm pour démarrer vos scripts (env, etc.)?

Si vous utilisez des .envfichiers, vous pouvez les inclure dans votre fichier package.json et utiliser npm pour les source / démarrer.

Exemple:

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

puis exécutez les scripts npm:

$ npm start-dev

Son décrit ici https://gist.github.com/ericelliott/4152984 Tous les crédits à Eric Elliot

lxx
la source
2
Pouvez-vous expliquer ce qu'est une "source"? Je reçoissource : not found
JohnnyBizzle
@JohnnyBizzle source(ou simplement, .) est une commande intégrée dans des shells Unix (Bash, etc.) pour lire et exécuter des commandes à partir du fichier donné, dans le shell actuel . Autrement dit, les commandes ne sont pas exécutées dans un sous-shell. L'effet de cela dans cet exemple est que les variables d'environnement définies dans prod.envsont ajoutées au shell courant et donc transmises à tout processus enfant généré par ce shell. Vous semblez utiliser Windows CMD. Voir cette question pour plus de détails.
Utku
À noter - l'application 12 facteurs recommande de ne pas créer dev.envet prod.env, mais d'avoir un seul .envfichier par déploiement.
Iiridayn
24

Vous pouvez également consulter node-config qui charge le fichier de configuration en fonction de la variable $ HOST et $ NODE_ENV (un peu comme RoR): documentation .

Cela peut être très utile pour différents paramètres de déploiement ( development, testou production).

Ngryman
la source
22

Faites simplement un simple settings.jsavec exports:

exports.my_password = 'value'

Ensuite, dans votre script, faites require:

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

Tous vos paramètres seront désormais disponibles via settings variable:

settings.my_password // 'value'
Vanuan
la source
@backdesk, bien sûr, vous pouvez mettre en place un système de stockage secret qui crypterait les secrets et limiterait l'accès à l'aide de l'ip, de certains jetons, etc. ne pas.
Vanuan
@backdesk Il n'y a aucun problème avec l'exemple. C'est juste ça: un exemple pour expliquer quelque chose de concret.
Emilio Grisolía
14

Je vais jeter mon chapeau sur le ring ici car aucune de ces réponses ne concerne tous les composants critiques dont presque tous les systèmes ont besoin. Considérations:

  • Configuration publique (visible par le frontend) vs configuration privée (guy mograbi a bien compris celui-ci). Et en veillant à ce que ceux-ci soient séparés.
  • Des secrets comme des clés
  • Valeurs par défaut vs remplacements spécifiques à l'environnement
  • Bundles frontaux

Voici comment je fais ma configuration:

  • config.default.private.js - Dans le contrôle de version, ce sont des options de configuration par défaut qui ne peuvent être vues que par votre backend.
  • config.default.public.js- Dans le contrôle de version, ce sont des options de configuration par défaut qui peuvent être vues par le backend et le frontend
  • config.dev.private.js - Si vous avez besoin de différents paramètres par défaut privés pour le dev.
  • config.dev.public.js - Si vous avez besoin de valeurs par défaut publiques différentes pour le dev.
  • config.private.js - Pas dans le contrôle de version, ce sont des options spécifiques à l'environnement qui remplacent config.default.private.js
  • config.public.js - Pas dans le contrôle de version, ce sont des options spécifiques à l'environnement qui remplacent config.default.public.js
  • keys/- Un dossier où chaque fichier stocke un secret différent d'une sorte. Ce n'est pas non plus sous contrôle de version (les clés ne doivent jamais être sous contrôle de version).

J'utilise des fichiers javascript simples pour la configuration, j'ai donc toute la puissance de la jauge javascript (y compris les commentaires et la possibilité de faire des choses comme charger le fichier de configuration par défaut dans le fichier spécifique à l'environnement afin qu'ils puissent ensuite être remplacés). Si vous souhaitez utiliser des variables d'environnement, vous pouvez les charger à l'intérieur de ces fichiers de configuration (je vous déconseille cependant d'utiliser des vars env pour la même raison que je ne recommande pas d'utiliser des fichiers json - vous n'avez pas la puissance d'un langage de programmation pour construire votre config).

La raison pour laquelle chaque clé se trouve dans un fichier séparé est à l'usage du programme d'installation. Cela vous permet d'avoir un programme d'installation qui crée des clés sur la machine et les stocke dans le dossier des clés. Sans cela, votre programme d'installation peut échouer lorsque vous chargez votre fichier de configuration qui ne peut pas accéder à vos clés. De cette façon, vous pouvez parcourir le répertoire et charger tous les fichiers clés qui se trouvent dans ce dossier sans avoir à vous soucier de ce qui existe et de ce qui n'existe pas dans une version donnée de votre code.

Puisque vous avez probablement des clés chargées dans votre configuration privée, vous ne voulez certainement pas charger votre configuration privée dans un code frontal. Bien qu'il soit probablement strictement plus idéal de séparer complètement votre base de code frontend de votre backend, la plupart du temps, PITA est une barrière suffisamment grande pour empêcher les gens de le faire, donc une configuration privée vs publique. Mais il y a deux choses que je fais pour empêcher le chargement d'une configuration privée dans le frontend:

  1. J'ai un test unitaire qui garantit que mes bundles frontend ne contiennent pas l'une des clés secrètes que j'ai dans la configuration privée.
  2. J'ai mon code frontal dans un dossier différent de mon code principal, et j'ai deux fichiers différents nommés "config.js" - un pour chaque extrémité. Pour le backend, config.js charge la configuration privée, pour le frontend, il charge la configuration publique. Ensuite, vous avez toujours juste besoin ('config') et ne vous inquiétez pas d'où cela vient.

Une dernière chose: votre configuration doit être chargée dans le navigateur via un fichier complètement distinct de tout autre code frontal. Si vous regroupez votre code frontal, la configuration publique doit être construite comme un ensemble complètement distinct. Sinon, votre configuration n'est plus vraiment la configuration - c'est juste une partie de votre code. La configuration doit pouvoir être différente sur différentes machines.

BT
la source
13

Condamné est une autre option qui ajoute un schéma de validation. Comme nconf, il prend en charge le chargement des paramètres à partir de n'importe quelle combinaison de variables d'environnement, d'arguments, de fichiers et d'objets json.

Exemple du 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"
  }
});

Article de mise en route: Apprivoiser les configurations avec node-convict

hurrymaplelad
la source
12

Vous pouvez utiliser Konfig pour les fichiers de configuration spécifiques à l'environnement. Il charge automatiquement les fichiers de configuration json ou yaml, il a une valeur par défaut et des fonctionnalités de configuration dynamique.

Un exemple du repo 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 développement:

> config.app.port
3000

En production, supposons que nous commençons l'application avec $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

Plus de détails: https://github.com/vngrs/konfig

Ali Davut
la source
9

Je vais créer un dossier comme config un nom de fichier config.jset plus tard j'utiliserai ce fichier partout où requis comme ci-dessous

Exemple de config.js

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

Ensuite, si je veux utiliser ce fichier de configuration quelque part

Je vais d'abord importer comme ci-dessous

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

et je peux accéder aux valeurs ci-dessous

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');
    }
});
Ron
la source
6

Utilisez simplement le npmmodule config(plus de 300000 téléchargements)

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

Node-config organise les configurations hiérarchiques pour les déploiements de vos applications.

Il vous permet de définir un ensemble de paramètres par défaut et de les étendre à différents environnements de déploiement (développement, qa, staging, production, 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
alex dykyі
la source
4

Il est préférable de séparer les configurations «développement» et «production» .

J'utilise la manière suivante: Voici mon fichier 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 : ""
        }
    }
} 

Pour exiger la configuration, utilisez ce qui suit:

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

Vous pouvez ensuite utiliser votre objet de configuration:

const ip_address = config.ip_address;
const port = config.port;
Aram Manukyan
la source
vous pouvez également utiliser module.exports = config;à la fin du config/index.jsfichier
mapmalith
3

Je suis un peu en retard dans le jeu, mais je n'ai pas trouvé ce dont j'avais besoin ici - ou ailleurs - alors j'ai écrit quelque chose moi-même.

Mes exigences pour un mécanisme de configuration sont les suivantes:

  1. Prise en charge front-end. Quel est l'intérêt si le frontal ne peut pas utiliser la configuration?
  2. Support settings-overrides.js- qui a la même apparence mais permet des remplacements de configuration à settings.js. L'idée ici est de modifier facilement la configuration sans changer le code. Je le trouve utile pour les saas.

Même si je me soucie moins des environnements de support - le vous expliquera comment l'ajouter facilement à ma solution

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;

Explication

  • undefined signifie que cette propriété est requise
  • null signifie qu'il est facultatif
  • meConf- actuellement le code est ciblé vers un fichier sous app. meConfest les fichiers de substitution qui sont ciblés conf/dev- qui sont ignorés par mes vcs.
  • publicConfiguration - sera visible du front-end et du back-end.
  • privateConfiguration - sera visible uniquement depuis le back-end.
  • sendPublicConfiguration- une route qui exposera la configuration publique et l'affectera à une variable globale. Par exemple, le code ci-dessous exposera la configuration publique en tant que variable globale myConf dans le front-end. Par défaut, il utilisera le nom de la variable globaleconf .

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

Logique des remplacements

  • privateConfiguration est fusionné avec publicConfiguration puis meConf.
  • publicConfiguration vérifie chaque clé si elle a un remplacement et utilise ce remplacement. De cette façon, nous n'exposons rien de privé.

Ajout de la prise en charge de l'environnement

Même si je ne trouve pas un "support d'environnement" utile, peut-être que quelqu'un le fera.

Pour ajouter la prise en charge de l'environnement, vous devez remplacer l'instruction meConf require par quelque chose comme ceci (pseudocode)

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

if (environnement == "développement") {meConf = require ("../ conf / dev / meConf"). development; }

De même, vous pouvez avoir un fichier par environnement

 meConf.development.js
 meConf.production.js

et importez le bon. Le reste de la logique reste le même.

guy mograbi
la source
pas terriblement évident qui undefinedsignifie vraiment «requis» et nullsignifie «facultatif». donc le bac jaune est pour les plastiques et le bleu pour le papier brouillon? bien, mais a dû lire le manuel avant de jeter cette litière.
flow
Vous n'êtes pas obligé d'utiliser cette convention. Je le trouve utile et j'informe mon équipe de l'utiliser, mais vous pouvez évidemment supprimer cette fonctionnalité.
guy mograbi
3

un exemple alternatif que je viens d'utiliser parce que je voulais plus de flexibilité qu'un fichier .json typique mais que je ne voulais pas qu'il soit extrait dans une bibliothèque qui nécessiterait une dépendance, c'est quelque chose comme ça. Fondamentalement, l'exportation d'une fonction invoquée immédiatement renvoyait un objet avec les valeurs que je voulais définir. Donne beaucoup de flexibilité.

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

Il y a une bien meilleure explication avec un exemple complet ici. Utilisation de fichiers de configuration dans Node.js

captainavi
la source
3

Je sais que c'est un très vieux post. Mais je veux partager mon module pour configurer les variables d'environnement, je pense que c'est une solution très flexible. Voici le module 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 

Ensuite, vous pouvez utiliser process.env.NODE_ENVpour obtenir toutes les variables de votre environnement.

Christian
la source
2

En plus du module nconf mentionné dans cette réponse et de node-config mentionné dans cette réponse , il existe également node-iniparser et IniReader , qui semblent être des analyseurs de fichiers de configuration .ini plus simples.

Wingman4l7
la source
aucun moyen de revenir aux fichiers win-ini ... qui iniparsersouligne fièrement le fait qu'ils savent comment analyser les sections dans la config ... en 2013 ... si vous avez besoin d'une imbrication plus profonde, dites-vous [foo/bar]? [foo\bar]? bar.baz=42? bar/baz=42? bar\baz=42? bar:baz=42? comment dites-vous 42est un nombre? il pourrait s'agir d'un texte à tous les chiffres! - à partir de XML, lancez YAML, lancez WIN.INI, embrassez JSON, les soucis disparaissent.
flow
1

Vous pouvez utiliser pconf: https://www.npmjs.com/package/pconf

Exemple:

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

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

}
Per Henrik Jakobsson
la source
1

Voici une approche soignée inspirée de cet article . Il ne nécessite aucun package supplémentaire, à l'exception du package lodash omniprésent . De plus, il vous permet de gérer les valeurs par défaut imbriquées avec des remplacements spécifiques à l'environnement.

Tout d'abord, créez un dossier de configuration dans le chemin racine du package qui ressemble à ceci

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

voici le fichier index.js

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

Supposons maintenant que nous avons un defaults.json comme

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

et development.json comme ça

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

si vous faites config = require('./config')ici, c'est ce que vous obtiendrez

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

Notez que vous obtenez toutes les valeurs par défaut, à l'exception de celles définies dans les fichiers spécifiques à l'environnement. Vous pouvez donc gérer une hiérarchie de configuration. L'utilisation defaultsDeepgarantit que vous pouvez même avoir des valeurs par défaut imbriquées.

Rahul
la source
0

J'ai essayé certaines des solutions suggérées ici, mais je n'en ai pas été satisfait, j'ai donc créé mon propre module. On l'appellemikro-config et la principale différence est qu'il respecte la convention sur la configuration, vous pouvez donc simplement avoir besoin du module et commencer à l'utiliser.

Vous stockez votre configuration dans des fichiers js simples ou json à partir du /configdossier. D'abord, il charge le default.jsfichier, puis tous les autres fichiers du /configrépertoire, puis il charge la configuration spécifique à l'environnement basée sur une $NODE_ENVvariable.

Il permet également de remplacer cette configuration pour le développement local avec local.jsou spécifique à l'environnement/config/env/$NODE_ENV.local.js .

Vous pouvez le regarder ici:

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

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

Martin Adámek
la source
0

Pendant longtemps, j'ai utilisé l'approche mentionnée dans la solution ici. Il existe cependant une préoccupation quant à la sécurité des secrets en texte clair. Vous pouvez utiliser un autre package par dessus configpour que les bits de sécurité soient pris en charge.

Vérifiez ceci: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

Rahul Soni
la source
Pourquoi devrais-je même m'abonner à Azure pour payer ce service? Pourquoi ne pas utiliser ansible-vault? Autre chose: je pense que personne ne publiera un fichier de configuration avec des informations d'identification en texte clair sur le référentiel source. Utilisez des variables d'environnement ou placez-les dans un fichier avec une autorisation de lecture seule.
Yasser Sinjab
Si vous pouvez le lire à partir d'un emplacement tiers et le décoder et que votre service utilise ces données secrètes, il sera possible pour un pirate informatique de faire exactement la même chose s'il accède à votre ordinateur. C'est plus de travail (prend plus de temps) mais au final ça ne vous protège pas. Si votre serveur est pénétré, imaginez que tout ce que vous avez dessus est désormais public.
Alexis Wilke