1. 程式人生 > >Node.js 專案中的配置檔案

Node.js 專案中的配置檔案

在使用 Node.js 編寫一個完整的專案時,程式中往往需要用到一些可配置的變數,從而使得程式能在不同的環境中執行。

1.通過環境變數指定配置

環境變數(environment variables)一般是指在作業系統中用來指定作業系統執行環境的一些引數,如:臨時資料夾位置和系統資料夾位置等。比如HOME表示當前使用者的根目錄,TMPDIR表示系統臨時目錄等,我們可以通過設定一些特定的環境變數,程式在啟動時可以讀取這些環境變數並做相應的初始化動作。

在 Node.js 中可以通過process.env來訪問當前的環境變數資訊,比如:

{PATH:'/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',TMPDIR:'/var/folders/rs/g4wqpvvj7bj08t35dxvfm0rr0000gn/T/',LOGNAME:'glen',XPC_FLAGS:'0x0',HOME:'/Users/glen',TERM:'xterm-256color',COLORFGBG:'7;0',USER:'glen',ITERM_PROFILE:'Glen',TERM_PROGRAM:'iTerm.app',XPC_SERVICE_NAME:'0',SHELL:'/bin/zsh',ITERM_SESSION_ID:'w0t4p0',PWD:'/Users/glen/work',__CF_USER_TEXT_ENCODING:'0x1F5:0x0:0x0',LC_CTYPE:'UTF-8',SHLVL:'1',OLDPWD:'/Users/glen/work',ZSH:'/Users/glen/.oh-my-zsh',PAGER:'less',LESS:'-R',LSCOLORS:'Gxfxcxdxbxegedabagacad',AUTOJUMP_SOURCED:'1',AUTOJUMP_ERROR_PATH:'/Users/glen/Library/autojump/errors.log',RUST_SRC_PATH:'/Users/glen/work/source/rust/src',_:'/usr/local/bin/node'}

2.設定環境變數

環境變數的名字一般為大寫,多個單詞之間可通過下劃線來連線。

Windows 系統下可通過set命令來設定環境變數,比如:

$set HELLO_MSG="Hello, world!"

Linux 系統下可通過export命令來設定,比如:

$ export HELLO_MSG="Hello, world!"

在 Node.js 中讀取環境變數

建立檔案1.js,程式碼如下:

console.log(process.env.HELLO_MSG);

然後在命令列中執行:

$ export HELLO_MSG="Hello, world"&& node1.js

控制檯將輸出Hello, world,即我們啟動程式時給環境變數HELLO_MSG設定的值。

3.通過配置檔案指定配置

一些規模較小的專案往往會通過單一的配置檔案來儲存其配置,比如 CNode 中文社群的開源專案nodeclub在啟動時會載入檔案config.js,該檔案的大概結構如下:

var config = {

//debug 為true時,用於本地除錯

debug:true,

name:'Nodeclub',//社群名字

description:'CNode:Node.js專業中文社群',//社群的描述

keywords:'nodejs, node, express, connect, socket.io',

//其他配置項

...};

module.exports = config;

在程式啟動的時候,可以使用require()來載入此檔案,得到一個物件,然後通過此物件的屬性來讀取相應的配置資訊:

// 載入配置檔案

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

// 以下為使用到配置的部分程式碼:

if(!config.debug && config.oneapm_key) {

require('oneapm');

}

app.use(session({

secret: config.session_secret,

store:newRedisStore({    port: config.redis_port,    host: config.redis_host,  }),

resave:true,

saveUninitialized:true,

}))

app.listen(config.port,function(){

 logger.log('NodeClub listening on port', config.port); 

logger.log('God bless love....');

logger.log('You can debug your app with http://'+ config.hostname +':'+ config.port);

logger.log('');

});

使用配置檔案與使用環境變數來指定配置相比,配置檔案的可讀性更強,可以表示一些更復雜的結構,而使用環境變數一般只限於key=value的形式。但在配置項數量較少時,使用環境變數會更簡單,比如專案中只需要配置一個監聽埠,可以簡單使用export PORT=3000 && node app.js命令來啟動程式,而不需要單獨建立一個配置檔案。大多數時候往往會結合這兩種方式來進行,下文講詳細講解。

4.其他配置檔案格式

一般為了方便,在 Node.js 專案中會習慣使用.js檔案格式,它的好處是可以使用通過程式來動態生成一些配置項,比如 nodeclub 的其中一個配置項:

var config = {

// 檔案上傳配置

// 注:如果填寫 qn_access,則會上傳到 7牛,以下配置無效

upload: {  

             path: path.join(__dirname, 'public/upload/'),   

             url: '/public/upload/' 

        },
}

其中使用到了path.join()和__dirname來生成upload.path。

JSON格式

另外,我們也可以使用JSON格式的配置檔案,比如檔案config.json:

