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
npm test
轉自:
作者:markmarkmark
連結:https://www.jianshu.com/p/fd4371073e3d