Node.jsで設定ファイルを読み込む


Node.jsでアプリを作った時に、パラメータを設定ファイルに書き出して開発環境やステージング、プロダクション環境などで切り替えたことがあります。この時に使用できるのが、[node-config](https://www.npmjs.org/package/config)モジュール。

## 設定ファイルとして対応しているフォーマット

- Javascript Object Notation - .json
- Javascript5 Object Notation - .json5
- Yet another markup language - .yaml
- Javascript - .js
- CoffeeScript - .coffee
- CoffeeScript Object Notation - .cson
- Properties file format - .properties

## ファイルの読み込み順
通常は実行しているアプリの./configディレクトリ下の設定ファイルを読み込みます。また、$NODE_ENV環境変数の値を見て読み込むファイルを切り替える様にすることもできます。

./configディレクトリ以下のファイルは次の順番で読み込まれる様です。

```
default.EXT
default-{instance}.EXT
{hostname}.EXT
{hostname}-{instance}.EXT
{deployment}.EXT
{deployment}-{instance}.EXT
{hostname}-{deployment}.EXT
{hostname}-{deployment}-{instance}.EXT
local.EXT
local-{instance}.EXT
local-{deployment}.EXT
local-{deployment}-{instance}.EXT  
```
- **.EXT** 対応しているフォーマットの拡張子
- **{instance}** Multi-Instnance Deploymentsのためのオプションのインスタンス名文字列
- **{hostname}** サーバーのホスト名。$HOST or $HOSTNAME環境変数の値
- **{deproyment}** デプロイメント名。$NODE_ENV環境変数の値

defalut.EXTは他のファイルでパラメータを上書きしてマージすることができます。

## サンプル

### 準備

```bash
$ mkdir sample-config
$ cd sample-config/
$ mkdir config
$ npm install config
config@1.8.1 node_modules/config
$ npm install js-yaml
js-yaml@3.2.3 node_modules/js-yaml
├── esprima@1.0.4
└── argparse@0.1.15 (underscore@1.4.4, underscore.string@2.3.3)
$ ls
config		node_modules
$ cd config
```

### 設定ファイル作成
configディレクトリ以下に設定ファイルを作成します。

**default.yaml**

```yaml
config:
    fname: "defalut.yaml"
    defaultParam: "default.yaml parameter"
```

**hostname.yaml**

```yaml
config:
    fname: "hostname.yaml"
    hostnameParam: "hostname.yaml parameter"
```

**myDevelopment.yaml**

```yaml
config:
    fname: "myDevelopment.yaml"
    myDevelopmentParam: "myDevelopment.yaml parameter"
```

**hostname-myDevelopment.yaml**

```
config:
    fname: "hostname-development.yaml"
    hostDevParam: "hostname-development.yaml parameter"
```

**local.yaml**

```yaml
config:
    fname: "local.yaml"
    localParam: "local.yaml parameter"
```

### 設定ファイルを読み込む実行スクリプトを作成

**app.js**

```javascript
ConfigFile = require('config');

console.log(ConfigFile.config);

// 全ての設定ファイルで共通項目
console.log("config.fname              : " + ConfigFile.config.fname);
// default.yaml only
console.log("config.defaultParam       : " + ConfigFile.config.defaultParam);
// hostname.yaml only
console.log("config.hostnameParam      : " + ConfigFile.config.hostnameParam);
// myDevelopment.yaml only
console.log("config.myDevelopmentParam : " + ConfigFile.config.myDevelopmentParam);
// hostname-myDevelopment.yaml only
console.log("config.hostDevParam       : " + ConfigFile.config.hostDevParam);
// local.yaml only
console.log("config.localParam         : " + ConfigFile.config.localParam);
```

### 実行する

#### $HOST(or $HOSTNAME)、$NODE_ENV未設定

環境変数を設定しないで事項すると、次の通り。

```bash
$ node app.js
{ fname: 'local.yaml',
  defaultParam: 'default.yaml parameter',
  localParam: 'local.yaml parameter' }
config.fname              : local.yaml
config.defaultParam       : default.yaml parameter
config.hostnameParam      : undefined
config.myDevelopmentParam : undefined
config.hostDevParam       : undefined
config.localParam         : local.yaml parameter
```

default.yaml、local.yamlでマージされている。
両ファイルの共通項目はファイルの読み込み順に則って、local.yamlの値で上書きされる。

#### $HOST環境変数を設定

```
$ export HOST=hostname
$ node app.js
{ fname: 'local.yaml',
  defaultParam: 'default.yaml parameter',
  hostnameParam: 'hostname.yaml parameter',
  localParam: 'local.yaml parameter' }
config.fname              : local.yaml
config.defaultParam       : default.yaml parameter
config.hostnameParam      : hostname.yaml parameter
config.myDevelopmentParam : undefined
config.hostDevParam       : undefined
config.localParam         : local.yaml parameter
```
hostname.yamlが読み込み対象となる。

#### $NODE_ENV環境変数を設定

```bash
$ export HOST=hostname
$ export NODE_ENV=myDevelopment

$ node app.js
{ fname: 'local.yaml',
  defaultParam: 'default.yaml parameter',
  myDevelopmentParam: 'myDevelopment.yaml parameter',
  hostnameParam: 'hostname.yaml parameter',
  hostDevParam: 'hostname-development.yaml parameter',
  localParam: 'local.yaml parameter' }
config.fname              : local.yaml
config.defaultParam       : default.yaml parameter
config.hostnameParam      : hostname.yaml parameter
config.myDevelopmentParam : myDevelopment.yaml parameter
config.hostDevParam       : hostname-development.yaml parameter
config.localParam         : local.yaml parameter
```
$HOSTと$NODE_ENVに設定してファイルの情報が読み込まれている。

### runtime.json

実行後にconfigディレクトリにruntime.jsonファイルができている場合があります。
これは、node-configが自動で設定を反映してくれるファイルです。

詳細は、GitHubにある[node-cofigのWiki](https://github.com/lorenwest/node-config/wiki)を見ると色々書いてあります。（英語ですが・・・）