Как сохранить файлы настроек / конфигурации Node.js?

640

Я работал над несколькими приложениями Node и искал хороший шаблон хранения настроек, связанных с развертыванием. В мире Django (откуда я родом) обычной практикой было бы иметь settings.pyфайл, содержащий стандартные настройки (часовой пояс и т. Д.), А затем файл local_settings.pyдля конкретных настроек развертывания, т.е. с какой базой данных общаться, с каким сокетом memcache, адресом электронной почты для администраторов и так далее.

Я искал похожие шаблоны для Node. Было бы неплохо просто файл конфигурации, так что его не нужно смешивать со всем остальным app.js, но я считаю важным иметь способ иметь специфическую для сервера конфигурацию в файле, который не находится под контролем исходного кода. Одно и то же приложение вполне может быть развернуто на разных серверах с совершенно разными настройками, с необходимостью иметь дело с конфликтами слияния и всем, что не является моей идеей забавы.

Так есть ли какой-то фреймворк / инструмент для этого или все просто взломали что-то вместе?

Mikl
источник
я на самом деле нравится, как конфигурация выполняется в mean.js . в основном, они хранят соответствующие настройки приложения в отдельном модуле, основанном на различных настройках для среды приложения (для производства, разработки, тестирования) и передачи определенных деталей через переменные среды приложения, такие как секреты и т. д.
Хинрих

Ответы:

765

Я использую package.jsonдля своих пакетов и config.jsдля моей конфигурации, которая выглядит следующим образом:

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;

Я загружаю конфиг из моего проекта:

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

и затем я могу получить доступ к своим вещам из config.db_host, config.db_portи т.д ... Это позволяет мне использовать жестко закодированные параметры или параметры, хранящиеся в переменных среды, если я не хочу хранить пароли в управлении исходным кодом.

Я также генерирую package.jsonи вставляю раздел зависимостей:

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

Когда я клонирую проект на свою локальную машину, я запускаю npm installустановку пакетов. Больше информации об этом здесь .

Проект хранится в GitHub, с добавленными пультами для моего производственного сервера.

недотрога
источник
32
что происходит, когда у вас разные настройки для dev и prod?
Чови
4
У меня нет, но вот один из способов сделать это ... для каждого env установить имя env в переменной ENV. Затем в этом файле просто JavaScript. Используйте оператор case или if для выборочной загрузки соответствующих переменных. Вы могли бы даже создать отдельный конфигурационный подфайл для каждого env, и в операторе if перезагрузить подфайл здесь в subconfig var и экспортировать этот subconfig var в основную конфигурацию. Все, что я в основном пытаюсь сказать, это то, что это просто JS, так что вы можете быть креативным
Ноли
4
что такое process.env? где он находится? И как это установить?
сердитый киви
12
Я думал: «Ух ты ... Я смотрел на node.js несколько часов, и мое приложение уже работает ... Кстати, может быть, я поделюсь этим случайным кусочком кода, который придумал»
noli
3
Разве вы не можете использовать переменные окружения для хранения этих паролей? Разве не для этого предназначена эта строка: config.twitter.password = process.env.TWITTER_PASSWORD || 'пароль';
DMart
244

Вы можете требовать файлы JSON с Node v0.5.x ( ссылаясь на этот ответ )

config.json:

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

app.js:

var config = require('./config.json');
log_in(config.username, config.password);
TinyTimZamboni
источник
40
Не так впечатлен этой функцией. Вам может потребоваться ("./ config.js"), и вы получите возможность добавлять комментарии к файлам конфигурации, которые я считаю очень важными, и другие навороты. Если вы конфигурируете только свойства, а код отсутствует, вы ничего не теряете по требованию (config.js) с вашим JSON с префиксом
exports.config
3
@teknopaul, вы правы, но когда-то шла большая дискуссия о «правильности» / удобстве использования тупых и умных шаблонных систем, которая говорила мне: (1) вы обычно хотите декларативный / тупой язык для шаблонов / параметров (2) плохая идея - реконструировать «почти PL», чтобы просто использовать шаблоны (или конфигурацию) - лучше повторно использовать существующий реальный PL с известным поведением. пока +1 для утилизации JS для выполнения пользовательских настроек; -1 за не идущий декларативный подход. мы видели некоторые довольно сложные вещи конфигурации, сделанные декларативным способом; моя кишка говорит мне, что это путь.
поток
1
Нет Intellisense для объектов из файлов JSON в VScode (конец 2017 года). Полностью рабочий intellisense для объектов из module.exports.
Ромен Винсент
199

