Il y a quelques jours, je cherchais à mettre en place un chargeur de fichier de configuration qui pouvait être surchargé, prendre en compte une configuration par défaut et valider les données. Surcharger signifie que le fichier principal de configuration pouvait être complété par un autre. L’usage par exemple est de pouvoir charger son fichier de configuration principale et celui de l’environnement de démarrage.
J’avais quelques pistes, comme object-assign mais il est mal adapté lorsque les propriétés enfants contiennent des objets, c’est-à-dire que object-assign va simplement décaler à gauche l’objet sans vérifier les valeurs de cet objet. J’ai continué à survoler les pages de module npm et github jusqu’à trouver node-convict.
Du côté du YAML (JSON-like en gros)
schema.yml
Prenons l’exemple de mon module, je souhaite que ma configuration me permette de renseigner le chemin vers le dossier du cache et le port de celui-ci.
D’un côté j’aurais :
- Le path vers le fichier cache de format
String
avec une valeur par défaut deapp/cache/
; - De l’autre le format
port
pour le port du serveur avec une valeur par défaut de3000
.
Mon schéma ressemblera à ceci :
path:
cache:
# path.cache
format: String
default: app/cache/
http:
port:
# http.port
format: port
default: 3000
config.yml et config_prod.yml
Je souhaite mettre mon application appA
en cache dans un sous-dossier et lorsque mon application est en prod, je souhaite utiliser le port 80, voici les deux configurations correspondantes :
config.yml
path:
cache: app/cache/appA/
http:
port: 5000
config_prod.yml
http:
port: 80
Résultat
{
"path": {
"cache": "app/cache/appA/"
},
"http": {
"port": 80
}
}
Du côté du code, JS
Du côté du javascript c’est assez simple à comprendre. Pour charger la configuration ça se passe comme ceci :
const Convict = require('convict');
const yaml = require('yaml')
const path = require('path')
// add support for YAML files
Convict.addParser({ extension: ['yml', 'yaml'], parse: yaml.parse });
// load schema.yml
const config = Convict(path.resolve(__dirname, 'schema.yml'))
const paths = [
path.resolve(__dirname, '..', 'app/config.yml'),
path.resolve(__dirname, '..', 'app/config_prod.yml')
]
config.loadFile(paths);
config.validate();
// show final Object
console.log(JSON.stringify(config.getProperties(), null, 2))
Pour obtenir le numéro du port, nous devrons faire : config.get('http.port')
.
Dans la pratique, il faudra intercepter la possible erreur qui peut être lancé par .validate()
si le format est incorrect, donc :
try {
config.validate()
} catch (err) {
console.error('Check your configuration you have an invalid value :')
console.error(err.message)
process.exit(1)
}
Essayer ?
Pour essayer rien de plus simple ! J’ai fais un dépôt git pour que ça soit simple & rapide, voici les 3 commandes à écrire :
git clone https://github.com/A-312/node-convict-example-usage && cd node-convict-example-usage
npm install
npm start
Bon vol !