Bagaimana untuk menyimpan Node.js penyebaran pengaturan/konfigurasi file?

Saya telah bekerja pada beberapa Node apps, dan I've telah mencari pola yang baik menyimpan penyebaran yang berhubungan dengan pengaturan. Di Django dunia (dari mana aku datang), umum berlatih akan memiliki settings.py file yang berisi pengaturan standar (timezone, dll), dan kemudian local_settings.py untuk penyebaran pengaturan khusus, yaitu. apa database untuk bicara, apa yang memcache socket, e-mail admin dan sebagainya.

Saya telah mencari pola yang sama untuk Node. Hanya file konfigurasi akan lebih baik, sehingga tidak harus menjadi macet dengan segala sesuatu yang lain dalam app.js, tetapi saya menemukan hal ini penting untuk memiliki cara untuk memiliki server-konfigurasi tertentu pada file yang tidak di kontrol sumber. Aplikasi yang sama juga bisa digunakan di server yang berbeda dengan liar pengaturan yang berbeda, dan harus berurusan dengan menggabungkan konflik dan semua itu adalah bukan ide yang menyenangkan.

Jadi ada semacam kerangka/alat untuk ini, atau apakah semua orang hanya hack sesuatu bersama-sama mereka?

Mengomentari pertanyaan (1)

Saya menggunakan paket.json untuk saya paket dan config.js untuk konfigurasi saya, yang terlihat seperti:

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;

Saya load config dari proyek saya:

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

dan kemudian saya dapat mengakses hal-hal dari config.db_host, config.db_port, dll... Ini memungkinkan saya menggunakan hardcoded parameter atau parameter yang disimpan dalam variabel lingkungan jika saya don't ingin menyimpan password di kontrol sumber.

Aku juga menghasilkan paket.json dan masukkan dependensi bagian:

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

Ketika saya clone proyek untuk mesin lokal, saya menjalankan npm install untuk menginstal paket. Info lebih lanjut tentang itu di sini.

Proyek yang disimpan di GitHub, dengan remote menambahkan untuk server produksi.

Komentar (18)

Anda dapat meminta file JSON sebagai Node v0.5.x (referensi jawaban ini)

config.json:

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

app.js:

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

Banyak kemudian, saya menemukan cukup baik Node.js modul untuk mengelola konfigurasi: nconf.

Contoh sederhana:

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

Ini juga mendukung menyimpan pengaturan di Redis, tulisan file-file konfigurasi, dan memiliki cukup solid API, dan juga didukung oleh salah satu dari lebih dihormati Node.js toko-toko, Nodejitsu, sebagai bagian dari [Seterika][] kerangka inisiatif, sehingga harus cukup masa depan-bukti.

Check out nconf di Github.

Komentar (15)

Solusi saya adalah cukup sederhana:

Beban lingkungan config di ./config/index.js

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

module.exports = cfg;

Mendefinisikan beberapa default dalam ./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';

Override default dalam ./config/config.test.js

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

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

module.exports = config;

Menggunakannya dalam ./models/user.js:

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

Menjalankan aplikasi anda di lingkungan tes:

NODE_ENV=test node ./app.js

Hal ini dijelaskan secara lebih rinci berikut ini: http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/

Komentar (4)

Anda mungkin juga melihat ke dotenv yang mengikuti prinsip-prinsip yang dua belas-faktor app.

Aku digunakan untuk menggunakan node-config, tapi dibuat dotenv untuk alasan itu. Itu benar-benar terinspirasi oleh ruby's dotenv perpustakaan.

Penggunaan cukup mudah:

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

Kemudian anda hanya membuat .env file dan menempatkan pengaturan anda di sana seperti:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Yang's dotenv untuk nodejs.

Komentar (4)

Apakah kalian menggunakan npm untuk memulai script anda (env dll) ?

Jika anda menggunakan .env file, anda dapat memasukkan mereka dalam paket.json dan menggunakan npm untuk sumber/awal mereka.

Contoh:

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

kemudian jalankan npm script:

$ npm start-dev

Yang dijelaskan di sini https://gist.github.com/ericelliott/4152984 Semua kredit untuk Eric Elliot

Komentar (4)

Anda mungkin juga melihat ke node-config yang memuat file konfigurasi tergantung pada $HOST dan __$NODE_ENV__ variabel (sedikit seperti RoR) : dokumentasi.

Ini bisa sangat berguna untuk berbagai penyebaran pengaturan (pembangunan, test atau produksi).

Komentar (0)

Hanya melakukan yang sederhana settings.js dengan ekspor:

exports.my_password = 'value'

Kemudian, pada script anda, melakukan memerlukan:

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

Semua pengaturan anda sekarang akan tersedia melalui pengaturan variabel:

settings.my_password // 'value'
Komentar (2)

I'm akan melemparkan topi ke dalam ring sini karena tidak satupun dari jawaban anda, semua komponen-komponen penting yang cukup banyak setiap kebutuhan sistem. Pertimbangan:

  • Semua konfigurasi (yang dapat dilihat oleh frontend) vs konfigurasi pribadi (pria mograbi punya yang satu ini benar). Dan membuat ini disimpan terpisah.
  • Rahasia seperti kunci
  • Default vs lingkungan tertentu menimpa
  • Frontend bundel

