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 modethinkjs_normal/src/config/*# module modethinkjs_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?1.1.11","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 默认的配置文件清单,这些系统特定配置都是有相应的使用场景和参数设置,详细说明及完整参数详见:
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.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: {// 定义与在线支付接口相关的参数 }, backend: {// 定义管理后台相关的参数 }, home: {// 定义前端网站相关的参数 }, rest: {// 定义 REST API 相关的参数 }, task: {// 定义 crond 相关的参数 }};
配置参数按照层次组织之后,需要注意的一点是:获取配置的时候,不能无限制的 this.config(参数.参数.参数.参数)
下去,详见下面读取配置的几种方式描述。
配置文件定义之后,需要在项目运行的特别业务中读取(也可以设置)到配置参数的值,根据读取配置的位置的不同,thinkjs 提供了以下几种读取方式。
这是使用率最高的读取配置方法,绝大多数位置都可以使用此方法来读取配置,比如 controller
logic
model
service
middleware
等地方。
// 配置 development.jslet dbOpt = this.config('db');let jwtOpt = this.config('jwt.options');
这里有一点需要注意:thinkjs 只能解析两层配置参数,超过的层级不予解析(源码中写死了仅返回两层)。
// 配置 development.jslet 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 方法可以:
无须考虑当前位置来读取配置参数(其内部运行方式类似 this.config )
跨模块读取配置参数
对于前者可以无须思考当前所在的模块,更自由的读取配置参数。
对于后者则对开发多模块协作有着比较重要的意义,配置参数只有一份,不可能向不同的模块复制相同的配置,因此需要“一处配置、多处可用”。因此无须考虑“我在哪里读取配置”,只要考虑“我要读取哪里的配置”即可。
// 配置文件:src/home/config/assets.jslet siteName = think.config('assets.site_name', undefined, 'home');
方法的第二个参数设置为 undefined
是为了避免将读取动作变为设置动作。
方法的第三个参数标明了这个配置参数在哪个模块下面,一旦给定此参数,thinkjs 会认为 src/home/config/
下面的配置是你需要读取的目标。
http.config 方法实质上是 think.config() 的一个别名,可以读取和设置配置参数。
如果不能理解 thinkjs 设计配置文件读取策略的情况下,会无意中踩坑,如下便是一个例子,代码说话。
假设有两个配置文件 src/common/config/assets.js
和 src/home/config/assets.js
,其中有着一样的属性名:
// src/common/config/assets.jsexport default { "site_title": "my site"};// src/home/config/assets.jsexport default { "site_title": "my test"};// 两个配置参数属性名一样的情况下// 使用不同的读取方式// 注意 config 方法的上下文对象的不同// 会导致读取的结果的不同// src/home/controller/index.jslet assets = this.config('assets');let siteTitle = assets['site_title'];console.log('siteTitle is: ', siteTitle);// 打印:// my test// src/home/controller/index.jslet 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 testthis.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: '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
是何方神聖,為啥修改等號左邊的變數的效果跟直接修改配置方法是一樣的?
原因其實很簡單:
thinkjs 內部會快取設定參數。
配置參數的值是一個 Object
而不是 String
。
OK~
語言包其實本身可以作為i18n 來單獨描述,不過由於國際化在實際開發甚至架構過程中極少涉及到,因此這裡簡略描述。
系統預設的英文語言環境,其中定義了相關的語言模版。
規格起見,建議手動設立這個語言模版文件,並修改src/common/config/local.js
中的default
參數為zh-CN
即可啟用本語言模版。
以上是ThinkJS 開發 config 實例教程的詳細內容。更多資訊請關注PHP中文網其他相關文章!