likes
comments
collection
share

还在考虑 node 服务端如何管理环境变量?来试试 node-configZimuAdmin 服务端目前集成了 MySq

作者站长头像
站长
· 阅读数 55

前言

大家好!我是 嘟老板ZimuAdmin 服务端目前集成了 MySqlRedis,连接的均是本地环境,考虑到未来发布时必然会涉及到环境变量的配置问题,索性今天就来处理一下,一次性搞定环境变量管理。

ZimuAdmin 服务端基于以下技术构建:

阅读本文您将收获:

  1. 了解 ZimuAdmin 集成 node-config 过程。
  2. 了解 node-config 配置文件及常见用法,管理环境变量。
  3. 了解出 node-config 外,其他可行的管理方法,供小伙伴参考。

集成过程

安装依赖

终端输入以下命令,回车执行:

pnpm add config -S
pnpm add @types/config -D

以上命令安装 node-configTS 类型包

工具函数

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_ENVNODE_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 配置如下:

还在考虑 node 服务端如何管理环境变量?来试试 node-configZimuAdmin 服务端目前集成了 MySq

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.hostredis.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 配置变更如下:

还在考虑 node 服务端如何管理环境变量?来试试 node-configZimuAdmin 服务端目前集成了 MySq

host 配置已被 production 配置文件覆盖。

注: prod:start 命令中,使用 cross-env 来设置 NODE_ENV 变量,来解决跨平台执行问题,(Windowsset NODE_ENV=productionLinux/macOSNODE_ENV=production),需执行 pnpm add cross-env -D 安装。

应用

node-config 配置已生效,现在调整 MysqlRedis 相关代码,改为使用环境变量。

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 算是前端老朋友了,前端常用的脚手架工具,如 vitevuecli 等都有 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
评论
请登录