还在考虑 node 服务端如何管理环境变量?来试试 node-configZimuAdmin 服务端目前集成了 MySq
前言
大家好!我是 嘟老板。ZimuAdmin 服务端目前集成了 MySql
和 Redis
,连接的均是本地环境,考虑到未来发布时必然会涉及到环境变量的配置问题,索性今天就来处理一下,一次性搞定环境变量管理。
ZimuAdmin 服务端基于以下技术构建:
阅读本文您将收获:
- 了解 ZimuAdmin 集成 node-config 过程。
- 了解 node-config 配置文件及常见用法,管理环境变量。
- 了解出 node-config 外,其他可行的管理方法,供小伙伴参考。
集成过程
安装依赖
终端输入以下命令,回车执行:
pnpm add config -S
pnpm add @types/config -D
以上命令安装 node-config 及 TS 类型包。
工具函数
在 tools 目录下新增 env-config.ts 用来编写环境变量相关。
import path from 'path'
// 定义 config 文件存储路径
process.env.NODE_CONFIG_DIR = path.resolve(__dirname, '../config')
const config = require('config')
/**
* 获取指定 key 对应的环境变量
* @param key
* @returns
*/
export function get(key: string) {
if (!has(key)) {
console.warn(`指定 key: ${key} 未配置环境变量`)
return null
}
return config.get(key)
}
/**
* 判断指定 key 是否存在环境变量
* @param key
* @returns
*/
export function has(key: string) {
return config.has(key)
}
env-config.ts 引入 node-config 并导出两个工具函数:
- get:获取指定 key 对应的环境变量值。
- has:判断指定的 key 是否配置环境变量。
引入
应用入口 app.ts 中引入 env-config.ts。
import './tools/env-config'
到此,node-config 集成就完事儿了,接下来我们创建几个环境变量配置文件。
配置文件
配置目录
node-config 配置文件默认存储目录为 ./config,可以通过设置 $NODE_CONFIG_DIR 环境变量来修改。
env-config.ts 中有段代码 process.env.NODE_CONFIG_DIR = path.resolve(__dirname, '../config')
即是用来修改配置文件路径的。
为什么呢?因为在 tools 目录下引入的 node-config ,若使用默认路径,则 node-config 会去 tools/config 下检索配置文件。然而目录结构中,配置文件目录在 src 目录下,因此需要手动修改路径。
配置文件介绍
配置文件可以是 .yml、.yaml、.xml、.coffee、.cson、.properties、.json、.json5、.hjson、.ts 或 .js 等类型。
文件以 环境.类型 格式命名,如 development.json,其中 环境 可通过设置环境变量 NODE_ENV 或 NODE_CONFIG_ENV 指定,若未指定,默认 development。
default 配置
config/default.XX 配置文件用来作为 node-config 的默认配置,通常包含其他文件可能覆盖的所有配置参数。覆盖是逐个参数进行的,后续文件可仅包含该覆盖所独有的参数。
在 src 目录下,创建 config/default.js 文件。
cd src
mkdir config
cd config
touch default.js
default.js 中写入以下配置:
module.exports = {
// 数据库配置
db: {
type: 'mysql', // 类型
host: 'localhost', // 主机地址
port: 3306, // 端口
username: 'root', // 账号
password: 'admin0125', // 密码
database: 'zimuadmin' // 库名
},
// Redis 配置
redis: {}
}
在 tools/data-source.ts
中引入 config.get 函数,打印一下 db 配置。
// ...
import { get } from './env-config'
console.log(get('db'))
// ...
启动服务,控制台打印 db 配置如下:
ok,配置已生效。
production
注: 此处并不是真正的生产环境配置,而是带大家了解 node-config 如何启用不同环境配置及配置覆盖特性。
新增 production.js
config 目录下新增 production.js 配置文件,写入以下配置:
module.exports = {
// 数据库配置
db: {
host: '10.121.1.13' // 主机地址
},
// Redis 配置
redis: {
url: 'redis://root:admin0125@10.121.1.13:6379'
}
}
production 主要覆盖了 db.host 和 redis.url 两个配置,其他与 default 配置一致。
创建 npm script
package.json 中的 scripts 配置中新增一条 prod:start 命令,用于启用 production 配置。
"prod:start": "cross-env NODE_ENV=production nodemon ./src/app.ts",
终端输入 pnpm prod:start
,启动服务,之前打印的 db 配置变更如下:
host 配置已被 production 配置文件覆盖。
注: prod:start 命令中,使用 cross-env 来设置 NODE_ENV 变量,来解决跨平台执行问题,(Windows:
set NODE_ENV=production
;Linux/macOS:NODE_ENV=production
),需执行pnpm add cross-env -D
安装。
应用
node-config 配置已生效,现在调整 Mysql 和 Redis 相关代码,改为使用环境变量。
Mysql
目光来到 tools/data-source.ts 文件,先将之前测试打印及原配置相关代码干掉,改为如下:
import { get } from './env-config'
const dbConfig = get('db')
const dataSource = new DataSource({
...dbConfig,
entities: [path.join(__dirname, '../entities/*.entity.{js,ts}')], // typeorm 实体
entityPrefix: 'zm-', // 数据库表前缀
logging: true // 开启日志
})
代码比较简单,只是从 config 中获取 db 配置并应用,效果与原代码一致,只是应用了环境变量配置。日后若有不同的 Mysql 环境,仅需要修改 config 配置文件即可。
Redis
此时目光来到 tools/redis.ts 文件,将获取实例方法 getRedisInstance 调整如下:
// 获取 redis 客户端实例,单例模式
export function getRedisInstance() {
if (!redisInstance) {
const redisConfig = get('redis')
redisInstance = createClient(redisConfig)
}
return redisInstance
}
将 createClient 函数原本的固定参数,改为从环境变量中取,后续若新增 Redis 环境,直接修改 config 配置即可。
其他方案
node-config 不是管理环境变量的唯一方案,甚至不能算是最优方案,接下来我们看看还有哪些类似工具。
dotenv
dotenv 算是前端老朋友了,前端常用的脚手架工具,如 vite、vuecli 等都有 dotenv 的身影,只不过被封装在脚手架内部,不需要我们手动处理相关逻辑。
dotenv 通过根目录下的 .env 文件维护环境变量,比如:
SECRET_KEY=YOURSECRETKEYGOESHERE
若有多环境,对应环境的配置文件需命名为 .env.[环境],如 .env.development。
自定义 config
顾名思义,就是完全由开发者处理,比如定义一个 config 对象,以各个环境名作为 key,分别配置不同的环境变量。
export const config = {
default: {
// ...
},
development: {
// ...
},
prouction: {
// ...
}
}
开发者可以通过 process.env.NODE_ENV 的值判断取哪一个环境的配置,缺点很明显,完全由开发者控制,可能会徒增额外的开发量,而且相较于一个环境对应一个配置文件的维护方式,不够方便直观。
convict
convict 是一款功能强大的配置管理库,可以处理各种类型的配置,包括环境变量,而且提供了 数据验证 和 转换 功能,以确保配置的准确性。
import convict from 'convict';
const config = convict({
env: {
doc: 'The application environment.',
format: ['production', 'development', 'test'],
default: 'development',
env: 'NODE_ENV'
},
})
// 获取环境变量并加载指定配置文件
var env = config.get('env');
config.loadFile('./config/' + env + '.json');
// 验证
config.validate({allowed: 'strict'});
export default config;
为什么选择 node-config
管理环境变量的方式还有很多,那么为什么我要选择 node-config 呢?有以下几点原因:
- 简单,专注于环境变量的配置与管理,功能集中,符合目前需求。
- 机制完善,支持默认配置、覆盖配置以及多文件配置,方便管理。
- 配置结构化,以对象结构维护,可将同类配置归为一个配置项内,方便维护和理解。
- 可增强,可通过与其他三方工具配合使用,实现更高级的需求,比如 类型验证 等。
结语
本文重点介绍了 ZimuAdmin 服务端集成 node-config,实现环境变量配置管理的过程,并列举了几种类似的解决方案,旨在帮助同学们加深对于 Node 环境变量管理的应用理解。希望对您有所帮助。相关代码已上传至 GitHub,欢迎 star。
如您对文章内容有任何疑问或想深入讨论,欢迎评论区留下您的问题和见解。
技术简而不凡,创新生生不息。我是 嘟老板,咱们下期再会。
往期推荐
转载自:https://juejin.cn/post/7392444932965842980