Намного позже я нашел довольно хороший модуль Node.js для управления конфигурацией: nconf .

Простой пример:

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

Он также поддерживает хранение настроек в Redis , написание файлов конфигурации и имеет довольно солидный API, а также поддерживается одним из наиболее уважаемых магазинов Node.js, Nodejitsu , как часть инициативы платформы Flatiron , так что это должно быть довольно перспективный.

Проверьте nconf в Github .

Mikl
источник
2
Возможно глупый вопрос, но я не видел четкого объяснения: где я могу установить переменные среды узла? Я уже использую nconf, но не ясно, где бы я устанавливал переменные среды. Это в nginx / apache? Это другой конфигурационный файл?
гражданское население
91
Я не думаю, что использовать файл .json в качестве конфигурации является хорошей идеей, так как комментарии не допускаются.
Фрэнк Сюй
11
Это выглядит великолепно. Я думаю, что вы удивитесь многим Unixheads, если файл конфигурации переопределяет параметры командной строки и переменные среды. Мы привыкли к следующему порядку возрастания приоритета: конфигурационные файлы, переменные среды, параметры командной строки.
Шелдон
2
@sheldonh Подождите, пока вы не обнаружите, что булевы параметры всегда установлены на argv, поэтому нарушается приоритет ...: /
Даниэль С. Собрал
@ DanielC.Sobral Это настоящий позор. Ох и ЛТНС! :-)
Шелдон
94

Мое решение довольно простое:

Загрузите конфигурацию среды в ./config/index.js

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

module.exports = cfg;

Определите некоторые значения по умолчанию в ./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';

Переопределите значения по умолчанию в ./config/config.test.js

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

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

module.exports = config;

Используя его в ./models/user.js:

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

Запуск вашего приложения в тестовой среде:

NODE_ENV=test node ./app.js
chovy
источник
2
Я предпочитаю этот. Как уже упоминалось, JSON не является предпочтительной структурой хранения, и эта иерархия с глобальными элементами проста и эффективна
Себастьян Дж.
Единственная причина, по которой я бы предпочел это, а не nconf, заключается в том, что он допускает формат .js для файлов конфигурации (dev, test и prod). что позволяет нам задокументировать каждый параметр конфигурации, который в противном случае невозможен в формате JSON.
Кунал Кападия
Кстати, по NODE_ENVумолчанию «развитие». Вы должны проверить «производство» вместо этого.
Кевин Саттл
5
Я не проверяю развитие. Я по умолчанию на это. Не уверен, почему я когда-либо по умолчанию на производство.
Чови
39

Вы также можете посмотреть на dotenv, который следует принципам приложения из двенадцати факторов .

Раньше я использовал node-config, но по этой причине создал dotenv. Он был полностью вдохновлен библиотекой рубинов.

Использование довольно просто:

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

Затем вы просто создаете файл .env и помещаете туда свои настройки следующим образом:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

Это дотенв для nodejs.

scottmotte
источник
2
Или просто используйте foreman run node xx.jsэто автоматически прочитает в вашем файле .env.
Симон
1
я бы использовал этот подход для производства также?
Ламур
1
@lamar no, вы устанавливаете их в переменных env на реальном сервере. Это было каждый раз, когда вы развертываете, они есть, но не в исходном коде.
Сидональдсон
@ Lamar да, вы можете это сделать, как более портативную альтернативу настройке переменных env на сервере. Важным моментом является не включать .envфайл в процесс управления версиями или в процесс развертывания.
Джош
31

Ребята, вы используете npm для запуска ваших скриптов (env и т. Д.)?

Если вы используете .envфайлы, вы можете включить их в свой package.json и использовать npm для их создания / запуска.

Пример:

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

затем запустите сценарии npm:

$ npm start-dev

Это описано здесь https://gist.github.com/ericelliott/4152984 Вся заслуга Эрика Эллиота

LXX
источник
2
Можете ли вы объяснить, что такое «источник»? Я получаюsource : not found
JohnnyBizzle
@JohnnyBizzle source(или просто .) - это встроенная команда в оболочках Unix (Bash и т. Д.) Для чтения и выполнения команд из данного файла в текущей оболочке . То есть команды не выполняются в под-оболочке. Эффект этого в этом примере состоит в том, что переменные среды, определенные в prod.env, добавляются в текущую оболочку и, следовательно, передаются любому дочернему процессу, порожденному этой оболочкой. Вы, кажется, используете Windows CMD. Смотрите этот вопрос для более подробной информации.
Утку
Стоит отметить - приложение 12 factor рекомендует не создавать dev.envи prod.env, но иметь один .envфайл на развертывание.
Iiridayn
24

