javascript
Node.js 国产 MVC 框架 ThinkJS 开发 config 篇
原創(chuàng):荊秀網(wǎng) 網(wǎng)頁即時推送 https://xxuyou.com | 轉(zhuǎn)載請注明出處
鏈接:https://blog.xxuyou.com/nodejs-thinkjs-study-config/
本系列教程以 ThinkJS v2.x 版本(官網(wǎng))為例進行介紹,教程以實際操作為主。
按模塊定義配置文件
thinkjs 允許開發(fā)者直接在 src/common/config/ 下面配置自己的參數(shù),直接增加 js 文件即可,文件名只要符合 json 屬性名要求即可,文件內(nèi)容遵照如下格式:
// 新增文件 assets.js 鍵入如下內(nèi)容 'use strict'; export default {// key: value };文件內(nèi)容只要符合一個 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"} // 設置記錄器的默認顯示級別,低于這個級別的日志,不會輸出 }配置文件屬于靜態(tài)設置,一般存放不經(jīng)常變動的設置參數(shù)(當然可以在內(nèi)存中更改配置參數(shù)的值,下面會詳細說明)。
另外配置文件是以 ES6 格式導出變量定義的 js 文件,而非 json 文件,這里有個好處就是可以增加以 // 開頭的注釋說明。
細心的你肯定也發(fā)現(xiàn)了:除了 src/common/config 以外,src/home/ 模塊下面也有個 config 文件夾。
一般來說按照配置文件的作用范圍來定義和安排,是比較合理的做法。
比如:所有模塊都會用到的配置放在 src/common/config 下面比較合適,而僅用于 home 模塊的配置,放在 src/home/config 下面比較合適。
當配置文件多了之后,我們需要關(guān)注一下多個配置文件的加載順序。
配置文件加載順序
官網(wǎng)是這么描述配置文件加載順序的:
框架默認的配置 -> 項目模式下框架配置 -> 項目公共配置 -> 項目模式下的公共配置 -> 模塊下的配置
先問個問題:這五個配置都指的是哪里呢?
前兩個可以忽略掉,那是 thinkjs 框架自身的配置設置,通常里面不會有我們項目會用到的配置參數(shù)。
第三個和第四個則是在不同的項目創(chuàng)建模式(項目創(chuàng)建模式參見 Node.js 國產(chǎn) MVC 框架 ThinkJS 開發(fā) 入門(荊秀網(wǎng)))下的默認 config 配置文件夾,位置在:
# normal mode thinkjs_normal/src/config/* # module mode thinkjs_module/src/common/config/*最后一個是指的在 module mode 下的項目,每個 module 自己的 config,位置在:
thinkjs_module/src/home/config/*需要注意的是:多個配置文件最終會在 thinkjs 運行時被全部加載,并合并在一起(注意加粗文字)。
所以當存在多個配置文件時,需要注意配置參數(shù)的 key(即屬性名)盡量不要重復,因為按照加載順序,后加載的 key 的值會覆蓋先加載的 key 的值,導致出現(xiàn)不希望的結(jié)果。
提示:教程主要講解處于模塊模式(moudule mode)下的開發(fā)方式。
自動切換配置文件
前面講到我們可以在 src/common/config 下面放置配置文件,可以是全部配置參數(shù)都放在一個文件中,也可以分散在多個文件中。
有個常見的場景相信每個開發(fā)人員都會遇到:
有些配置參數(shù)是本地開發(fā)時才會用到,有些則是線上運行時才會用到。當開發(fā)完成在做持續(xù)集成時,配置參數(shù)上傳時卻發(fā)現(xiàn)開發(fā)參數(shù)和線上參數(shù)混合在一起。。。
thinkjs 在 src/common/config/env/ 下提供了三種配置參數(shù)環(huán)境,分別是 開發(fā)配置 development、生產(chǎn)配置 production、測試配置 testing,可以拯救我們的持續(xù)集成。
我們可以把項目配置分成三份一樣屬性名的參數(shù),分別放在不同的配置環(huán)境中,這樣在本地開發(fā)是 thinkjs 自動加載開發(fā)配置,持續(xù)集成后線上加載的是生產(chǎn)配置,是不是很方便~
開發(fā)配置
開發(fā)配置文件是:src/common/config/env/development.js
如前所述,開發(fā)配置適用于本地開發(fā)使用,那么 thinkjs 是怎么知道現(xiàn)在是哪個環(huán)境呢?
答案是:已經(jīng)在 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 時具體執(zhí)行的實際上是 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 實例的運行環(huán)境 });// Build code from src to app directory. instance.compile({log: true });instance.run();:-)
生產(chǎn)配置
生產(chǎn)配置文件是:src/common/config/env/production.js
明白了開發(fā)配置的原理,也就不難明白生產(chǎn)配置了。
使用 node www/production.js 命令可以告訴 thinkjs 現(xiàn)在運行的是生產(chǎn)環(huán)境。
同理,生產(chǎn)配置中的參數(shù)名(屬性名)一般與開發(fā)配置一樣,只是值不同而已。
比較常見的是數(shù)據(jù)庫連接,本地開發(fā)時連接的是測試庫,而生產(chǎn)環(huán)境中連接的是生產(chǎn)庫,不同的地址、用戶、密碼和庫名,這些都是要交給運維人員來管理了。
測試配置
測試配置文件是:src/common/config/env/testing.js
明白了前兩個配置,這個也不難明白~
使用 node www/testing.js 命令可以告訴 thinkjs 現(xiàn)在運行的是測試環(huán)境。
定義和使用配置文件
前面其實有介紹過配置文件的分布原則和定義方法,只要確保不與系統(tǒng)特定配置沖突即可自由定義。
系統(tǒng)特定配置
下面是 thinkjs 默認的配置文件清單,這些系統(tǒng)特定配置都是有相應的使用場景和參數(shù)設置,詳細說明及完整參數(shù)詳見:https://thinkjs.org/zh-cn/doc/2.2/config.html#toc-f2a
src/common/config/ ├── config.js # 可以放置自己的配置 ├── db.js # 數(shù)據(jù)庫連接 ├── env # 運行時配置,下面會詳述 │?? ├── development.js │?? ├── production.js │?? └── testing.js ├── error.js # 錯誤配置 ├── hook.js # 鉤子配置 ├── locale # 多語言版配置 │?? └── en.js ├── session.js └── view.js # 視圖文件配置自定義配置
一般做法是使用帶有層級的配置定義來組織配置參數(shù)(當然你一定要把全部參數(shù)都放在根下面也不是不可以),參見如下配置:
// development.js 'use strict'; export default {site_name: "",site_title: "",site_keywords: "",site_description: "",db: { // 這里的配置替代 db.jstype : '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: {// 定義與在線支付接口相關(guān)的參數(shù)},backend: {// 定義管理后臺相關(guān)的參數(shù)},home: {// 定義前端網(wǎng)站相關(guān)的參數(shù)},rest: {// 定義 REST API 相關(guān)的參數(shù)},task: {// 定義 crond 相關(guān)的參數(shù)} };配置參數(shù)按照層次組織之后,需要注意的一點是:獲取配置的時候,不能無限制的 this.config(參數(shù).參數(shù).參數(shù).參數(shù)) 下去,詳見下面讀取配置的幾種方式描述。
幾種讀取配置的方式
配置文件定義之后,需要在項目運行的特別業(yè)務中讀取(也可以設置)到配置參數(shù)的值,根據(jù)讀取配置的位置的不同,thinkjs 提供了以下幾種讀取方式。
this.config()
這是使用率最高的讀取配置方法,絕大多數(shù)位置都可以使用此方法來讀取配置,比如 controller logic model service middleware 等地方。
// 配置 development.js let dbOpt = this.config('db'); let jwtOpt = this.config('jwt.options');這里有一點需要注意:thinkjs 只能解析兩層配置參數(shù),超過的層級不予解析(源碼中寫死了僅返回兩層)。
// 配置 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); // 超過三層,讀取失敗,只能讀取到兩層內(nèi)容,打印: // { // options: { // algorithm: 'HS128', // expiresIn: '7d' // } // } jwtOptAlg = jwtOpt['algorithm']; console.log(jwtOptAlg); // 正確的讀取方式,打印: // HS128think.config()
think.config 方法可以:
- 無須考慮當前位置來讀取配置參數(shù)(其內(nèi)部運行方式類似 this.config )
- 跨模塊讀取配置參數(shù)
對于前者可以無須思考當前所在的模塊,更自由的讀取配置參數(shù)。
對于后者則對開發(fā)多模塊協(xié)作有著比較重要的意義,配置參數(shù)只有一份,不可能向不同的模塊復制相同的配置,因此需要“一處配置、多處可用”。因此無須考慮“我在哪里讀取配置”,只要考慮“我要讀取哪里的配置”即可。
// 配置文件:src/home/config/assets.js let siteName = think.config('assets.site_name', undefined, 'home');方法的第二個參數(shù)設置為 undefined 是為了避免將讀取動作變?yōu)樵O置動作。
方法的第三個參數(shù)標明了這個配置參數(shù)在哪個模塊下面,一旦給定此參數(shù),thinkjs 會認為 src/home/config/ 下面的配置是你需要讀取的目標。
http.config()
http.config 方法實質(zhì)上是 think.config() 的一個別名,可以讀取和設置配置參數(shù)。
避免踩坑之正確讀取參數(shù)
如果不能理解 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" }; // 兩個配置參數(shù)屬性名一樣的情況下 // 使用不同的讀取方式 // 注意 config 方法的上下文對象的不同 // 會導致讀取的結(jié)果的不同 // 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 配置文件加載順序,就不會對上面發(fā)生的情況驚訝了~
如果你實在懶得去思考 this.config 和 think.config 兩者的分別,建議你干脆使用后者,當讀取參數(shù)只傳入第一個參數(shù)時,它的表現(xiàn)與前者一致。這樣貌似更有利于代碼的維護~
避免踩坑之動態(tài)修改配置參數(shù)
當讀取到了配置參數(shù)后,當然是可以動態(tài)修改其為新的值,以讓后續(xù)的處理都讀到新的值。動態(tài)修改方法也很簡單:config 方法的第二個參數(shù)就是給定的新值。
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上面的動態(tài)修改方法其實平淡無奇,來看看更有趣的修改方法,如下:
let siteAuthor = this.config('assets.site_author'); console.log(siteAuthor); // 打印: // { // name: 'xxuyou.com', // email: 'cap@xxuyou.com' // } siteAuthor['name'] = 'cap'; siteAuthor = this.config('assets.site_author'); console.log(siteAuthor); // 打印: // { // name: 'cap', // email: 'cap@xxuyou.com' // }假如上面的代碼片段修改一下寫法,就可以得到預期的效果,如下:
let siteAuthor = think.extend({}, this.config('assets.site_author')); // <-- 不同點在這里 console.log(siteAuthor); // 打印: // { // name: 'xxuyou.com', // email: 'cap@xxuyou.com' // } siteAuthor['name'] = 'cap'; siteAuthor = this.config('assets.site_author'); console.log(siteAuthor); // 打印: // { // name: 'xxuyou.com', // email: 'cap@xxuyou.com' // }暫且不管這個 think.extend 是何方神圣,為啥修改等號左邊的變量的效果跟直接修改配置方法是一樣的?
原因其實很簡單:
OK~
語言包
語言包其實本身可以作為 i18n 來單獨描述,不過由于國際化在實際開發(fā)甚至架構(gòu)過程中極少涉及到,因此這里簡略描述。
src/config/locale/en.js
系統(tǒng)默認的英語語言環(huán)境,其中定義了相關(guān)的語言模版。
src/config/locale/zh-CN.js
規(guī)范起見,建議手工設立這個語言模版文件,并修改 src/common/config/local.js 中的 default 參數(shù)為 zh-CN即可啟用本語言模版。
done~
上一篇:Node.js 國產(chǎn) MVC 框架 ThinkJS 開發(fā) 入門(荊秀網(wǎng))
下一篇:Node.js 國產(chǎn) MVC 框架 ThinkJS 開發(fā) controller 篇(荊秀網(wǎng))
原創(chuàng):荊秀網(wǎng) 網(wǎng)頁即時推送 https://xxuyou.com | 轉(zhuǎn)載請注明出處
鏈接:https://blog.xxuyou.com/nodejs-thinkjs-study-config/
轉(zhuǎn)載于:https://www.cnblogs.com/xxuyou/p/nodejs-thinkjs-study-start.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Node.js 国产 MVC 框架 ThinkJS 开发 config 篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 团购活动宣传文案30句
- 下一篇: JavaScript | JSON基本格