目录
按模块定义配置文件
配置文件加载顺序
自动切换配置文件
开发配置
生产配置
测试配置
定义和使用配置文件
系统特定配置
自定义配置
几种读取配置的方式
this.config()
think.config()
http.config()
避免踩坑之正确读取参数
避免踩坑之动态修改配置参数
语言包
src/config/locale/en.js
src/config/locale/zh-CN.js
首页 web前端 js教程 ThinkJS 开发 config 实例教程

ThinkJS 开发 config 实例教程

Jul 26, 2017 pm 06:02 PM
javascript node.js

按模块定义配置文件

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(&#39;<npm run watch-compile> no longer need, use <npm start> command direct.&#39;);console.log();\"","watch": "npm run watch-compile"
  }}
登录后复制

可以看到 scripts.start 属性定义了我们直接使用 npm start 时具体执行的实际上是 node www/development.js 命令。

本着打破沙锅问到底的原则,看看这个文件里面都有啥:

var thinkjs = require(&#39;thinkjs&#39;);var path = require(&#39;path&#39;);var rootPath = path.dirname(__dirname);var instance = new thinkjs({
  APP_PATH: rootPath + path.sep + &#39;app&#39;,
  RUNTIME_PATH: rootPath + path.sep + &#39;runtime&#39;,
  ROOT_PATH: rootPath,
  RESOURCE_PATH: __dirname,
  env: &#39;development&#39;  // <-- 这里定义了当前的 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&#39;use strict&#39;;export default {
  site_name: "",
  site_title: "",
  site_keywords: "",
  site_description: "",
  db: {  // 这里的配置替代 db.jstype   : &#39;mysql&#39;,log_sql: true, //是否记录 sql 语句adapter: {  mysql: {host    : &#39;127.0.0.1&#39;,port    : &#39;3306&#39;,database: &#39;&#39;,user    : &#39;&#39;,password: &#39;&#39;,prefix  : &#39;thinkjs_&#39;,encoding: &#39;utf8&#39;  }}
  },
  jwt: { // 第三方模块的公共定义options: {  algorithm: &#39;HS128&#39;,  expiresIn: &#39;7d&#39;}
  },
  pay: {// 定义与在线支付接口相关的参数
  },
  backend: {// 定义管理后台相关的参数
  },
  home: {// 定义前端网站相关的参数
  },
  rest: {// 定义 REST API 相关的参数
  },
  task: {// 定义 crond 相关的参数
  }};
登录后复制

配置参数按照层次组织之后,需要注意的一点是:获取配置的时候,不能无限制的 this.config(参数.参数.参数.参数) 下去,详见下面读取配置的几种方式描述。

几种读取配置的方式

配置文件定义之后,需要在项目运行的特别业务中读取(也可以设置)到配置参数的值,根据读取配置的位置的不同,thinkjs 提供了以下几种读取方式。

this.config()

这是使用率最高的读取配置方法,绝大多数位置都可以使用此方法来读取配置,比如 controller logic model service middleware 等地方。

// 配置 development.jslet dbOpt = this.config(&#39;db&#39;);let jwtOpt = this.config(&#39;jwt.options&#39;);
登录后复制

这里有一点需要注意:thinkjs 只能解析两层配置参数,超过的层级不予解析(源码中写死了仅返回两层)。

// 配置 development.jslet jwtOpt = this.config(&#39;jwt.options&#39;);console.log(jwtOpt);// 读取成功,打印:// {//   options: {//     algorithm: &#39;HS128&#39;,//     expiresIn: &#39;7d&#39;//   }// }let jwtOptAlg = this.config(&#39;jwt.options.algorithm&#39;);console.log(jwtOptAlg);// 超过三层,读取失败,只能读取到两层内容,打印:// {//   options: {//     algorithm: &#39;HS128&#39;,//     expiresIn: &#39;7d&#39;//   }// }jwtOptAlg = jwtOpt[&#39;algorithm&#39;];console.log(jwtOptAlg);// 正确的读取方式,打印:// HS128
登录后复制

think.config()

think.config 方法可以:

  • 无须考虑当前位置来读取配置参数(其内部运行方式类似 this.config )

  • 跨模块读取配置参数

对于前者可以无须思考当前所在的模块,更自由的读取配置参数。

