配置
VextJS 采用 三层配置合并 机制,支持按环境覆盖配置,同时提供丰富的内置配置项覆盖框架行为。
配置加载机制
框架启动时,config-loader 按以下顺序加载配置文件并深度合并:
框架内置默认值 → default.ts → {NODE_ENV}.ts → local.ts
每一层都可以只声明需要覆盖的字段,未声明的字段从上一层继承。
配置文件
环境文件通过 NODE_ENV 环境变量自动匹配。未设置 NODE_ENV 时默认为 development。
合并规则
- 对象字段:深度合并(deep merge),环境文件只需声明需要覆盖的字段
middlewares 数组:智能 patch 策略——按 name 匹配并合并,而非简单替换整个数组
- 其他数组:后层覆盖前层
- 最终结果:深冻结(
deepFreeze),运行时不可修改
配置文件格式
每个配置文件使用 export default 导出一个对象:
// src/config/default.ts
export default {
port: 3000,
host: '0.0.0.0',
logger: {
level: 'info',
},
cors: {
origins: ['*'],
},
openapi: {
enabled: true,
},
};
// src/config/production.ts — 仅覆盖需要变更的字段
export default {
logger: {
level: 'warn', // 生产环境减少日志输出
},
cors: {
origins: ['https://myapp.com'], // 生产环境限制来源
},
openapi: {
enabled: false, // 生产环境关闭文档
},
};
// src/config/local.ts — 本地开发特殊配置(不提交 Git)
export default {
port: 8080, // 本地使用其他端口
};
Middlewares Patch 策略
middlewares 数组使用智能合并,按中间件 name 匹配:
// src/config/default.ts
export default {
middlewares: [
'auth',
{ name: 'check-role', options: { roles: ['user'] } },
{ name: 'rate-limit-api', options: { max: 100 } },
],
};
// src/config/development.ts
export default {
middlewares: [
// 只需声明要覆盖的中间件,其余保留
{ name: 'check-role', options: { roles: [] } }, // 开发环境不检查角色
{ name: 'rate-limit-api', options: { max: 10000 } }, // 放宽限流
],
};
合并后结果:
middlewares: [
'auth', // 保留
{ name: 'check-role', options: { roles: [] } }, // 被覆盖
{ name: 'rate-limit-api', options: { max: 10000 } }, // 被覆盖
]
使用 Adapter
默认使用 Native Adapter(http.createServer + find-my-way)。要切换其他 Adapter,在配置中指定 adapter 字段:
// src/config/default.ts — 使用 Hono Adapter
import { honoAdapter } from 'vextjs/adapters/hono';
export default {
adapter: honoAdapter(),
port: 3000,
};
// src/config/default.ts — 使用 Fastify Adapter
import { fastifyAdapter } from 'vextjs/adapters/fastify';
export default {
adapter: fastifyAdapter(),
port: 3000,
};
// src/config/default.ts — 使用 Express Adapter
import { expressAdapter } from 'vextjs/adapters/express';
export default {
adapter: expressAdapter(),
port: 3000,
};
// src/config/default.ts — 使用 Koa Adapter
import { koaAdapter } from 'vextjs/adapters/koa';
export default {
adapter: koaAdapter(),
port: 3000,
};
Tip
不指定 adapter 时默认使用 Native Adapter,性能最高且零框架依赖。仅当需要使用特定框架的生态或特性时才切换。
完整配置项参考
基础配置
export default {
port: 3000,
host: '0.0.0.0',
trustProxy: false,
};
CORS 配置 (cors)
export default {
cors: {
origins: ['https://myapp.com'], // 生产环境限制来源(数组格式)
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
},
};
限流配置 (rateLimit)
export default {
rateLimit: {
enabled: true,
max: 100,
window: 60000, // 1 分钟
message: 'Too many requests, please try again later',
keyBy: 'ip',
},
};
路由级限流覆盖
可以在路由的 options.override.rateLimit 中为特定路由覆盖限流配置:
app.post('/login', {
override: {
rateLimit: { max: 5, window: 60000 }, // 登录接口更严格
},
}, handler);
app.get('/health', {
override: {
rateLimit: false, // 健康检查不限流
},
}, handler);
请求 ID 配置 (requestId)
export default {
requestId: {
enabled: true,
header: 'x-request-id',
},
};
当请求中携带 X-Request-Id 头时,框架会透传该 ID 而不是生成新的。适合微服务链路追踪。
日志配置 (logger)
支持的日志级别(从低到高):'trace' → 'debug' → 'info' → 'warn' → 'error' → 'fatal' → 'silent'
export default {
logger: {
level: 'info', // 生产环境建议 'warn'
},
};
VextJS 内置 pino 作为日志引擎,默认使用 pino-pretty 格式化输出。
优雅关闭配置 (shutdown)
export default {
shutdown: {
timeout: 15000, // 15 秒超时
},
};
收到 SIGTERM / SIGINT 信号后,框架按注册的逆序执行所有 onClose 钩子(如关闭数据库连接),超时后强制退出。
响应配置 (response)
export default {
response: {
envelope: true,
successCode: 0,
codeField: 'code',
dataField: 'data',
},
};
启用包装后,res.json(data) 的实际输出:
{
"code": 0,
"data": { "name": "Alice" },
"requestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
设置 envelope: false 可关闭包装,res.json(data) 直接输出原始数据。
Body Parser 配置 (bodyParser)
export default {
bodyParser: {
enabled: true,
limit: '5mb', // 允许更大的请求体
json: true,
urlencoded: true,
},
};
limit 支持字符串格式('1mb'、'500kb')和数字格式(字节数)。
Access Log 配置 (accessLog)
export default {
accessLog: {
enabled: true,
level: 'info',
},
};
启用后,每个请求完成时自动记录:
INFO GET /api/users → 200 (12ms)
OpenAPI 配置 (openapi)
export default {
openapi: {
enabled: true,
title: 'My App API',
description: '我的应用 API 文档',
version: '1.0.0',
docsPath: '/docs',
specPath: '/openapi.json',
scalar: {
theme: 'default',
darkMode: false,
layout: 'modern',
favicon: '/favicon.svg',
},
servers: [
{ url: 'http://localhost:3000', description: '本地开发' },
{ url: 'https://api.myapp.com', description: '生产环境' },
],
tags: [
{ name: '用户', description: '用户管理相关接口' },
{ name: '订单', description: '订单管理相关接口' },
],
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
contact: {
name: 'API Support',
email: 'support@myapp.com',
},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT',
},
},
};
请求上下文配置 (requestContext)
export default {
requestContext: {
enabled: true,
},
};
性能提示
禁用 requestContext 可提升约 3-8% RPS,但以下功能将失效:
app.logger 自动携带 requestId
app.throw() 自动解析请求 locale
app.fetch 自动传播 requestId
仅在极致性能场景下考虑禁用。
Cluster 配置 (cluster)
export default {
cluster: {
enabled: true,
workers: 'auto', // 自动检测 CPU 核数
autoRestart: true,
maxRestarts: 10,
healthCheck: true,
reload: true,
},
};
也可以通过环境变量 VEXT_CLUSTER=1 开启 Cluster 模式,无需修改配置文件。
中间件白名单 (middlewares)
export default {
middlewares: [
// 普通中间件 — 字符串声明
'auth',
'timing',
// 工厂中间件 — 对象声明(附带默认参数)
{ name: 'check-role', options: { roles: ['user'] } },
{ name: 'cache-control', options: { maxAge: 3600 } },
],
};
只有在白名单中声明的中间件才能在路由的 options.middlewares 中被引用。
在代码中访问配置
路由中
export default defineRoutes((app) => {
app.get('/info', async (_req, res) => {
res.json({
port: app.config.port,
env: process.env.NODE_ENV,
openapi: app.config.openapi.enabled,
});
});
});
服务中
export default class MyService {
constructor(private app: VextApp) {}
getApiBaseUrl() {
const { host, port } = this.app.config;
return `http://${host}:${port}`;
}
}
插件中
export default definePlugin({
name: 'my-plugin',
setup(app) {
const myConfig = app.config.myPlugin ?? { enabled: false };
if (!myConfig.enabled) return;
// ...
},
});
配置只读
app.config 在启动后被深冻结(deepFreeze),任何修改尝试都会抛出 TypeError。这确保配置在运行时不被意外修改。
自定义配置字段
VextConfig 接口允许扩展自定义字段。插件和业务代码可以在配置中添加任意字段:
// src/config/default.ts
export default {
port: 3000,
// 自定义字段
redis: {
url: 'redis://localhost:6379',
db: 0,
},
mailer: {
smtp: 'smtp://localhost:1025',
from: 'noreply@myapp.com',
},
};
配合 declare module 获得类型提示:
// src/types/config.d.ts
declare module 'vextjs' {
interface VextConfig {
redis?: {
url: string;
db?: number;
};
mailer?: {
smtp: string;
from: string;
};
}
}
环境变量
除了配置文件,部分设置也可以通过环境变量控制:
// src/config/default.ts — 使用环境变量
export default {
port: Number(process.env.PORT) || 3000,
logger: {
level: process.env.LOG_LEVEL || 'info',
},
};
:::warning 安全提示
敏感信息(如数据库密码、API Key)不要硬编码在配置文件中。推荐:
- 使用环境变量:
process.env.DB_PASSWORD
- 使用
local.ts(已加入 .gitignore)存放本地开发的敏感配置
:::
配置校验
config-loader 在合并完成后会执行 Fail Fast 校验,检查以下内容:
port 必须是 1-65535 范围内的正整数
adapter 必须是已知的内置标识或合法的 adapter 对象/函数
middlewares 数组中每个元素必须是字符串或 { name: string } 对象
rateLimit.max 必须是正整数
rateLimit.window 必须是正整数
logger.level 必须是合法的日志级别
shutdown.timeout 必须是正整数
cluster.workers 必须是正整数或 'auto' / 'max' / 'half'
如果校验失败,框架会在启动时立即报错并给出清晰的错误信息,避免配置错误在运行时才暴露。
完整示例
// src/config/default.ts
import { honoAdapter } from 'vextjs/adapters/hono';
export default {
port: Number(process.env.PORT) || 3000,
host: '0.0.0.0',
adapter: honoAdapter(),
trustProxy: false,
logger: {
level: 'info',
},
cors: {
origin: '*',
credentials: false,
},
rateLimit: {
enabled: true,
max: 100,
window: 60000,
keyBy: 'ip',
},
requestId: {
enabled: true,
header: 'x-request-id',
},
bodyParser: {
enabled: true,
limit: '1mb',
},
accessLog: {
enabled: true,
level: 'info',
},
response: {
envelope: true,
successCode: 0,
},
shutdown: {
timeout: 10000,
},
requestContext: {
enabled: true,
},
openapi: {
enabled: true,
title: 'My App API',
version: '1.0.0',
},
middlewares: [
'auth',
{ name: 'check-role', options: { roles: ['user'] } },
],
// 自定义配置
redis: {
url: process.env.REDIS_URL || 'redis://localhost:6379',
},
};
// src/config/production.ts
export default {
logger: { level: 'warn' },
cors: { origin: 'https://myapp.com', credentials: true },
openapi: { enabled: false },
accessLog: { level: 'warn' },
cluster: {
enabled: true,
workers: 'auto',
},
};
// src/config/local.ts — 不提交到 Git
export default {
port: 8080,
redis: {
url: 'redis://localhost:6380',
},
};
下一步