Вы также можете посмотреть на node-config, которая загружает файл конфигурации в зависимости от переменной $ HOST и $ NODE_ENV (немного похоже на RoR): документация .

Это может быть весьма полезным для различных параметров развертывания ( development, testили production).

ngryman
источник
22

Просто сделайте простое settings.jsс exports:

exports.my_password = 'value'

Затем в вашем скрипте выполните require:

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

Все ваши настройки теперь будут доступны через settingsпеременную:

settings.my_password // 'value'
Vanuan
источник
@ backdesk Конечно, вы можете настроить секретную систему хранения, которая будет шифровать секреты и ограничивать доступ с помощью ip, некоторых токенов и т. д. Но в конечном итоге все сводится к чтению некоторых файлов с диска, будь то зашифрованное или не.
Вануан
@backdesk Нет проблем с примером. Это просто пример для объяснения чего-то конкретного.
Эмилио Гризолиа
14

Я собираюсь бросить свою шляпу в кольцо здесь, потому что ни один из этих ответов не обращается ко всем критическим компонентам, которые в значительной степени нужны любой системе. Соображения:

  • Публичная конфигурация (которую видит внешний интерфейс) против частной конфигурации (парень mograbi понял это правильно). И обеспечение их хранятся отдельно.
  • Секреты как ключи
  • Значения по умолчанию против переопределений, зависящих от среды
  • Фронтенд связки

Вот как я делаю свою конфигурацию:

  • config.default.private.js - В управлении версиями это параметры конфигурации по умолчанию, которые видны только вашему бэкэнду.
  • config.default.public.js- В управлении версиями это параметры конфигурации по умолчанию, которые видны бэкэндом и внешним интерфейсом.
  • config.dev.private.js - Если вам нужны разные частные настройки по умолчанию для dev.
  • config.dev.public.js - Если вам нужны разные публичные значения по умолчанию для dev.
  • config.private.js - Не в управлении версиями, это специфические параметры среды, которые переопределяют config.default.private.js
  • config.public.js - Не в управлении версиями, это специфические параметры среды, которые переопределяют config.default.public.js
  • keys/- Папка, в которой каждый файл хранит какой-то секрет. Это также не под контролем версий (ключи никогда не должны быть под контролем версий).

Я использую простые старые файлы javascript для конфигурации, поэтому у меня есть все возможности языка javascript (включая комментарии и возможность делать такие вещи, как загрузка файла конфигурации по умолчанию в файле, специфичном для среды, чтобы затем их можно было переопределить). Если вы хотите использовать переменные окружения, вы можете загрузить их в эти файлы конфигурации (хотя я рекомендую не использовать env vars по той же причине, по которой я не рекомендую использовать файлы json - у вас нет возможностей языка программирования для создания ваш конфиг).

Причина, по которой каждый ключ находится в отдельном файле, предназначена для использования установщиком. Это позволяет вам иметь установщик, который создает ключи на компьютере и сохраняет их в папке ключей. Без этого ваш установщик может потерпеть неудачу при загрузке файла конфигурации, который не может получить доступ к вашим ключам. Таким образом, вы можете перемещаться по каталогу и загружать любые ключевые файлы, которые находятся в этой папке, не беспокоясь о том, что существует, а что нет в любой конкретной версии вашего кода.

Поскольку у вас, вероятно, есть ключи, загруженные в вашу личную конфигурацию, вы определенно не хотите загружать вашу личную конфигурацию в любой код внешнего интерфейса. В то время как, вероятно, было бы гораздо более идеальным полностью отделить вашу кодовую базу веб-интерфейса от вашей серверной части, во многих случаях PITA является достаточно большим барьером, препятствующим тому, чтобы люди делали это, таким образом, частная и общедоступная конфигурация. Но есть две вещи, которые я делаю, чтобы предотвратить загрузку приватного конфига в интерфейсе:

  1. У меня есть модульное тестирование, которое гарантирует, что мои пакеты веб-интерфейса не содержат один из секретных ключей, которые у меня есть в приватной конфигурации.
  2. У меня есть мой код внешнего интерфейса в папке, отличной от моего внутреннего кода, и у меня есть два разных файла с именем "config.js" - по одному для каждого конца. Для бэкэнда config.js загружает приватный конфиг, для внешнего интерфейса - публичный конфиг. Тогда вы всегда просто требуете ('config') и не беспокоитесь о том, откуда оно берется.