对于后者则对开发多模块协作有着比较重要的意义,配置参数只有一份,不可能向不同的模块复制相同的配置,因此需要“一处配置、多处可用”。因此无须考虑“我在哪里读取配置”,只要考虑“我要读取哪里的配置”即可。

// 配置文件:src/home/config/assets.jslet siteName = think.config(&#39;assets.site_name&#39;, undefined, &#39;home&#39;);
登录后复制

方法的第二个参数设置为 undefined 是为了避免将读取动作变为设置动作。

方法的第三个参数标明了这个配置参数在哪个模块下面,一旦给定此参数,thinkjs 会认为 src/home/config/ 下面的配置是你需要读取的目标。

http.config()

http.config 方法实质上是 think.config() 的一个别名,可以读取和设置配置参数。

避免踩坑之正确读取参数

如果不能理解 thinkjs 设计配置文件读取策略的情况下,会无意中踩坑,如下便是一个例子,代码说话。

假设有两个配置文件 src/common/config/assets.jssrc/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(&#39;assets&#39;);let siteTitle = assets[&#39;site_title&#39;];console.log(&#39;siteTitle is: &#39;, siteTitle);// 打印:// my test// src/home/controller/index.jslet assets = think.config(&#39;assets&#39;, undefined, &#39;common&#39;);let siteTitle = assets[&#39;site_title&#39;];console.log(&#39;siteTitle is: &#39;, siteTitle);// 打印:// my site
登录后复制

明白了 thinkjs 配置文件加载顺序,就不会对上面发生的情况惊讶了~

如果你实在懒得去思考 this.configthink.config 两者的分别,建议你干脆使用后者,当读取参数只传入第一个参数时,它的表现与前者一致。这样貌似更有利于代码的维护~

避免踩坑之动态修改配置参数

当读取到了配置参数后,当然是可以动态修改其为新的值,以让后续的处理都读到新的值。动态修改方法也很简单:config 方法的第二个参数就是给定的新值。

let siteTitle = this.config(&#39;assets.site_title&#39;);console.log(siteTitle);// 打印:// my testthis.config(&#39;assets.site_title&#39;, &#39;test 123&#39;);siteTitle = this.config(&#39;assets.site_title&#39;);console.log(siteTitle);// 打印:// test 123
登录后复制

上面的动态修改方法其实平淡无奇,来看看更有趣的修改方法,如下:

let siteAuthor = this.config(&#39;assets.site_author&#39;);console.log(siteAuthor);// 打印:// {//   name: &#39;xxuyou.com&#39;,//   email: &#39;cap@xxuyou.com&#39;// }siteAuthor[&#39;name&#39;] = &#39;cap&#39;;siteAuthor = this.config(&#39;assets.site_author&#39;);console.log(siteAuthor);// 打印:// {//   name: &#39;cap&#39;,//   email: &#39;cap@xxuyou.com&#39;// }
登录后复制

假如上面的代码片段修改一下写法,就可以得到预期的效果,如下:

let siteAuthor = think.extend({}, this.config(&#39;assets.site_author&#39;)); // <-- 不同点在这里console.log(siteAuthor);// 打印:// {//   name: &#39;xxuyou.com&#39;,//   email: &#39;cap@xxuyou.com&#39;// }siteAuthor[&#39;name&#39;] = &#39;cap&#39;;siteAuthor = this.config(&#39;assets.site_author&#39;);console.log(siteAuthor);// 打印:// {//   name: &#39;xxuyou.com&#39;,//   email: &#39;cap@xxuyou.com&#39;// }
登录后复制

暂且不管这个 think.extend 是何方神圣,为啥修改等号左边的变量的效果跟直接修改配置方法是一样的?

原因其实很简单:

  1. thinkjs 内部会缓存配置参数。

  2. 配置参数的值是一个 Object 而不是 String

OK~

语言包

语言包其实本身可以作为 i18n 来单独描述,不过由于国际化在实际开发甚至架构过程中极少涉及到,因此这里简略描述。

src/config/locale/en.js

系统默认的英语语言环境,其中定义了相关的语言模版。

src/config/locale/zh-CN.js

规范起见,建议手工设立这个语言模版文件,并修改 src/common/config/local.js 中的 default 参数为 zh-CN即可启用本语言模版。

以上是 ThinkJS 开发 config 实例教程的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

See all articles