配置项
本页说明公开配置分组、默认值、覆盖规则和实际生效边界。首次配置请先读配置指南;片段按分组合并到现有文件,不要把互斥示例拼成多个 default export。插件自定义配置以对应插件文档为准,内部 _testMode / _runtimeMode 不属于用户设置。
默认值分为框架常量、模块解析回退和模板显式配置,三者不同。“已解析但未接入”不表示功能已经可用。
按任务查阅
每个字段同时核对默认值、单位、启用前提和路由覆盖能力。build identity 是产物的 profile/buildId 等身份记录;manifest 是生成清单。它们说明实际加载的产物,不是额外需要配置的业务字段。
配置加载机制
VextJS 使用多层配置合并策略,按优先级从低到高:
普通对象递归合并,数组通常整体替换,middlewares 按 name 专门合并。校验通过后普通对象与数组经 deepFreeze 冻结;Date、Map、Set、Buffer 和 class 实例等保留运行时状态,不把它们视为可热更新的配置通道。
profile 与运行模式不同。显式选择顺序为 --config → VEXT_CONFIG → 非标准 NODE_ENV(兼容并警告)。无显式选择时,start/deploy assets 优先使用所选成功构建产物记录的 profile,无记录才回退 production;build 默认 production,dev 默认 development。start/build 的运行模式为 production,dev 为 development。即使用 start --config development,生产模式也不读取 local.ts;标准 NODE_ENV 不替代 --config 选择 profile。命令示例见配置指南。
TypeScript 中的各层不会共用一个宽松类型。基础 default.ts 使用 VextUserConfig;一旦包含 database,该嵌套值就必须是完整的 MonSQLizeDatabaseConfig。profile/local patch 使用 VextConfigOverride,嵌套字段可按运行时深度合并语义分层提供。
配置文件清单
src/config/bootstrap.ts
当数据库、密钥或配置中心 patch 需要在配置冻结前完成注入时,可新增:
此为远程 provider 的结构片段,须准备可访问的配置服务和合法 database patch,并校验响应 JSON。最小本地项目使用 providers: [],无需访问示例域名。
约束:
- provider 必须返回 plain object patch 或
null - patch 只支持 JSON-like 结构,不能注入函数或 class 实例;多个 provider 按声明顺序合并
timeoutMs是硬期限:到期会中止 provider 的signal,迟到 continuation 返回的 patch 会被丢弃,不会再合并required未声明时:production默认 fail-fast,development / test默认 warning 后继续- Cluster 模式下,同一启动周期会复用同一份 provider patch,避免 Master / Worker 看到不同结果
配置文件示例
完整配置参考
VextConfig
自动插件初始化期限通过 plugin 配置,完整类型见 VextPluginConfig。
host 支持 "0.0.0.0"、"::"、具体 IPv4、具体 IPv6 和主机名。配置为 "::" 时,ready 日志会同时展示 IPv4 local URL 与 bracketed IPv6 local/network URL(例如 http://[::1]:3000);具体 IPv6 host 也会以方括号 URL 格式输出。
adapter
以下方式互斥,实际文件只导出一种配置;自定义实例由应用先实现。
底层 HTTP 适配器,支持三种传参方式:
trustProxy
当设置为 true 时:
req.ip从X-Forwarded-For请求头读取第一个 IPreq.protocol从X-Forwarded-Proto请求头读取
仅在请求经过可信代理、且代理覆盖转发头时启用;该开关没有可信代理 IP 白名单。
middlewares
路由级中间件声明。字符串如 "auth" 等价于 { name: "auth" };完整项支持 options 与 enabled。同名声明按层浅合并,options 整体替换,新名称追加,同一层重复名称报错;enabled:false 禁用该项。引用还要求 src/middlewares 中存在并成功加载对应文件。
全局中间件(如 CORS、body-parser)由框架自动注册,无需在此声明。此处只声明路由级可选中间件。
Vext 内置 auth() helper 仍然以路由级中间件文件注册,路由再通过 RouteOptions.auth 选择是否保护:
VextCorsConfig
跨域资源共享配置。
origins: ['*'] 与 credentials: true 不能同时使用。需要携带凭证时必须指定具体域名。
VextRateLimitConfig
全局速率限制配置,基于 flex-rate-limit。默认在认证中间件之前执行,因此此例按 IP 限流;完整流程见请求限流。
keyBy 选项
全局显式启用后,路由 options.override.rateLimit 可覆盖 max/window/字符串 keyBy,或设为 false 跳过。函数 keyBy 须同步返回字符串;其他字符串按 IP 处理。仅路由覆盖不会自行启用全局限流。
限流 Store
rateLimit.store 默认 "memory",支持 "redis" 或 Redis 对象。各进程内存不共享;Redis 地址按 url → uri → VEXT_REDIS_URL → REDIS_URL 选择,无目标时初始化失败。
同一策略的实例应使用一致目标与前缀,不同策略应设计独立键。内置 Store 检查错误可能放行,见限流故障语义。
VextPluginConfig
config.plugin 控制自动插件加载;自定义插件字段保留给应用使用。
vext dev、vext start 与 createTestApp 共用该值。超时发送取消信号、停止后续插件并回滚已注册的清理;插件仍需监听 signal 并自行停止工作。手动 createTestApp({ setupPlugins }) 回调不受此配置控制。修改配置需重启,详见插件。
VextLocaleConfig
后端语言配置与 frontend.i18n 职责不同:
请求语言始终写入 req.locale,独立于 requestId 开关;启用请求上下文后也写入 store,错误翻译据此选语言。请求上下文关闭或请求外调用使用应用默认语言。词典与匹配顺序见后端国际化,前端可按前端国际化继承或独立探测。
VextRequestIdConfig
请求 ID 用于关联请求和日志。非空入站头优先,其次 app.setRequestIdGenerator、config.generate、randomUUID;须为1—512字符且无控制字符。enabled:false 时 ID 为空且不写响应头,独立语言/传播头处理仍执行。
requestId vs traceId
requestId 是 vext 内置的请求唯一标识,traceId 通常指 APM 链路追踪系统(如 OpenTelemetry / Jaeger)生成的追踪 ID。两者有不同的使用场景:
模式一:自定义关联头
可将 ID 头改为 x-trace-id 作为应用间约定;这不会创建 OpenTelemetry trace/span 或 W3C Trace Context:
模式二:requestId + APM traceId 并存(企业级场景)
保留 requestId,可用 fetch.propagateHeaders 转发收到的追踪头;这本身不会创建出站 span 或新的 traceparent。真实追踪还须按OpenTelemetry初始化并验证活跃上下文:
- 内部系统、简单追踪 → 模式一(改 header 名为
x-trace-id) - 接入 OpenTelemetry → 保留 requestId,并按插件方案初始化、传播和验证 trace/span
- 详见 请求上下文 → 与分布式追踪的关系 :::
也可通过插件动态替换生成器:
VextFetchConfig
内置 HTTP 客户端与请求代理配置。
timeout 必须是大于 0 且不超过 2147483647 毫秒的有限数字;retryDelay 必须是 0 或正数且不超过 2147483647 毫秒,函数形式的返回值也会在运行时校验。
VextFetchProxyTargetConfig
代理请求头优先级:target.headers < forwardHeaders < target.defaultInjectHeaders < options.headers < options.injectHeaders。Authorization 默认不透传,必须同时配置白名单和 allowAuthorizationForward: true。
代理 retry 优先级:options.retry > target.retry > config.fetch.retry > 0。仅 GET / HEAD / OPTIONS / PUT / DELETE 会在上游 5xx 或网络错误时自动重试;POST / PATCH 默认不重试,超时不重试并返回本地 504。
VextLoggerConfig
结构化日志配置,基于 Vext 内置 logger kernel 实现。
日志级别优先级(从高到低):
设置某个级别后,只输出该级别及更高级别的日志。设为 'silent' 完全静默。
默认 logger 还支持运行时 app.logger.getLevel() / app.logger.setLevel(level) 调整后续日志阈值;配置对象本身仍会在启动后冻结,不应通过修改 app.config.logger.level 动态变更。
VextShutdownConfig
优雅关闭配置。
收到 SIGTERM / SIGINT 信号后,框架会:
- 从关闭开始建立
timeout的单一绝对期限 - 停止接受新请求并等待飞行中请求完成
- 按 LIFO 顺序执行
onClose,随后关闭响应缓存、生命周期 hook 与 logger - 期限到达后仍调用尚未启动的清理,但不再继续等待,然后退出进程
VextServerConfig
入站 Node.js HTTP server 层配置。适用于内置 Native / Hono / Fastify / Express / Koa adapter,也适用于 vext dev 创建的开发 server。未设置字段保持当前 Node.js / adapter 默认值。
config.server 只控制入站服务请求。出站 app.fetch / app.fetch.proxy 的超时由 config.fetch.timeout、代理目标 timeout 或调用时 options 控制。
VextResponseConfig
响应格式配置。
错误日志字段
日志仍受 logger.level 影响;Schema 校验错误不会因 http4xx:true 自动记录,日志配置与响应隐藏相互独立。
出口包装
启用 wrap: true 时,res.json(data) 自动包装:
错误响应格式:
wrap:false 使 res.json 发送原始 data,不改变错误响应合同。rawJson、页面、文本和流不走成功 JSON 包装。
隐藏内部错误
hideInternalErrors 只影响“未知异常”这条 500 错误路径,例如路由、service、middleware 中直接 throw new Error("...") 的场景。它不会改变 app.throw(...) 或 VextValidationError 这类结构化错误的状态码与响应格式。
hideInternalErrors: true 时,500 错误不暴露 stack trace:
VextSessionConfig
config.session.enabled: true 会在生产、开发、测试和软重载链路中自动注册 Session。显式 session() 中间件仅用于作用域化或手动注册场景。
VextSessionCookieOptions 基于 CookieSerializeOptions,并额外支持 secure: boolean | "auto"。Cookie 选项包含 domain、path、expires、maxAge、httpOnly、secure、sameSite、priority、partitioned 与 encode。
VextSessionStore 必须实现 get(id)、set(id, data, ttlSeconds) 和 delete(id)。可选方法包括 touch(id, ttlSeconds)、clearExpired() 与 close()。配置 Store 和已启用的手动 Session 运行时会在应用关闭时调用 close()。
生产 cache-backed session 推荐使用 vextjs 根入口导出的 createCacheSessionStore(cacheLike, options?)。它接收具备 get、set、del 的结构型 VextCacheLike,把 session TTL 秒转换为 cache 毫秒,默认写入 JSON string,且只有传入 options.close 时才暴露 close()。config.cache.cacheHub 仍然只是路由响应缓存配置,不会注入 Session Store。Session、RateLimit、Job 与响应缓存各自拥有 Redis 集成边界;可以共用同一个 Redis 服务,但每个模块应使用自己的自动 namespace 或显式 prefix。
RouteOptions.session 接受 false、true 或 { enabled?, rolling?, autoCommit? },可为单个路由关闭 Session,也可在全局运行时关闭时单独启用。
VextCsrfConfig
config.csrf 用于配置内置 CSRF 中间件。enabled: true 会在 body parsing 与插件全局中间件之后自动全局注册 CSRF;也可以保持禁用,并手动注册 csrf() 保护指定路径。
路由可通过 route options { csrf: false } 跳过 CSRF。
VextSecurityHeadersConfig
config.securityHeaders 用于启用 Vext 内置浏览器安全响应头。默认关闭。preset: "basic" 是多数应用的低破坏主路径;strict 与 custom 都是显式 opt-in。
basic 发送 X-Content-Type-Options: nosniff、Referrer-Policy: strict-origin-when-cross-origin 与 X-Frame-Options: SAMEORIGIN。strict 额外开启 HTTPS-only HSTS、最小 Permissions-Policy、COOP 和 CORP,但 CSP 与 COEP 仍需显式配置。custom 只发送你配置的字段。路由可通过 { securityHeaders: false } 跳过。
VextBodyParserConfig
请求体解析配置。
禁用后内置链不填充 req.body / req.files,自定义解析器仍可设置它们。支持 JSON、urlencoded 和已启用的 multipart,其他类型跳过;非法 JSON 通常400,超限413,MIME失败415,见上传指南。
maxBodySize 支持的格式:
VextMultipartConfig
Multipart / 文件上传全局配置。
:::tip Fastify 联动
multipart.maxFileSize 只限制单个文件大小;总请求体读取上限由 bodyParser.maxBodySize 控制。使用 Fastify 时,如额外传入 fastifyAdapter({ bodyLimit }),实际读取边界会取 adapter bodyLimit 与 body-parser 总体上限中的较小值。
存储与清理
内置 multipart 解析是纯内存路径。Vext 读取请求体后,将每个上传文件暴露为 req.files[*].buffer;它不会创建框架管理的临时文件或临时目录。因此没有可配置的 tmpDir、磁盘保留 TTL 或定时清理任务。请求和业务代码不再持有 Buffer 引用后,由正常的 Node.js GC 回收;Vext 不会删除应用自行保存的文件。
multipart 还要求 bodyParser 启用,不会独立注册解析链。
请有意识地设置 bodyParser.maxBodySize、multipart.maxFileSize、multipart.maxFiles 与 multipart.allowedMimeTypes。大文件、流式对象存储或任何需要持久化文件生命周期的场景,应在该路由关闭/避免内置解析,并使用由插件自身负责存储和清理策略的流式上传方案。
VextAccessLogConfig
访问日志使用响应完成事件,必要时回退到处理链完成时记录;时机、级别与大小见访问日志 API。
访问日志输出示例:
消息字段包括 HTTP 方法、路径、状态码、响应时间(ms)和客户端 IP;requestId 由 logger 的 AsyncLocalStorage mixin 自动注入到 JSON 记录字段。
VextOpenAPIConfig
OpenAPI 文档自动生成配置。
openapi.enabled 常量为 false,普通配置省略时开发模式也不会自动变 true,应显式开启;title/version 未填写时生成器回退 VextJS API / 1.0.0。文档权限、sources、code 来源的完整对象字段见OpenAPI 指南;文档访问权限不代替 API 授权。
各 code 来源的对象形式支持 enabled、dir、include、exclude、title;sources[] 支持 id、label、match、version、description、default、access、code.include/exclude。字段按来源扫描约定解释,关闭 UI 试调或隐藏菜单均不等于关闭业务接口。
docs.access.cacheKey 不是当前版本支持的配置字段。Vext 会拒绝该字段,避免让用户误以为文档访问链路已经提供 response cache 或 access result cache。
固定本地或部署 API 目标时,servers[].url 建议直接写带端口的完整 base URL,例如 http://127.0.0.1:3000。只有环境名、区域、租户或 API 版本这类真正会变化的 URL 片段,才建议使用 servers[].variables。docs.tryItOut.defaultServer 用于控制 Try it out 初始选中的 server,docs.tryItOut.customServer 用于允许用户在浏览器里临时输入其他目标地址,不需要修改项目配置。
tagGroups 只有在显式配置时才会透传为 x-tagGroups。默认 Vext Docs renderer 使用 OpenAPI path segment 构建递归导航;tagGroups 主要用于下游 OpenAPI 工具明确消费该 vendor extension 的场景。
默认 Vext Docs renderer 会从 code docs 数据生成 Services / Utils / Models / Components / Plugins / Middlewares。Model 条目可展示静态 schema fields、enums、options、indexes、methods、hooks 和 usage;Plugins 与 Middlewares 可展示可推断的 lifecycle/bootstrap、app extension、middleware 类型、route usage 和源码链接;Locales / Config / Styles / Preload 属于可选高级静态来源,可在 docs.code 下显式开启,但不进入默认顶层文档入口;本地 loopback 文档页还可为 code docs 条目展示 Open source 链接,不需要新增单独配置项。
guardSecurityMap 历史回退
用于把只声明 middleware 的历史路由映射到 OpenAPI Security Scheme。新的 Auth 示例应把最终 RouteOptions.auth 内联到路由,或保存为同文件 const,让运行时保护、静态投影和 OpenAPI security 共用同一个真相源。有限静态语法不支持 route-options helper 调用:
securitySchemes
支持的安全方案类型:
对于 in: "cookie" 的 apiKey 安全方案和 validate.cookie 参数,内置文档可以展示字段,但浏览器 Try it out 不能直接设置受限的 Cookie header。如需手动 cookie 值,请使用同源浏览器 cookie 或 HTTP 客户端。
VextRequestContextConfig
AsyncLocalStorage 请求上下文配置。
:::warning 禁用后以下功能失效:
- Logger 自动注入
requestId app.throw()自动解析请求级localeapp.fetch()自动传播requestId:::
VextFrontendConfig
内置前端构建与静态服务配置。frontend:true 使用默认启用配置,对象形式须 enabled:true。用法见前端配置。
SSR 与浏览器共享 CSS Modules 类名和资源 import URL;CSR 空 shell 使用 createRoot,完成 SSR 使用 hydrateRoot;静态 sitemap/robots 使用正确 MIME。验证步骤见渲染模式、样式与资源、静态资源与SEO。
上面的 SPA scope 示例还需要真实 shell 页面。scopes[].ssr 可按需求选择,按CSR 与 SPA fallback验证挂载与未知路径行为。
适配器扩展契约
frontend.adapter 的通用 resolver 已弃用:VextFrontendAdapter 声明的 resolveBuildOptions(config) 不会执行,配置函数时构建会明确诊断。请使用已接入的 build.client / build.server;该保留字段计划在下一个破坏性版本移除。它不会启用另一套 bundler、RSC、Server Functions 或 PPR。
frontend.seo 的完整用法见 SEO、Sitemap 与 Robots。publicOrigin 是部署 origin,不是固定页面 URL;当前 pathname 或页面显式 canonical 提供每页部分。runtime 产物只接受精确声明的 Host,provider 也不会隐式收到 app 或 app.db。
如果交付目标不是内置的本地 staging adapter,请向 deploy.upload.adapter 传入 VextFrontendDeployUploadAdapter 对象。它提供 name 和 upload(input);其 VextFrontendDeployUploadAdapterInput 包含 asset、sourcePath、uploadKey 与 dryRun,而 VextFrontendDeployUploadAdapterResult 必须返回 uploaded,并可返回 url 与 etag。
filesystem 与 mock 是仅有的内置 upload adapter 名称。云厂商适配器必须显式写在应用配置中,因此运行时不会暗中安装或发现云服务/bundler 插件。
build.client.externalRuntime 的映射值也支持 URL 字符串简写,或使用含 url / integrity / crossOrigin 的对象。
默认 spaFallback.scopes 为空,因此未知 HTML 路径不会被自动吞成 SPA 页面。需要混合 SSR + client-router 子应用时,在 scopes[] 中声明具体 basePath。spaFallback: true 仅作为兼容 shorthand,不推荐在企业级混合项目中使用。
VextClusterConfig
Cluster 多进程配置。完整接口定义见 src/types/app.ts VextClusterConfig。
基础字段
healthCheck — 心跳检测
reload — 零停机滚动重启
Windows 不支持当前 reload 信号操作,旧 Worker 退出时长连接仍可能断开,见Cluster 指南。
cluster.reload 只配置 vext reload / SIGHUP 触发滚动重启时的时间参数。省略 cluster.reload 不会禁用滚动重启,框架会使用默认值。
也可通过环境变量启用(无需修改配置文件):
VextCacheConfig
路由级响应缓存全局配置。
Memory 完整配置:
Redis 配置:
MultiLevel 配置:
cacheHub 只接受 response-cache-kit/cache-hub 配置,不接受自定义 Store。路由级响应缓存通过 RouteOptions.cache 配置。公开配置单位使用毫秒;响应头中的 Cache-Control: max-age 会按 HTTP 标准输出秒。详见 响应缓存指南。
VextDevConfig
仅开发模式使用的配置。vext dev 会读取这些字段,生产模式会忽略。
VextDevOverlayConfig
VextDevMcpConfig
dev.mcp 用于声明项目的 MCP 意图。它不会让框架执行 shell 命令、启动或重启服务、运行测试或应用业务文件修改。随包提供的 vext mcp --root <dir> stdio 服务仍只返回分析结果、机器可校验的输入错误和需要宿主执行的步骤;vext mcp sync 会按该声明写入受管宿主配置并返回回读校验与刷新提示,其中 Codex 写入用户级 Codex 配置(优先 CODEX_HOME/config.toml,否则当前用户 .codex/config.toml),命令执行、业务文件应用和宿主重启仍由 AI 宿主负责。
dev.mcp: true 表示启用默认声明。项目需要记录宿主目标或同步策略时,使用对象形式:
DEFAULT_CONFIG
下面是 DEFAULT_CONFIG 常量值快照,用于查阅,不是项目最小配置。模块回退不一定显式写在常量中,实际值还受合并层影响:
VextUserConfig
src/config/default.ts 的基础配置输入类型。框架默认值会补足省略的框架设置,因此其顶层字段可选;但一旦写出嵌套对象,该对象自身的必填字段仍然有效。尤其是 database 必须包含合法连接 config,不能把半截 database 留给后续 profile 补齐。loadConfig() 合并所有层后生成完整 VextConfig。
VextConfigOverride
用于 development.ts、production.ts、自定义 profile、local.ts 以及
createTestApp({ config }) 的路径感知 patch 类型。普通配置对象遵循运行时深度合并;
数组、函数与已注册路径在类型中保持原子值;middlewares 仍按专用规则合并。类型注册表不改变运行时 merge,见下文。
嵌套局部值只有在前层已经拥有必需的运行时数据时才成立。例如,完整 base database
存在后,profile 可以只 patch database.findLimit;createTestApp() 不会加载项目
base,因此在那里新增 database 时仍须给出完整数据库配置。
扩展原子路径
通过 module augmentation 增加的应用或插件字段默认是递归 patch。如果自定义路径
保存 client、class 实例、adapter 或其他必须整体提供的 capability,应在同一
augmentation 中把相对 VextConfig 根的点分路径加入
VextConfigOverrideAtomicPathRegistry:
注册表只影响类型,不改变运行时 merge。只有真正需要整体替换的 capability 才应 登记;普通配置对象应继续保持递归 patch。
loadConfig
配置加载函数,接收配置目录路径并执行完整配置链合并。
通常不需要手动调用,bootstrap() 内部会自动调用 loadConfig()。合并顺序为:DEFAULT_CONFIG < default < config profile < local(非生产)< bootstrap provider patch < CLI override。
环境变量覆盖
框架不会自动解析 .env*,由启动环境、部署工具或显式预加载注入;不支持把任意配置名自动转换为环境变量。
部分配置支持通过环境变量覆盖:
PowerShell 可先设置 $env:VEXT_PORT 与 $env:VEXT_CONFIG 再运行 npm start。端口须为1—65535整值;CLI 非法端口报错,直接环境覆盖非法时底层可能忽略,不以启动成功推断已采用。
类型声明扩展
插件可通过 declare module 为 VextConfig 添加自定义字段:
确保 tsconfig.include 包含声明文件;先 import vextjs 避免覆盖模块声明。配置使用 satisfies VextUserConfig 检查:
配置变更后验证
先执行已有的类型检查和构建,再重启相应进程验证实际端口、功能入口及失败路径;配置被冻结,修改文件不等于已运行实例更新。根据功能选择限流、认证与安全、Session、数据库、前端配置或Jobs API中的操作验证。首次排查确认 mode/profile、当前工作目录、provider 是否成功和 CLI 覆盖,不通过整体打印配置暴露不必要的信息。