И последнее: ваша конфигурация должна быть загружена в браузер с помощью совершенно отдельного файла, чем любой другой код вашего внешнего интерфейса. Если вы связываете свой код внешнего интерфейса, общедоступная конфигурация должна создаваться как отдельный пакет. В противном случае ваш конфиг уже не является конфигом - это просто часть вашего кода. Конфиг должен быть разным на разных машинах.

BT
источник
13

Convict - это еще одна опция, которая добавляет схему для проверки. Как и nconf, он поддерживает загрузку настроек из любой комбинации переменных среды, аргументов, файлов и объектов json.

Пример из 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"
  }
});

Начальная статья: Укрощение конфигураций с помощью node-convict

hurrymaplelad
источник
12

Вы можете использовать Konfig для конкретных конфигурационных файлов. Он загружает файлы конфигурации json или yaml автоматически, имеет значения по умолчанию и функции динамической конфигурации.

Пример из репозитория 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"
    }
}

В развитие:

> config.app.port
3000

В производстве предположим, что мы запускаем приложение с $ NODE_ENV=production PORT=4567 node app.js

> config.app.port
4567

Более подробная информация: https://github.com/vngrs/konfig

Али Давут
источник
9

Я создам папку как config имя файла, а config.jsпозже я буду использовать этот файл везде, где требуется, как показано ниже

Пример config.js

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

Тогда, если я хочу использовать этот файл конфигурации где-нибудь

Я сначала импортирую, как показано ниже

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

и я могу получить доступ к значениям, как показано ниже

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

Просто используйте npmмодуль config(более 300000 загрузок)

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

Node-config организует иерархические конфигурации для ваших приложений.

Он позволяет вам определять набор параметров по умолчанию и расширять их для различных сред развертывания (разработки, качества, подготовки, производства и т. Д.).

$ 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

Лучше разделять конфиги «разработка» и «производство» .

Я использую следующий способ: Вот мой файл 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 : ""
        }
    }
} 

Для настройки требуется использовать следующее:

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

Чем вы можете использовать свой объект конфигурации:

const ip_address = config.ip_address;
const port = config.port;
Арам Манукян
источник
также вы можете использовать пользователя module.exports = config;в конце config/index.jsфайла
mapmalith
3

Я немного опоздал в игре, но я не мог найти то, что мне было нужно здесь или где-то еще, поэтому я написал что-то сам.

Мои требования к механизму конфигурации следующие:

  1. Поддержка front-end. Какой смысл, если клиент не может использовать конфигурацию?
  2. Поддержка settings-overrides.js- которая выглядит так же, но допускает переопределения конфигурации settings.js. Идея заключается в том, чтобы легко изменить конфигурацию без изменения кода. Я считаю это полезным для СААС.

Несмотря на то, что меня меньше заботят вспомогательные среды, я объясню, как легко добавить его в мое решение.

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;

объяснение

  • undefined означает, что это свойство обязательно
  • null означает, что это необязательно
  • meConf- в настоящее время код является целевым для файла в app. meConfэто файлы переопределений, на которые нацелены conf/dev- которые игнорируются моими vcs.
  • publicConfiguration - будет виден с передней и задней части.
  • privateConfiguration - будет виден только с конца.
  • sendPublicConfiguration- маршрут, который представит общедоступную конфигурацию и назначит ее глобальной переменной. Например, приведенный ниже код предоставит общедоступную конфигурацию как глобальную переменную myConf во внешнем интерфейсе. По умолчанию он будет использовать имя глобальной переменной conf.

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

Логика переопределений

  • privateConfiguration объединяется с publicConfiguration, а затем meConf.
  • publicConfiguration проверяет каждый ключ, если он имеет переопределение, и использует это переопределение. Таким образом, мы не разоблачаем ничего личного.

Добавление поддержки среды

Даже если я не нахожу полезной «поддержку среды», возможно, кто-то это сделает.

Чтобы добавить поддержку среды, вам нужно изменить выражение meConf require на что-то вроде этого (псевдокод)

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

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

Точно так же вы можете иметь файл для каждой среды

 meConf.development.js
 meConf.production.js

и импортировать правильный. Остальная логика остается прежней.

парень Мограби
источник
не очень очевидно, что на undefinedсамом деле означает «требуется» и nullозначает «необязательно». так желтая корзина для пластмассы, а синяя для макулатуры? хорошо, но пришлось прочитать руководство, прежде чем бросать этот мусор.
поток
Вам не нужно использовать это соглашение. Я считаю это полезным и приказываю моей команде использовать его, но вы, очевидно, можете удалить эту функцию.
парень mograbi
3

