原創: "荊秀網 網頁即時推送 https://xxuyou.com" | 轉載請註明出處 鏈接: "https://blog.xxuyou.com/nodejs thinkjs study config/" 本系列教程以 ThinkJS v2.x 版本( "官網" )為例進行介紹,教程以實際操作為 ...
原創:荊秀網 網頁即時推送 https://xxuyou.com | 轉載請註明出處
鏈接:https://blog.xxuyou.com/nodejs-thinkjs-study-config/
本系列教程以 ThinkJS v2.x 版本(官網)為例進行介紹,教程以實際操作為主。
按模塊定義配置文件
thinkjs 允許開發者直接在 src/common/config/
下麵配置自己的參數,直接增加 js 文件即可,文件名只要符合 json 屬性名要求即可,文件內容遵照如下格式:
// 新增文件 assets.js 鍵入如下內容
'use strict';
export default {
// key: value
};
文件內容只要符合一個 json 對象格式的定義即可。來看一個 log4js 的配置定義:
// log4js.js
'use strict';
export default {
appenders: [
{
type : "console",
category: "console"
},
// 定義一個日誌記錄器
{
type : "dateFile", // 日誌文件類型,可以使用日期作為文件名的占位符
filename : "logs/", // 日誌文件名,可以設置相對路徑或絕對路徑
pattern : "debug/yyyyMMddhh.txt", // 占位符,緊跟在filename後面
absolute : true, // filename是否絕對路徑
alwaysIncludePattern: true, // 文件名是否始終包含占位符
category : "logInfo" // 記錄器名
}
],
levels : {
logInfo: "DEBUG"
} // 設置記錄器的預設顯示級別,低於這個級別的日誌,不會輸出
}
配置文件屬於靜態設置,一般存放不經常變動的設置參數(當然可以在記憶體中更改配置參數的值,下麵會詳細說明)。
另外配置文件是以 ES6 格式導出變數定義的 js 文件,而非 json 文件,這裡有個好處就是可以增加以 // 開頭的註釋說明。
細心的你肯定也發現了:除了 src/common/config
以外,src/home/
模塊下麵也有個 config
文件夾。
一般來說按照配置文件的作用範圍來定義和安排,是比較合理的做法。
比如:所有模塊都會用到的配置放在 src/common/config
下麵比較合適,而僅用於 home 模塊的配置,放在 src/home/config
下麵比較合適。
當配置文件多了之後,我們需要關註一下多個配置文件的載入順序。
配置文件載入順序
官網是這麼描述配置文件載入順序的:
框架預設的配置 -> 項目模式下框架配置 -> 項目公共配置 -> 項目模式下的公共配置 -> 模塊下的配置
先問個問題:這五個配置都指的是哪裡呢?
前兩個可以忽略掉,那是 thinkjs 框架自身的配置設置,通常裡面不會有我們項目會用到的配置參數。
第三個和第四個則是在不同的項目創建模式(項目創建模式參見 Node.js 國產 MVC 框架 ThinkJS 開發 入門(荊秀網))下的預設 config 配置文件夾,位置在:
# normal mode
thinkjs_normal/src/config/*
# module mode
thinkjs_module/src/common/config/*
最後一個是指的在 module mode 下的項目,每個 module 自己的 config,位置在:
thinkjs_module/src/home/config/*
需要註意的是:多個配置文件最終會在 thinkjs 運行時被全部載入,並合併在一起(註意加粗文字)。
所以當存在多個配置文件時,需要註意配置參數的 key(即屬性名)儘量不要重覆,因為按照載入順序,後載入的 key 的值會覆蓋先載入的 key 的值,導致出現不希望的結果。
提示:教程主要講解處於模塊模式(moudule mode)下的開發方式。
自動切換配置文件
前面講到我們可以在 src/common/config
下麵放置配置文件,可以是全部配置參數都放在一個文件中,也可以分散在多個文件中。
有個常見的場景相信每個開發人員都會遇到:
有些配置參數是本地開發時才會用到,有些則是線上運行時才會用到。當開發完成在做持續集成時,配置參數上傳時卻發現開發參數和線上參數混合在一起。。。
thinkjs 在 src/common/config/env/
下提供了三種配置參數環境,分別是 開發配置 development
、生產配置 production
、測試配置 testing
,可以拯救我們的持續集成。
我們可以把項目配置分成三份一樣屬性名的參數,分別放在不同的配置環境中,這樣在本地開發是 thinkjs 自動載入開發配置,持續集成後線上載入的是生產配置,是不是很方便~
開發配置
開發配置文件是:src/common/config/env/development.js
如前所述,開發配置適用於本地開發使用,那麼 thinkjs 是怎麼知道現在是哪個環境呢?
答案是:已經在 package.json 裡面定義好了
{
"scripts": {
"start": "node www/development.js",
"compile": "babel src/ --out-dir app/",
"watch-compile": "node -e \"console.log('<npm run watch-compile> no longer need, use <npm start> command direct.');console.log();\"",
"watch": "npm run watch-compile"
}
}
可以看到 scripts.start
屬性定義了我們直接使用 npm start
時具體執行的實際上是 node www/development.js
命令。
本著打破沙鍋問到底的原則,看看這個文件裡面都有啥:
var thinkjs = require('thinkjs');
var path = require('path');
var rootPath = path.dirname(__dirname);
var instance = new thinkjs({
APP_PATH: rootPath + path.sep + 'app',
RUNTIME_PATH: rootPath + path.sep + 'runtime',
ROOT_PATH: rootPath,
RESOURCE_PATH: __dirname,
env: 'development' // <-- 這裡定義了當前的 thinkjs 實例的運行環境
});
// Build code from src to app directory.
instance.compile({
log: true
});
instance.run();
:-)
生產配置
生產配置文件是:src/common/config/env/production.js
明白了開發配置的原理,也就不難明白生產配置了。
使用 node www/production.js
命令可以告訴 thinkjs 現在運行的是生產環境。
同理,生產配置中的參數名(屬性名)一般與開發配置一樣,只是值不同而已。
比較常見的是資料庫連接,本地開發時連接的是測試庫,而生產環境中連接的是生產庫,不同的地址、用戶、密碼和庫名,這些都是要交給運維人員來管理了。
測試配置
測試配置文件是:src/common/config/env/testing.js
明白了前兩個配置,這個也不難明白~
使用 node www/testing.js
命令可以告訴 thinkjs 現在運行的是測試環境。
定義和使用配置文件
前面其實有介紹過配置文件的分佈原則和定義方法,只要確保不與系統特定配置衝突即可自由定義。
系統特定配置
下麵是 thinkjs 預設的配置文件清單,這些系統特定配置都是有相應的使用場景和參數設置,詳細說明及完整參數詳見:https://thinkjs.org/zh-cn/doc/2.2/config.html#toc-f2a
src/common/config/
├── config.js # 可以放置自己的配置
├── db.js # 資料庫連接
├── env # 運行時配置,下麵會詳述
│ ├── development.js
│ ├── production.js
│ └── testing.js
├── error.js # 錯誤配置
├── hook.js # 鉤子配置
├── locale # 多語言版配置
│ └── en.js
├── session.js
└── view.js # 視圖文件配置
自定義配置
一般做法是使用帶有層級的配置定義來組織配置參數(當然你一定要把全部參數都放在根下麵也不是不可以),參見如下配置:
// development.js
'use strict';
export default {
site_name: "",
site_title: "",
site_keywords: "",
site_description: "",
db: { // 這裡的配置替代 db.js
type : 'mysql',
log_sql: true, //是否記錄 sql 語句
adapter: {
mysql: {
host : '127.0.0.1',
port : '3306',
database: '',
user : '',
password: '',
prefix : 'thinkjs_',
encoding: 'utf8'
}
}
},
jwt: { // 第三方模塊的公共定義
options: {
algorithm: 'HS128',
expiresIn: '7d'
}
},
pay: {
// 定義與線上支付介面相關的參數
},
backend: {
// 定義管理後臺相關的參數
},
home: {
// 定義前端網站相關的參數
},
rest: {
// 定義 REST API 相關的參數
},
task: {
// 定義 crond 相關的參數
}
};
配置參數按照層次組織之後,需要註意的一點是:獲取配置的時候,不能無限制的 this.config(參數.參數.參數.參數)
下去,詳見下麵讀取配置的幾種方式描述。
幾種讀取配置的方式
配置文件定義之後,需要在項目運行的特別業務中讀取(也可以設置)到配置參數的值,根據讀取配置的位置的不同,thinkjs 提供了以下幾種讀取方式。
this.config()
這是使用率最高的讀取配置方法,絕大多數位置都可以使用此方法來讀取配置,比如 controller
logic
model
service
middleware
等地方。
// 配置 development.js
let dbOpt = this.config('db');
let jwtOpt = this.config('jwt.options');
這裡有一點需要註意:thinkjs 只能解析兩層配置參數,超過的層級不予解析(源碼中寫死了僅返回兩層)。
// 配置 development.js
let jwtOpt = this.config('jwt.options');
console.log(jwtOpt);
// 讀取成功,列印:
// {
// options: {
// algorithm: 'HS128',
// expiresIn: '7d'
// }
// }
let jwtOptAlg = this.config('jwt.options.algorithm');
console.log(jwtOptAlg);
// 超過三層,讀取失敗,只能讀取到兩層內容,列印:
// {
// options: {
// algorithm: 'HS128',
// expiresIn: '7d'
// }
// }
jwtOptAlg = jwtOpt['algorithm'];
console.log(jwtOptAlg);
// 正確的讀取方式,列印:
// HS128
think.config()
think.config 方法可以:
- 無須考慮當前位置來讀取配置參數(其內部運行方式類似 this.config )
- 跨模塊讀取配置參數
對於前者可以無須思考當前所在的模塊,更自由的讀取配置參數。
對於後者則對開發多模塊協作有著比較重要的意義,配置參數只有一份,不可能向不同的模塊複製相同的配置,因此需要“一處配置、多處可用”。因此無須考慮“我在哪裡讀取配置”,只要考慮“我要讀取哪裡的配置”即可。
// 配置文件:src/home/config/assets.js
let siteName = think.config('assets.site_name', undefined, 'home');
方法的第二個參數設置為 undefined
是為了避免將讀取動作變為設置動作。
方法的第三個參數標明瞭這個配置參數在哪個模塊下麵,一旦給定此參數,thinkjs 會認為 src/home/config/
下麵的配置是你需要讀取的目標。
http.config()
http.config 方法實質上是 think.config() 的一個別名,可以讀取和設置配置參數。
避免踩坑之正確讀取參數
如果不能理解 thinkjs 設計配置文件讀取策略的情況下,會無意中踩坑,如下便是一個例子,代碼說話。
假設有兩個配置文件 src/common/config/assets.js
和 src/home/config/assets.js
,其中有著一樣的屬性名:
// src/common/config/assets.js
export default {
"site_title": "my site"
};
// src/home/config/assets.js
export default {
"site_title": "my test"
};
// 兩個配置參數屬性名一樣的情況下
// 使用不同的讀取方式
// 註意 config 方法的上下文對象的不同
// 會導致讀取的結果的不同
// src/home/controller/index.js
let assets = this.config('assets');
let siteTitle = assets['site_title'];
console.log('siteTitle is: ', siteTitle);
// 列印:
// my test
// src/home/controller/index.js
let assets = think.config('assets', undefined, 'common');
let siteTitle = assets['site_title'];
console.log('siteTitle is: ', siteTitle);
// 列印:
// my site
明白了 thinkjs 配置文件載入順序,就不會對上面發生的情況驚訝了~
如果你實在懶得去思考 this.config
和 think.config
兩者的分別,建議你乾脆使用後者,當讀取參數只傳入第一個參數時,它的表現與前者一致。這樣貌似更有利於代碼的維護~
避免踩坑之動態修改配置參數
當讀取到了配置參數後,當然是可以動態修改其為新的值,以讓後續的處理都讀到新的值。動態修改方法也很簡單:config 方法的第二個參數就是給定的新值。
let siteTitle = this.config('assets.site_title');
console.log(siteTitle);
// 列印:
// my test
this.config('assets.site_title', 'test 123');
siteTitle = this.config('assets.site_title');
console.log(siteTitle);
// 列印:
// test 123
上面的動態修改方法其實平淡無奇,來看看更有趣的修改方法,如下:
let siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// 列印:
// {
// name: 'xxuyou.com',
// email: '[email protected]'
// }
siteAuthor['name'] = 'cap';
siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// 列印:
// {
// name: 'cap',
// email: '[email protected]'
// }
假如上面的代碼片段修改一下寫法,就可以得到預期的效果,如下:
let siteAuthor = think.extend({}, this.config('assets.site_author')); // <-- 不同點在這裡
console.log(siteAuthor);
// 列印:
// {
// name: 'xxuyou.com',
// email: '[email protected]'
// }
siteAuthor['name'] = 'cap';
siteAuthor = this.config('assets.site_author');
console.log(siteAuthor);
// 列印:
// {
// name: 'xxuyou.com',
// email: '[email protected]'
// }
暫且不管這個 think.extend
是何方神聖,為啥修改等號左邊的變數的效果跟直接修改配置方法是一樣的?
原因其實很簡單:
- thinkjs 內部會緩存配置參數。
- 配置參數的值是一個
Object
而不是String
。
OK~
語言包
語言包其實本身可以作為 i18n 來單獨描述,不過由於國際化在實際開發甚至架構過程中極少涉及到,因此這裡簡略描述。
src/config/locale/en.js
系統預設的英語語言環境,其中定義了相關的語言模版。
src/config/locale/zh-CN.js
規範起見,建議手工設立這個語言模版文件,並修改 src/common/config/local.js
中的 default
參數為 zh-CN
即可啟用本語言模版。
done~
上一篇:Node.js 國產 MVC 框架 ThinkJS 開發 入門(荊秀網)
下一篇:Node.js 國產 MVC 框架 ThinkJS 開發 controller 篇(荊秀網)
原創:荊秀網 網頁即時推送 https://xxuyou.com | 轉載請註明出處
鏈接:https://blog.xxuyou.com/nodejs-thinkjs-study-config/