--- kind: configuration_system name: 后端 .env + 前端 Vite 环境变量双轨配置体系 category: configuration_system scope: - '**' source_files: - backend/src/config/loadEnv.js - backend/src/config/env.js - backend/src/config/database.js - backend/src/config/redis.js - backend/src/config/logger.js - backend/src/app.js - .env.example - frontend_v2/.env - frontend_v2/vite.config.ts --- ## 系统概览 本仓库采用「后端 Node.js + 前端 Vue3/Vite」前后端分离的单体部署模式,配置系统分为两条独立轨道: - **后端**:基于 `dotenv` 从根目录 `.env` 加载,通过 `process.env` 注入;启动时由 `src/config/loadEnv.js` 统一读取。 - **前端(v2)**:基于 Vite 的 `loadEnv`,按 `VITE_` 前缀暴露给浏览器,支持多环境文件 `.env` / `.env.prod` / `.env.test`。 ## 关键文件与包 - `backend/src/config/loadEnv.js` — 项目入口最先执行,解析根目录 `.env`(Docker 场景下由 compose env_file 覆盖)。 - `backend/src/config/env.js` — 提供 `APP_ENV`、`isDevelopment`、`isProduction` 三个布尔/字符串常量,供各模块判断运行环境。 - `backend/src/config/database.js` — Sequelize 连接串,所有 MySQL 参数均走 `DATABASE_*` 环境变量,开发默认 `localhost:3306/audio/root/root123`。 - `backend/src/config/redis.js` — ioredis 客户端单例工厂 `getEqCacheRedis()`,通过 `REDIS_HOST/PORT/PASSWORD/EQ_DB` 控制,带错误日志与重连策略。 - `backend/src/config/logger.js` — winston 实例,固定输出到 `backend/logs/app.log` 与控制台,无运行时可配级别。 - `backend/src/app.js` — 应用入口,先 `require('./config/loadEnv')` 再挂载中间件、路由,最后以 `process.env.PORT` 监听。 - `backend/.env.example` — 完整的环境变量清单(数据库、JWT、Meilisearch、S3、OTA URL、Curve API、Redis 等),是部署时的权威参考。 - `frontend_v2/.env` / `.env.prod` / `.env.test` — Vite 构建期环境变量,全部以 `VITE_` 前缀命名,被 `vite.config.ts` 通过 `loadEnv` 读取并注入到 `define`/`server.proxy` 中。 - `frontend_v2/vite.config.ts` — 使用 `loadEnv(configEnv.mode, process.cwd())` 加载对应环境的 `.env*`,并将 `base`、`proxy`、`sourcemap` 等构建选项与之一一对应。 ## 架构与约定 1. **加载顺序**:`app.js` → `require('./config/loadEnv')` → `dotenv.config({ path: root/.env })` → 后续各 `config/*.js` 直接读 `process.env`。这保证了在 Docker 中以 `env_file` 注入的变量优先级高于本地 `.env`。 2. **环境标识**:仅依赖单一变量 `APP_ENV`(development | production),不提供 staging 等中间态;各模块用 `isDevelopment`/`isProduction` 做分支逻辑(如 Sequelize logging、OTA 上传目录回退到系统临时目录)。 3. **配置分层**:没有集中式配置对象,每个子系统(DB、Redis、Logger、JWT、S3、OTA URL)各自在自己的 config 文件中按需读取 `process.env`,形成“分散但自描述”的配置结构。 4. **前端隔离**:Vite 只把 `VITE_` 前缀的变量注入到客户端代码,敏感信息不会进入产物;后端变量与前端变量完全解耦,避免泄露风险。 5. **默认值策略**:所有关键配置都提供合理的本地开发默认值(MySQL root/root123、Redis 空密码、端口 8083/9527),保证克隆后 `pnpm dev` 即可运行。 ## 开发者应遵循的规则 - **新增环境变量**:先在根目录 `.env.example` 补充条目与注释,再在对应 `config/*.js` 或 `vite.config.ts` 中消费;不要硬编码路径或密钥。 - **区分环境**:通过 `APP_ENV` 切换行为,不要在业务代码里写死 `if (process.env.NODE_ENV)` 之类的判断。 - **安全边界**:任何包含密钥、密码、私钥的变量一律不进源码,仅出现在 `.env.example`(占位值)和 CI/CD 的 secrets 中;前端变量必须以 `VITE_` 开头。 - **Docker 优先**:容器内不依赖 `.env` 文件,所有变量应由 `docker-compose.yml` 的 `environment`/`env_file` 注入;本地开发才使用根目录 `.env`。 - **前端构建期变量**:修改 `VITE_*` 需要重新 build,而非热重载生效;生产环境通过 `.env.prod` 控制打包产物。