{

"debug":true,

"name":"Nodeclub",

"description":"CNode:Node.js專業中文社群",

"keywords":"nodejs, node, express, connect, socket.io"

}

在程式中可以通過以下方式來載入JSON檔案配置:

// 通過require()函式

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

// 讀取檔案並使用JSON.parse()解析

var fs =require('fs');

var config =JSON.parse(fs.readFileSync('./config.json').toString());

根據執行環境選擇不同的配置

大多數情況下,程式在本地開發環境和生產環境中的配置資訊是不一樣的,比如開發時連線到的資料庫裡面的資料是模擬出來的,而生產環境要連線到實際的資料庫上,因此我們需要讓程式能根據不同的執行環境來載入不同的配置檔案。

5.使用 config 模組來讀取配置

config模組是 NPM 上下載量最高的 Node.js 配置檔案管理模組,其實現原理與上文中介紹的方法大同小異,在實際開發中我們可以考慮使用這個現成的模組。下面將介紹此模組的簡單使用方法。

config模組通過環境變數NODE_CONFIG_DIR來指定配置檔案所在的目錄,預設為./config(即當前執行目錄下的config目錄),通過環境變數NODE_ENV來指定當前的執行環境版本。

配置檔案使用 JSON 格式,模組載入後,會首先載入預設的配置檔案${NODE_CONFIG_DIR}/default.json,再載入檔案${NODE_CONFIG_DIR}/${NODE_ENV}.json,如果配置項有衝突則覆蓋預設的配置。

比如我們新建預設配置檔案config/default.json:

{

//Customer module configs

"Customer": {

"dbConfig": {

"host":"localhost",

"port":5984,

"dbName":"customers"

},

"credit": {"initialLimit":100,

//Set low for development

"initialDays":1

}

}

}

再新建production環境配置檔案config/production.json:

{

"Customer":

{

"dbConfig": {"host":"prod-db-server"},

"credit": {"initialDays":30}

}

}

再新建測試檔案1.js:

var config= require('config');

console.log(config);

執行程式,可看到其輸出的結果為預設的配置:

{Customer:

{dbConfig: {host:'prod-db-server',port:5984,dbName:'customers'},

credit: {initialLimit:100,initialDays:30} } }

假如要使用production的配置,則使用以下命令啟動:

$ export NODE_ENV=production && node1.js

則其輸出將是如下結果:

{Customer:  {dbConfig: {host:'prod-db-server',port:5984,dbName:'customers'},credit: {initialLimit:100,initialDays:30} } }

在production.json檔案中,重新定義了Customer.dbConfig.host和Customer.credit.initialDays這兩個配置項,所以在production環境中僅這兩項被覆蓋為新的值,而其他配置項則使用default.json中指定的值。

6.config-lite模組配置

不管是小專案還是大專案,將配置與程式碼分離是一個非常好的做法。我們通常將配置寫到一個配置檔案裡,如 config.js 或 config.json

,並放到專案的根目錄下。但通常我們都會有許多環境,如本地開發環境、測試環境和線上環境等,不同的環境的配置不同,我們不可能每次部署時都要去修改引用

config.test.js 或者 config.production.js。config-lite 模組正是你需要的

config-lite是一個輕量的讀取配置檔案的模組。config-lite 會根據環境變數(NODE_ENV)的不同從當前執行程序目錄下的 config 目錄載入不同的配置檔案。如果不設定NODE_ENV,則讀取預設的 default 配置檔案,如果設定了NODE_ENV,則會合並指定的配置檔案和 default 配置檔案作為配置,config-lite 支援 .js、.json、.node、.yml、.yaml 字尾的檔案。

如果程式以NODE_ENV=test node app啟動,則通過require('config-lite')會依次降級查詢config/test.js、config/test.json、config/test.node、config/test.yml、config/test.yaml併合並 default 配置; 如果程式以NODE_ENV=production node app啟動,則通過require('config-lite')會依次降級查詢config/production.js、config/production.json、config/production.node、config/production.yml、config/production.yaml併合並 default 配置。

config-lite

A super simple & flexible & useful config module.

Install

npm i config-lite --save

Usage

var config = require('config-lite');

By default,require('config-lite')will bubbling findconfig(or custom) directory fromprocess.cwd().

See test. After v1.0.0, support yaml config file.

example

config/default.js

module.exports = 'default';

config/test.js

module.exports = 'test';

config/production.js

module.exports = 'production';

\====================================

node app

require('config-lite'); //=> 'default'

NODE_ENV=test node app

require('config-lite'); //=> 'test'

NODE_ENV=production node app

require('config-lite'); //=> 'production'

or:

NODE_ENV=production node app --host=localhost --port=3000

Test

npm test


轉自:
作者:markmarkmark
連結:https://www.jianshu.com/p/fd4371073e3d