Egg Config 配置

2020-02-06 14:10 更新

框架提供了強(qiáng)大且可擴(kuò)展的配置功能,可以自動(dòng)合并應(yīng)用、插件、框架的配置,按順序覆蓋,且可以根據(jù)環(huán)境維護(hù)不同的配置。合并后的配置可直接從 app.config 獲取。

配置的管理有多種方案,以下列一些常見(jiàn)的方案

  1. 使用平臺(tái)管理配置,應(yīng)用構(gòu)建時(shí)將當(dāng)前環(huán)境的配置放入包內(nèi),啟動(dòng)時(shí)指定該配置。但應(yīng)用就無(wú)法一次構(gòu)建多次部署,而且本地開(kāi)發(fā)環(huán)境想使用配置會(huì)變的很麻煩。
  2. 使用平臺(tái)管理配置,在啟動(dòng)時(shí)將當(dāng)前環(huán)境的配置通過(guò)環(huán)境變量傳入,這是比較優(yōu)雅的方式,但框架對(duì)運(yùn)維的要求會(huì)比較高,需要部署平臺(tái)支持,同時(shí)開(kāi)發(fā)環(huán)境也有相同痛點(diǎn)。
  3. 使用代碼管理配置,在代碼中添加多個(gè)環(huán)境的配置,在啟動(dòng)時(shí)傳入當(dāng)前環(huán)境的參數(shù)即可。但無(wú)法全局配置,必須修改代碼。

我們選擇了最后一種配置方案,配置即代碼,配置的變更也應(yīng)該經(jīng)過(guò) review 后才能發(fā)布。應(yīng)用包本身是可以部署在多個(gè)環(huán)境的,只需要指定運(yùn)行環(huán)境即可。

多環(huán)境配置

框架支持根據(jù)環(huán)境來(lái)加載配置,定義多個(gè)環(huán)境的配置文件,具體環(huán)境請(qǐng)查看運(yùn)行環(huán)境配置

config
|- config.default.js
|- config.prod.js
|- config.unittest.js
`- config.local.js

config.default.js 為默認(rèn)的配置文件,所有環(huán)境都會(huì)加載這個(gè)配置文件,一般也會(huì)作為開(kāi)發(fā)環(huán)境的默認(rèn)配置文件。

當(dāng)指定 env 時(shí)會(huì)同時(shí)加載對(duì)應(yīng)的配置文件,并覆蓋默認(rèn)配置文件的同名配置。如 prod 環(huán)境會(huì)加載 config.prod.js 和 config.default.js 文件,config.prod.js 會(huì)覆蓋 config.default.js 的同名配置。

配置寫(xiě)法

配置文件返回的是一個(gè) object 對(duì)象,可以覆蓋框架的一些配置,應(yīng)用也可以將自己業(yè)務(wù)的配置放到這里方便管理。

// 配置 logger 文件的目錄,logger 默認(rèn)配置由框架提供
module.exports = {
logger: {
dir: '/home/admin/logs/demoapp',
},
};

配置文件也可以簡(jiǎn)化的寫(xiě)成 exports.key = value 形式

exports.keys = 'my-cookie-secret-key';
exports.logger = {
level: 'DEBUG',
};

配置文件也可以返回一個(gè) function,可以接受 appInfo 參數(shù)

// 將 logger 目錄放到代碼目錄下
const path = require('path');
module.exports = appInfo => {
return {
logger: {
dir: path.join(appInfo.baseDir, 'logs'),
},
};
};

內(nèi)置的 appInfo 有

appInfo說(shuō)明
pkgpackage.json
name應(yīng)用名,同 pkg.name
baseDir應(yīng)用代碼的目錄
HOME用戶目錄,如 admin 賬戶為 /home/admin
root應(yīng)用根目錄,只有在 local 和 unittest 環(huán)境下為 baseDir,其他都為 HOME。

appInfo.root 是一個(gè)優(yōu)雅的適配,比如在服務(wù)器環(huán)境我們會(huì)使用 /home/admin/logs 作為日志目錄,而本地開(kāi)發(fā)時(shí)又不想污染用戶目錄,這樣的適配就很好解決這個(gè)問(wèn)題。

請(qǐng)根據(jù)具體場(chǎng)合選擇合適的寫(xiě)法,但請(qǐng)確保沒(méi)有寫(xiě)出以下代碼:

// config/config.default.js
exports.someKeys = 'abc';
module.exports = appInfo => {
const config = {};
config.keys = '123456';
return config;
};

配置加載順序

應(yīng)用、插件、框架都可以定義這些配置,而且目錄結(jié)構(gòu)都是一致的,但存在優(yōu)先級(jí)(應(yīng)用 > 框架 > 插件),相對(duì)于此運(yùn)行環(huán)境的優(yōu)先級(jí)會(huì)更高。

比如在 prod 環(huán)境加載一個(gè)配置的加載順序如下,后加載的會(huì)覆蓋前面的同名配置。

-> 插件 config.default.js
-> 框架 config.default.js
-> 應(yīng)用 config.default.js
-> 插件 config.prod.js
-> 框架 config.prod.js
-> 應(yīng)用 config.prod.js

注意:插件之間也會(huì)有加載順序,但大致順序類似,具體邏輯可查看加載器

合并規(guī)則

配置的合并使用 extend2 模塊進(jìn)行深度拷貝,extend2 fork 自 extend,處理數(shù)組時(shí)會(huì)存在差異。

const a = {
arr: [ 1, 2 ],
};
const b = {
arr: [ 3 ],
};
extend(true, a, b);
// => { arr: [ 3 ] }

根據(jù)上面的例子,框架直接覆蓋數(shù)組而不是進(jìn)行合并。

配置結(jié)果

框架在啟動(dòng)時(shí)會(huì)把合并后的最終配置 dump 到 run/application_config.json(worker 進(jìn)程)和 run/agent_config.json(agent 進(jìn)程)中,可以用來(lái)分析問(wèn)題。

配置文件中會(huì)隱藏一些字段,主要包括兩類:

  • 如密碼、密鑰等安全字段,這里可以通過(guò) config.dump.ignore 配置,必須是 Set 類型,查看默認(rèn)配置。
  • 如函數(shù)、Buffer 等類型,JSON.stringify 后的內(nèi)容特別大

還會(huì)生成 run/application_config_meta.json(worker 進(jìn)程)和 run/agent_config_meta.json(agent 進(jìn)程)文件,用來(lái)排查屬性的來(lái)源,如

{
"logger": {
"dir": "/path/to/config/config.default.js"
}
}


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)