Berikut ini's bagaimana saya melakukan konfigurasi:

  • config.default.private.js - In kontrol versi, ini adalah konfigurasi default pilihan yang hanya dapat dilihat oleh backend anda.
  • config.default.public.js - In kontrol versi, ini adalah konfigurasi default pilihan yang dapat dilihat oleh backend dan frontend
  • config.dev.private.js - Jika anda membutuhkan pribadi yang berbeda default untuk dev.
  • config.dev.public.js - Jika anda membutuhkan publik yang berbeda default untuk dev.
  • config.private.js - Tidak di kontrol versi, ini adalah lingkungan tertentu pilihan yang menimpa config.default.private.js
  • config.public.js - Tidak di kontrol versi, ini adalah lingkungan tertentu pilihan yang menimpa config.default.public.js
  • kunci - folder di mana masing-masing file yang menyimpan berbagai rahasia dari beberapa jenis. Ini juga tidak di bawah kontrol versi (kunci tidak boleh di bawah kontrol versi).

Saya menggunakan javascript polos-lama file-file untuk konfigurasi sehingga aku memiliki kekuatan penuh dari javascript langauge (termasuk komentar dan kemampuan untuk melakukan hal-hal seperti load default config di lingkungan-file tertentu sehingga mereka kemudian dapat diganti). Jika anda ingin menggunakan variabel lingkungan, anda dapat memuat mereka dalam mereka config file (tho saya sarankan terhadap menggunakan env var untuk alasan yang sama saya don't sarankan menggunakan json file - anda don't memiliki kekuatan bahasa pemrograman untuk membangun config).

Alasan setiap tombol pada file yang terpisah adalah untuk installer menggunakan. Hal ini memungkinkan anda untuk memiliki installer yang menciptakan tombol on-mesin dan toko-toko mereka di tombol folder. Tanpa ini, installer anda mungkin gagal ketika anda memuat berkas konfigurasi yang dapat't akses kunci anda. Dengan cara ini anda dapat melintasi direktori dan beban tombol apa saja file yang ada di folder itu tanpa harus khawatir tentang apa yang ada dan apa yang doesn't dalam setiap versi dari kode anda.

Karena anda mungkin memiliki tombol dimuat dalam pribadi anda konfigurasi, anda pasti don't ingin memuat pribadi anda config di frontend kode. Sementara yang mungkin benar-benar lebih ideal untuk benar-benar terpisah frontend anda codebase dari backend anda, banyak kali bahwa PITA ini cukup besar penghalang untuk mencegah orang dari melakukan hal itu, sehingga swasta vs publik config. Tapi ada's dua hal yang saya lakukan untuk mencegah swasta config yang dimuat di frontend:

  1. Saya memiliki unit tes yang memastikan saya frontend bundel don't mengandung salah satu kunci rahasia yang saya miliki di swasta config.
  2. Saya frontend kode di folder yang berbeda dari saya kode backend, dan saya memiliki dua file yang berbeda bernama "config.js" - satu untuk masing-masing ujung. Untuk backend, config.js beban pribadi config, untuk frontend, beban umum config. Kemudian anda hanya memerlukan('config') dan don't khawatir tentang di mana itu berasal dari.

Satu hal terakhir: konfigurasi anda harus dimuat ke browser melalui benar-benar file terpisah dari yang lain frontend kode. Jika anda bundel frontend anda kode, umum konfigurasi yang harus dibangun sebagai benar-benar terpisah bundel. Jika tidak, anda config isn't benar-benar config lagi - hanya bagian dari kode anda. Config kebutuhan untuk dapat berbeda pada mesin yang berbeda.

Komentar (2)

Tahanan adalah pilihan lain yang menambahkan skema untuk validasi. Seperti nconf, mendukung memuat pengaturan dari setiap kombinasi dari variabel lingkungan, argumen, file, dan objek json.

Contoh dari 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"
  }
});

Memulai artikel: Penjinakan Konfigurasi dengan node-convict

Komentar (0)

Anda dapat menggunakan Konfig untuk lingkungan tertentu config file. Beban json atau yaml file konfigurasi secara otomatis, memiliki nilai default dan dinamis konfigurasi fitur.

Contoh dari Konfig repo:

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

Dalam pembangunan:

> config.app.port
3000

Dalam produksi, misalnya kita mulai dengan aplikasi $ NODE_ENV=produksi PORT=4567 node app.js

> config.app.port
4567

Rincian lebih lanjut : https://github.com/vngrs/konfig

Komentar (0)

Saya akan membuat sebuah folder config file penamaan sebagai config.js dan kemudian saya akan menggunakan file ini di mana pun diperlukan sebagai berikut

Contoh config.js

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

Kemudian jika saya ingin menggunakan file konfigurasi ini di suatu tempat

Pertama saya akan impor seperti di bawah ini

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

