[Cowfig] Cowfig runtime: yet another config management

前言

專案開發過程中,總會面對在不同階段會有不同的環境配置,至少 developmentproduction 環境必然不同。有時為了測試需求,還額外需要 testing 的環境, 甚至在測試階段時需要不同的數值參數設置以便測試。

管理不同階段需求、不同環境下的設定檔,在 Node.js 開發環節裡已是個老問題, 解法和工具也很多元。Running multi-environment apps in node.js 一文中很清楚地說明相關問題的背景因素並介紹多種不同的環境管理方法。 其中程式中依不同環境變數載入不同設定檔是很快速的作法,但擴充與維護較不易且容易出錯。

該文中也介紹了 Nconf 套件的使用方法。 透過套件管理則是較方便的方法,此類的套件很多,列舉在後。 類似的環境設定管理套件實作方法各有不同、使用上各有優缺點。 而在不同環境設定檔的管理上,支援度普遍相當成熟,問題也少,可以直接套用在生產環境上。

只是因應專案的特殊需求,我仍然重造了輪子,說明如後:

需求與設計

不同環境有不同的伺服器配置檔是難免的。而在我遇到的專案需求裡,種種因素, 導致線上運作數值參數也需存放在設定檔。且營運中需要不關機熱更新線上設定檔的參數內容。 在已知的套件中,都不支援熱更新這種奇異的的功能需求。

面對熱更新的需求,我可以利用現有套件來管理設定檔,另透過程式去處理熱更新機制; 或另外寫一個支援熱更新的設定檔管理套件。 考慮到日後維護方便,新寫了個 Cowfig 來管理設定檔。

每个造轮子的程序员都有自己“不得不造”的理由。比如:

  • 以为自己的需求独一无二,现有的库就是在某个点上满足不了
  • 需要在老轮子上添加新功能,然而老轮子代码难读无人可问,不知道何时能弄明白,看不到结果,容易放弃

Cowfig

Cowfig is yet another configurarion manager for multi-environment. Like other packages, Cowfig organizes hierarchical configurations for your app deployments.

It let you define the default parameters, and overwrite them for different deployment environments (development, qa, staging, production, etc.).

The major different between cowfig and others is the cowfig supports hot-reload configuration file for online services.

Feature

  • Simple - Get started fast
  • Powerful - For multi-node enterprise deployment
  • Flexible - Supporting multiple config file formats
    • cueernt: json, json5
    • in working: yaml, js
  • Hot Reload - Supporting config file hot reload

Usage

Basic Setting

1
2
3
var Cowfig = require('cowfig');
// var config = new Cowfig({initial data}, BASE_PATH, ENV);
var config = new Cowfig({}, config);
  • BASE_PATH: Where your config file located. Default: ./config
  • ENV: Target environment. Default: process.env.NODE_ENV

Load config file

1
2
3
4
var Cowfig = require('cowfig');
var config = new Cowfig({}, 'config');
// config.add(PARA_NAME, FILE_NAME);
config.add('db', 'db');
  • PARA_NAME: Access your config data at config.PARA_NAME.
  • FILE_NAME: Filename to find config file.
    1
    2
    3
    4
    5
    Search priority: 
    config/ENV/FILE_NAME.json > config/ENV/FILE_NAME.json5
    > config/ENV/FILE_NAME/index.json > config/ENV/FILE_NAME/index.json5
    > config/FILE_NAME.json > config/FILE_NAME.json5
    > config/FILE_NAME/index.json > config/FILE_NAME/index.json5

Hot-Reload

1
2
3
4
5
var Cowfig = require('cowfig');
var config = new Cowfig({}, 'config');
config.add('db', 'db');
// config.add(PARA_NAME, FILE_NAME, LIFE_CYCLE);
config.add('app', 'app', {'lifecycle': 'INTERVAL', 'interval': 300}););
  • LIFE_CYCLE
    • FINAL: Default {'lifecycle': 'FINAL'}
    • INTERVAL: {'lifecycle': 'INTERVAL', 'interval': 300})
      Reload your config file every 300 seconds.

Installation

1
npm install kywk/cowfig --save

One More Thing

Comments in JSON file

1
2
3
Suppose you are using JSON to keep configuration files, which you would
like to annotate. Go ahead and insert all the comments you like. Then
pipe it through JSMin before handing it to your JSON parser.

JSON5

Why JSON5?
There are many reasons. But JSON5 makes it JSON format that is ideal for configurations many suggested to use YAML.

  • Great for config files.
  • Comment ( Obviously )
  • Trailing Comma
  • Passing Hex
  • Single-quoted String.

see also: JSON5 Is Pointless and Unimaginative | iLee

Reference

Talking about