一、什么问题
开发场景 :
在基于 Vite 的 TypeScript 项目中,遇到以下代码片段不理解其实现原理:
typescript
// 动态加载配置
const modules = import.meta.glob("./*/*.ts", { eager: true });
const api = modules[`./${env.VITE_APP_ENV}/api.ts`] as { default: APIS };
具体疑问:
- 如何根据环境变量动态加载不同配置?
import.meta.glob
的作用和原理是什么?- 类型断言
as { default: APIS }
的必要性? - 如何保证多环境配置的一致性?
二、为什么出现
需求背景:
- 多环境管理:项目需要适配开发、测试、预发、生产等不同环境,每个环境有独立配置(如 API 地址)
- 动态注入:构建时需根据环境变量自动打包对应配置,避免硬编码
- 类型安全:需通过 TypeScript 类型系统保障各环境配置结构一致性
技术痛点:
- 传统
if-else
条件判断加载配置会导致代码冗余 - 手动维护多份配置文件易出错
- 动态导入模块时类型提示缺失
三、如何解决
1. 标准化目录结构
bash
src/config/
├─ shared.ts # 公共配置
├─ dev/ # 开发环境
│ └─ api.ts
├─ test/ # 测试环境
│ └─ api.ts
├─ pre/ # 预发环境
│ └─ api.ts
└─ online/ # 生产环境
└─ api.ts
2. 核心实现代码
typescript
// 读取所有子目录中的 ts 文件
const modules = import.meta.glob("./*/*.ts", { eager: true });
// 根据环境变量动态加载配置
const env = import.meta.env;
const apiConfig = modules[`./${env.VITE_APP_ENV}/api.ts`] as {
default: APIS; // 类型断言保证结构
};
// 合并公共配置与环境配置
export default {
...sharedConfig,
env,
api: apiConfig.default
};
3. 类型保障方案
typescript
// 定义标准配置类型(以 online 环境为基准)
import type onlineConfig from "./online/api";
export type APIS = typeof onlineConfig;
// 每个环境文件必须遵循此结构
// dev/api.ts
export default {
BAPI: "http://dev-api.example.com",
MAPI: "http://dev-mock.example.com",
// ...其他相同字段
}
4. 环境变量配置
.env.development
文件示例:
ini
VITE_APP_ENV=dev # 控制加载 ./dev/api.ts
四、底层原理
1. Vite 的 Glob 导入
import.meta.glob
:Vite 特有的模块批量导入方法- 模式匹配 :
./*/*.ts
匹配所有一级子目录中的 ts 文件 - 返回结构 :
{ [文件路径]: 模块对象 }
的键值对
javascript
// 输出示例
{
"./dev/api.ts": { default: { BAPI: "http://dev..." } },
"./test/api.ts": { default: { BAPI: "http://test..." } }
}
2. Eager 模式
- 立即加载 :
{ eager: true }
使所有匹配模块在构建时被静态导入 - 与动态导入区别:非懒加载模式,直接返回解析后的模块内容
3. 环境变量处理
- 构建时替换 :
import.meta.env
中的变量会在构建阶段被静态替换 - 安全前缀 :只有以
VITE_
开头的变量会被暴露到客户端
4. 类型系统保障
- 类型断言 :
as { default: APIS }
强制模块具有标准结构 - 类型继承 :
typeof onlineConfig
确保所有环境配置继承自基准类型 - 编译时检查:若环境配置文件缺少字段,TypeScript 会抛出类型错误
文档使用说明 :
当遇到环境配置加载异常时,按以下顺序排查:
- 检查
.env
文件是否正确定义VITE_APP_ENV
- 确认目标环境目录存在对应的
api.ts
文件 - 使用
console.log(modules)
输出所有加载的模块路径 - 检查各环境配置文件的导出结构是否与
APIS
类型一致 - 确保没有拼写错误(如
api.ts
必须全小写)
此方案已通过 Vite 4.x + TypeScript 5.x 验证,适用于需要多环境管理的 Web 应用场景。