dan saya dapat mengakses nilai-nilai seperti di bawah ini

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

Hanya menggunakan npm modul config (lebih dari 300000 download)

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

Node-config menyelenggarakan hirarkis konfigurasi untuk aplikasi anda penyebaran.

Hal ini memungkinkan anda menentukan satu set default parameter, dan memperpanjang mereka untuk berbagai penyebaran lingkungan (pengembangan, qa, pementasan, produksi, dll.).

$ 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
Komentar (0)

It's baik untuk memisahkan 'pengembangan' dan 'produksi' konfigurasi.

Saya menggunakan cara berikut: Di sini saya config/index.js file:

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

Untuk memerlukan konfigurasi menggunakan berikut:

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

Daripada anda dapat menggunakan konfigurasi objek:

const ip_address = config.ip_address;
const port = config.port;
Komentar (1)

Saya sedikit terlambat dalam permainan, tapi aku tidak't menemukan apa yang saya butuhkan di sini - atau di mana pun - jadi saya menulis sesuatu sendiri.

Kebutuhan saya untuk konfigurasi mekanisme adalah sebagai berikut:

  1. Dukungan front-end. Apa gunanya jika front-end tidak dapat menggunakan konfigurasi?
  2. Dukungan settings-overrides.js - yang terlihat sama tetapi memungkinkan menimpa konfigurasi di settings.js. Idenya di sini adalah untuk mengubah konfigurasi dengan mudah tanpa mengubah kode. Saya menemukan itu berguna untuk saas.

Meskipun saya peduli tentang lingkungan yang mendukung - yang akan menjelaskan bagaimana untuk menambah mudah untuk solusi saya

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;

Penjelasan

  • undefined berarti properti ini diperlukan
  • null berarti itu adalah opsional
  • meConf - saat ini kode adalah target untuk file di bawah aplikasi. meConf adalah menimpa file yang ditargetkan untuk conf/dev - yang diabaikan oleh saya vcs.
  • publicConfiguration - akan terlihat dari front-end dan back-end.
  • privateConfiguration - akan terlihat dari back-end saja.
  • sendPublicConfiguration - rute yang akan mengekspos semua konfigurasi dan menetapkan variabel global. Untuk contoh kode di bawah ini akan mengekspos semua konfigurasi sebagai variabel global myConf di front-end. Secara default akan menggunakan variabel global nama conf.

aplikasi.mendapatkan("/backend/conf", memerlukan("conf").sendPublicConfiguration);

<script src="/backend/conf?nama=myConf" type="javascript/teks">

Logika menimpa

  • privateConfiguration bergabung dengan publicConfiguration dan kemudian meConf.
  • publicConfiguration cek setiap tombol jika telah menimpa, dan menggunakan yang menimpa. Dengan cara ini kita tidak mengekspos hal-hal pribadi.

Menambahkan dukungan lingkungan

Meskipun aku don't menemukan "lingkungan mendukung" berguna, mungkin seseorang akan.

Untuk menambah lingkungan dukungan yang anda butuhkan untuk mengubah meConf memerlukan pernyataan untuk sesuatu seperti ini (pseudocode)

jika ( lingkungan == "produksi" ) { meConf = require("../conf/dev/meConf").produksi; }

jika ( lingkungan == "pengembangan" ) { meConf = require("../conf/dev/meConf").pembangunan; }

Demikian pula anda dapat memiliki sebuah file per lingkungan

 meConf.development.js
 meConf.production.js

dan impor yang tepat. Sisa logika tetap sama.

Komentar (2)

alt contoh yang saya hanya digunakan karena aku ingin lebih banyak fleksibilitas daripada yang khas .file json tetapi didn't ingin disarikan pergi ke perpustakaan yang akan membutuhkan ketergantungan adalah sesuatu seperti ini. Pada dasarnya, mengekspor fungsi yang dipanggil segera yang kembali sebuah objek dengan nilai-nilai yang saya inginkan mengatur. Memberikan banyak fleksibilitas.

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

Ada banyak penjelasan yang lebih baik dengan penuh contoh berikut. Menggunakan Config File di Node.js

Komentar (0)

Saya tahu ini adalah benar-benar old post. Tapi saya ingin berbagi modul untuk mengkonfigurasi variabel lingkungan, saya pikir itu adalah solusi yang fleksibel. Berikut ini adalah modul json-configurator

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

Kemudian anda dapat menggunakan proses.env.NODE_ENV untuk mendapatkan semua variabel untuk lingkungan anda.

Komentar (1)

Selain nconf modul disebutkan dalam jawaban, dan node-config disebutkan di jawaban ini, ada juga node-iniparser dan IniReader, yang muncul untuk menjadi lebih sederhana .ini file konfigurasi parsers.

Komentar (1)

Saya baru-baru ini merilis sebuah modul kecil untuk memuat semua jenis file-file konfigurasi. It's cukup lurus ke depan, anda dapat memeriksa di https://github.com/flesler/config-node

Komentar (0)

Anda dapat menggunakan pconf: https://www.npmjs.com/package/pconf

Contoh:

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

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

}
Komentar (0)