使用 node-config 在 Node.js 中建立配置檔案

杭州程式設計師張張發表於2022-01-14

管理跨不同環境的多個配置檔案可能具有挑戰性,並且有多種工具正試圖用不同的方法解決這個問題。但是,在本文中,我們將學習如何使用 node-config 跨不同部署環境建立和管理 Node.js 配置檔案。

node-config是什麼?

Node-config允許你在你的Node應用程式中為不同的部署環境建立配置檔案。有了它,你可以定義一個你打算跨環境重複使用的預設配置檔案,然後將預設配置擴充套件到其他環境,如開發、暫存等。

你可以使用一些臨時的命令列引數來覆蓋這些引數,比如在你的命令列引數中加入NODE_ENV=development

Node-config使建立和管理一個在所有部署環境中共享的一致的配置介面變得更加容易。

為了更好地理解如何設定這個配置,讓我們使用一個Node應用樣本。首先,在你的終端上執行下面的命令來克隆這個資源庫,或者從這裡下載並解壓它。

git clone https://github.com/ezesundayeze/node-env-sample

要安裝 Node 依賴項,請執行:

npm install

設定 node-config

因為node-config是一個npm包,我們可以通過執行這些命令中的任何一個來用npm或yarn安裝它。

npm install config

或者

yarn add config

支援的 node-config 副檔名

Node-config 支援許多副檔名。在釋出時,當前版本的 node-config (3.3.6) 支援以下擴充套件:

- .json
- .json5
- .hjson
- .yaml or .yml
- .coffee
- .js
- .cson
- .properties
- .toml
- .ts
- .xml

這意味著你可以用任何一個支援的擴充套件來建立你的配置檔案,但為你的專案選擇一個擴充套件並在整個構建過程中堅持使用它是有意義的。

在本教程中,我們將使用 .json 副檔名。

建立預設環境變數

建立一個 config 目錄並向其中新增一個 config/default.json 檔案。這將是預設配置檔案,並將包含所有預設環境變數。

在我們的示例應用程式中它應該是這樣的:

config/default.json

{
  "server": {
    "host": "localhost",
    "port": 0,
  }
}

我們將在我們的應用程式中通過匯入 config 和使用 get 方法訪問變數來訪問它。

const config = require('config');
const port = config.get('server.port');
const host = config.get('server.host');

讓我們建立一個 server.js 檔案並新增以下程式碼。

const express = require('express');
const config = require('config');
const app = express();
const port = config.get('server.port');
const host = config.get('server.host');

app.get('/', (req, res) => {
  res.send('Hello World');
});
const server = app.listen(port, host, (err) => {
  if (err) {
    console.log(err);
    process.exit(1);
  }
  console.log(`Server is running on ${host}:${server.address().port}`);
});

你可以在你的應用程式的其他部分以類似的方式使用node-config。

擴充套件預設配置檔案

你可以通過建立其他配置檔案來擴充套件預設的配置檔案。例如,你可以為開發、生產、QA、暫存、本地等建立配置檔案。讓我們來介紹一下我們將在我們的應用程式中使用的配置檔案的主要型別。

本地配置檔案

建立本地配置檔案是為了覆蓋你的配置檔案的部署版本。例如,對於你的開發部署,你可以有一個 local-development.json 檔案來儲存你所有的本地開發配置——它反映了你在部署的開發環境中期望的那種行為。

因此,你可以擁有這樣的東西:

local-{instance}.EXT
local-{deployment}.EXT
local-{deployment}-{instance}.EXT

短主機名和完整主機名

你也可以使用簡短和完整的主機名來定義你在特定平臺上的配置檔案,以防你要在多個例項上進行部署。例如,您可以有一個 {short_hostname},它將代表您的伺服器名稱直到第一個點。如果您的主機名是 demo.example.com,則配置可以是 demo.EXT (demo.json)

此外,如果您的 {full_hostname} 是您的整個伺服器名稱,則您可以在 {short_hostname} 與其他機器發生衝突時使用它。因此,在您的主機名是 demo.example.com 的情況下,您的配置檔名將是 demo.example.com.json

自定義配置檔案

你可能還想建立一個自定義的配置檔案來容納一些環境變數的覆蓋。Node-config提供了對配置檔案型別的支援,你可以用 custom-environment-variables.EXT(custom-environment-variables.json)的名字來定義。

測試配置值

如果您的環境變數沒有設定,使用它們的服務就會中斷。所以,你應該確保你的環境變數已經過測試。Node-config 提供了多個實用程式,其中之一是 config.has() 方法,它允許您驗證是否設定了環境變數。

你可以建立一個測試檔案或將其新增到你的預提交鉤子中,以確保你的配置檔案都已設定好。

以下是如何使用 config.has() 檢查配置變數是否存在的示例:

if (config.has('dbConfig')) { 
... 
}

你也可以在你的Jest測試中使用它,像這樣:

const config = require('config');
test('Server config exist', () => {
  expect(config.has("server")).toBe(true);
});
test('Default config exist', () => {
  expect(config.has("server.port")).toBe(true);
  expect(config.has("server.host")).toBe(true);
});

使用命令列重寫

使用命令列覆蓋允許你從你的終端或命令列中即時指定配置引數。你需要在啟動應用程式時通過指定 NODE_CONFIG='{...}' 命令來設定配置,引數必須是JSON字串的格式。

下面是一個例子:

NODE_CONFIG='{"server": {"host":"192.168.43.13", "port":"3030"}}' npm run dev

JSON 值周圍的單引號允許您安全地使用雙引號。在某些情況下,根據您的作業系統,您可能需要對某些字元進行轉義。您還可以使用命令列匯出來避免一直鍵入命令。

在你的終端上執行下面的命令將覆蓋你的伺服器的主機和埠或你選擇覆蓋的任何其他配置。

export NODE_CONFIG='{"server": {"host":"192.168.43.13", "port":"3030"}}'

如果您更喜歡使用 JavaScript,可以在呼叫配置庫之前將其新增到您的伺服器檔案中,如下所示:

const express = require('express');
process.env.NODE_CONFIG = '{"server": {"host":"localhost", "port":"3030"}}';
const config = require('config');

訣竅是在配置載入之前將 NODE_CONFIG 變數設定為 JSON 字串。

發生這種情況是因為命令列覆蓋優先於所有其他型別的覆蓋。下面是一些在使用 node-config 時不能用作環境變數的保留字,因為庫提供了它們的實現,可能會與您的實現衝突。

get
has
util
getConfigSources
makeHidden
makeImmutable
setModuleDefaults
watch 
_attachProtoDeep
_cloneDeep
_diffDeep

這不是一個詳盡的列表,所以一定要檢視文件。

有一些外掛可以讓你高效地使用 node-config 和 Docker 來管理金鑰,一個外掛可以讓你自動重新載入 node-config(你可能已經知道,配置不會在檔案更改時自動載入),以及允許您取消快取您的配置(uncache your config)變數的外掛。

總結

使用 node-config 時,有無數種方法可以配置您的 Node 應用程式。有了它,您可以輕鬆管理您的配置檔案並根據需要擴充套件它們,從而在您的專案中實現最大的靈活性、可靠性和一致性。謝謝閱讀。

相關文章