Пример alt, который я только что использовал, потому что я хотел большей гибкости, чем типичный файл .json, но не хотел, чтобы его абстрагировали в библиотеку, для которой потребовалась бы зависимость, что-то вроде этого. По сути, экспорт вызываемой функции немедленно возвращает объект со значениями, которые я хотел установить. Дает большую гибкость.

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

Здесь есть намного лучшее объяснение с полным примером. Использование файлов конфигурации в Node.js

captainavi
источник
3

Я знаю, что это действительно старый пост. Но я хочу поделиться своим модулем для настройки переменных среды, я думаю, что это очень гибкое решение. Вот модуль 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 

Затем вы можете использовать, process.env.NODE_ENVчтобы получить все переменные для вашей среды.

Кристиан
источник
2

Помимо модуля nconf, упомянутого в этом ответе , и узла-конфигурации, упомянутого в этом ответе , существуют также node-iniparser и IniReader , которые представляются более простыми анализаторами файла конфигурации .ini.

Wingman4l7
источник
нет способа вернуться к файлам win-ini ... которые iniparserгордо подчеркивают тот факт, что они знают, как анализировать разделы в конфигурации ... в 2013 году ... если вам нужно более глубокое вложение, говорите [foo/bar]? [foo\bar]? bar.baz=42? bar/baz=42? bar\baz=42? bar:baz=42? как вы скажете 42это число? это может быть текст из всех цифр! - бросить XML, бросить YAML, бросить WIN.INI, принять JSON, переживания исчезли.
поток
1

Я только недавно выпустил небольшой модуль для загрузки любых типов файлов конфигурации. Это довольно просто, вы можете проверить это на https://github.com/flesler/config-node

Ариэль Флезлер
источник
1

Вы можете использовать pconf: https://www.npmjs.com/package/pconf

Пример:

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

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

}
Пер Хенрик Якобссон
источник
1

Вот аккуратный подход, вдохновленный этой статьей . Он не требует никаких дополнительных пакетов, кроме вездесущего пакета lodash . Более того, он позволяет вам управлять вложенными значениями по умолчанию с перезаписью, зависящей от среды.

Сначала создайте папку config в корневом каталоге пакета, которая выглядит следующим образом

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

вот файл index.js

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

Теперь давайте предположим, что у нас есть defaults.json как

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

и development.json вроде так

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

если вы сделаете config = require('./config')вот то, что вы получите

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

Обратите внимание, что вы получаете все значения по умолчанию, за исключением тех, которые определены в специфичных для среды файлах. Таким образом, вы можете управлять иерархией конфигурации. Использование defaultsDeepгарантирует, что вы даже можете иметь вложенные значения по умолчанию.

Рахул
источник
0

Я попробовал некоторые из предложенных решений здесь, но не был удовлетворен ими, поэтому я создал свой собственный модуль. Он называется, mikro-configи главное отличие заключается в том, что он соблюдает соглашение о конфигурации, поэтому вы можете просто потребовать модуль и начать его использовать.

Вы сохраняете свою конфигурацию в виде простых файлов js или json из /configпапки. Сначала он загружает default.jsфайл, затем все остальные файлы из /configкаталога, затем загружает конфигурацию, зависящую от среды, на основе $NODE_ENVпеременной.

Это также позволяет переопределить эту конфигурацию для локальной разработки local.jsили конкретной среды /config/env/$NODE_ENV.local.js.

Вы можете взглянуть на это здесь:

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

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

Мартин Адамек
источник
0

Долгое время я использовал подход, упомянутый в решении здесь. Однако существует обеспокоенность по поводу сохранности секретов в открытом тексте. Вы можете использовать другой пакет поверх него, configчтобы обеспечить защиту битов.

Проверьте это: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

Рахул Сони
источник
Почему я должен даже подписаться на Azure для оплаты этой услуги? Почему бы не использовать ansible-vault? Другое дело: я думаю, что никто не будет публиковать файл конфигурации с открытым текстом в хранилище исходного кода. Либо используйте переменные окружения, либо поместите ваши секретные данные в файл с правами только для чтения.
Ясир
Если вы сможете прочитать его из какого-либо стороннего местоположения и декодировать, и ваша служба будет использовать эти сверхсекретные данные, то хакер сможет сделать то же самое, если получит доступ к вашему компьютеру. Это больше работы (занимает больше времени), но в конечном итоге это не защищает вас. Если ваш сервер проник, представьте, что все, что у вас есть на нем, теперь общедоступно.
Алексис Вилке