TypeScript 应用程序配置:工具与库概述
现代 TypeScript 应用程序很少在隔离环境中运行。它需要知道连接哪个数据库、使用哪个端口、第三方 API 位于何处,以及如何在不同的环境(开发、预发布、生产)中运行。良好的配置不仅仅是存储设置,而是一门包含验证、类型化和安全的学科。
在本文中,我们将分析 TypeScript 项目中用于配置管理的关键工具和库,从简单的解决方案到行业标准。
为什么需要单独的配置?
有几种存储设置的方法,每种方法都有其缺点:
- 源代码中的硬编码 — 违反了 12-factor app 原则,配置与代码混合,无法在不重新构建的情况下更改行为。
- 环境变量 (process.env) — 标准方法,但所有值都是字符串,没有验证,容易出错。
- JSON/YAML 文件 — 方便,但需要谨慎地进行版本控制,以免将机密信息提交到仓库。
TypeScript 增加了另一层:我们希望配置是强类型的,并且错误在编译阶段而不是运行时被发现。
用于处理环境变量的库
dotenv
最流行的从 .env 文件加载变量的库。在 TypeScript 项目中几乎总是使用。
// npm install dotenv @types/dotenvimport dotenv from 'dotenv';
dotenv.config(); // 将 .env 加载到 process.env 中
console.log(process.env.PORT); // '3000' — 字符串特点:
- 适用于任何框架(Express、NestJS、Next.js)。
- 支持多个文件(
.env.local、.env.production)。 - 不进行验证 — 仅加载。
env-var
在 process.env 之上的封装,添加了运行时验证和类型转换。
// npm install env-varimport env from 'env-var';
export const config = { PORT: env.get('PORT').required().asPortNumber(), DB_HOST: env.get('DB_HOST').required().asString(), DEBUG: env.get('DEBUG').default('false').asBool(), API_KEYS: env.get('API_KEYS').asArray()};优点: API 简单,内置转换器(数字、端口、布尔值、数组)。
缺点: 在类型层面没有与 TypeScript 集成 — 结果仍然是 string | number | boolean。
工业级解决方案:convict 和 node-config
Convict
用于描述配置模式的库,支持验证、默认值以及多种来源(文件、环境变量、命令行参数)。
// npm install convict @types/convictimport convict from 'convict';
const config = convict({ env: { format: ['production', 'development', 'test'], default: 'development', env: 'NODE_ENV' }, server: { port: { format: 'port', default: 3000, env: 'PORT' } }, db: { host: { format: String, default: 'localhost', env: 'DB_HOST' } }});
config.validate({ allowed: 'strict' }); // 数据无效时将抛出错误
export default config;convict 的特点:
- 内置格式:
port、email、url、int、nat(自然数)。 - 自动从
process.env和 JSON 文件读取。 - 支持嵌套模式。
- 不足