CLI 命令
VextJS 提供了 vext 命令行工具,覆盖项目创建、开发、构建、部署的完整生命周期。
安装
vext CLI 随 vextjs 包一起安装,无需额外安装:
安装后可以通过以下方式调用:
命令概览
vext create — 创建项目
交互式创建新的 VextJS 项目,自动生成项目骨架和配置文件。默认模板是 fullstack-react;API-only 脚手架仍可通过 --template api --frontend none 创建。
用法
选项
示例
命令只接受一个项目名;多余的位置参数会在创建目标目录前直接失败。自动安装依赖失败时,create 以非零状态退出但保留已生成文件,可执行 cd <project-name> 后重新运行 npm install。生成的 TypeScript 全栈项目会为内置的 @frontend、@pages、@components、@styles 和 @assets 提供兼容 NodeNext 的路径映射。
生成的目录结构
创建完成后:
访问 http://localhost:3000,你应该能看到 React 客户端。API 路由位于 /api/hello 与 /api/health。
如需在配置冻结前拉取远程配置(例如 Nacos / 启动期数据库配置),可将 src/config/bootstrap.example.ts 复制为 src/config/bootstrap.ts 并通过 defineBootstrapConfig() 注册 provider。需要本地覆盖时,可将 src/config/local.example.ts 复制为 src/config/local.ts,该文件默认被 .gitignore 排除。
vext dev — 开发模式
以开发模式启动项目,支持文件监听和智能热重载。
用法
vext dev 不支持位置参数。--root、--port、--host、--config、--poll-interval、--debounce、--startup-profile-json、--port-conflict 等取值参数必须跟随非 option 值;数字参数必须是完整整数,3000x、50x 这类数字前缀会失败。
选项
端口冲突策略
error:直接失败(默认)prompt:在 TTY 环境下询问父进程如何处理kill:尝试终止占用端口的进程next:自动选择下一个可用端口
启动日志分层
默认 vext dev 只打印监听地址与总启动耗时,随后在 cold restart / hot reload 时打印必要结果。vext dev --startup-profile 才会输出人类可读的启动摘要与详细事件;摘要按 main/preflight、main/preload、pre-worker-bootstrap、compile、config、i18n、database、plugins、middleware、services、routes、openapi、listen、onReady 等阶段归类;超过阈值的未命名空窗会以 gap.* 形式进入 profile JSON。
--startup-profile-json <path> 只写 JSON 文件,不会自动打印摘要或 details;如需两者同时输出,可组合 --startup-profile --startup-profile-json <path>。
如需生命周期排障细节,可开启:
示例
热重载策略
vext dev 提供三层热重载策略,自动选择最优方式:
详见 热重载 章节。
src/frontend/** 下的前端文件和 public/** 下的静态资源变更会触发前端重建消息。React 页面、layout、公共组件默认走 Fast Refresh;除非同时混入后端变更,否则不需要后端 cold restart。
package.json 脚本
vext build — 构建项目
将 TypeScript 源码编译为 JavaScript,生成生产可用的 dist/ 目录;构建前会刷新 typegen 与 route manifest 这类工具产物。启用前端时,vext build 还会把浏览器客户端打包到 dist/client/。
用法
选项
示例
构建行为
- 先刷新
.vext/types/*.generated.d.ts、src/types/generated/index.d.ts、.vext/manifest/services.json与.vext/manifest/routes.json --typecheck开启时,在 generated / manifest 刷新后执行tsc --noEmit- 使用 esbuild 进行服务端编译与前端打包
- 不支持位置参数;
--outdir、--config等取值参数必须提供非 option 值 - 输出目录默认为
dist/ - 保持源码目录结构
- 默认生成
.js和.js.map文件;不会在dist/中生成声明文件 - 重复构建会自动移除已删除或重命名服务端源码留下的后端 stale 产物;
--clean表示先清空整个输出目录 - 启用前端时,会生成
dist/client/index.html、manifest.json、deploy-manifest.json、size-report.json、静态资源与 client contract 产物 - 使用
--upload-assets时,会读取dist/client/deploy-manifest.json,按 sha256 和frontend.deploy.upload.stateFile增量上传静态资源
package.json 脚本
vext dev:直接从src/加载.ts文件,通过 esbuild 即时编译,支持热重载vext build:将src/编译到dist/,生产模式从dist/加载 :::
vext deploy assets — 上传前端静态资源
读取 dist/client/deploy-manifest.json,把前端构建产物中的 JS、CSS、图片、字体和 public/** 资源上传到配置的目标。首期内置 filesystem 与 mock adapter;普通云厂商上传可通过后续自定义 adapter 承接。
用法
vext deploy assets 不支持位置参数。--manifest、--adapter、--target-dir、--prefix、--state-file 等取值参数必须跟随非 option 值,例如 --manifest dist/client/deploy-manifest.json;--manifest --dry-run 会作为缺值错误失败。
选项
示例
第二次执行时,Vext 会读取 frontend.deploy.upload.stateFile,对比每个 uploadKey 的 sha256;内容未变化的资源会跳过,不会重复上传图片、字体或稳定 public 文件。默认 deploy manifest 不包含 index.html 和 source map:HTML 仍由 Vext 服务端渲染,source map 不随 CDN 静态资源发布。
vext typegen — 生成声明并执行 service 依赖诊断(experimental)
为 app.services 与插件里的 app.extend() / defineAppExtensions<{ ... }>() 提供 generated 声明,同时执行 tooling-only 的 service 依赖检查。
用法
vext typegen 不接受位置参数。未知参数会立即失败,并输出可操作的诊断信息。--root / -C 这类取值选项必须跟随非 option 值;--root --json 会被拒绝,不会把 --json 当成路径。
选项
产物
示例
适用边界
typegen整体仍属于 tooling-only 能力,不会进入vext start的 runtime 主路径;vext dev会在 preflight 中自动执行基础typegen,vext build也会在可选 typecheck 与编译前刷新 generated 声明和 manifest;- TypeScript 语义诊断默认在 ready / reload 后异步输出;如果希望像旧行为一样阻塞启动或重载,可使用
--strict-preflight或VEXT_DEV_STRICT_PREFLIGHT=1; - TS 项目优先输出高质量类型,JS 项目允许退化到
import(...).default/unknown,但命令本身仍可用; --write-manifest会把 service 索引、app.extend()/defineAppExtensions<{ ... }>()聚合结果与服务依赖图摘要写入.vext/manifest/services.json;- 更多 generated 声明示例可结合 服务 与 插件 文档查看。
vext doctor routes — 静态路由诊断(experimental)
扫描 src/routes/ 中的静态路由元数据,输出重复路由、缺失 docs.summary、自动推断 operationId 等诊断,并可将结果落盘到 inspect / manifest 产物中。
用法
--root / -C 这类取值选项必须跟随非 option 值;--root --json 会被拒绝,不会把 --json 当成路径。
Targets
选项
产物定位
示例
当前边界
- 当前 route manifest 与 services manifest 仍分层维护,不合并为单一总 manifest;
docs.operationId缺失时,doctor 会按 runtime 行为给出auto-operation-id信息提示,而不是误报 warning;- 路由侧仍由
doctor routes --write-manifest负责;service 侧则由typegen --write-manifest负责。
vext start — 生产模式启动
以生产模式启动项目。TypeScript 项目从 dist/ 目录加载编译后的代码,需要先执行 vext build;如果缺少有效构建产物,命令会直接失败并提示使用 vext build 或开发期改用 vext dev。
用法
vext start 不支持位置参数。--port、--host、--config、--port-conflict、--startup-profile-json 等取值参数必须跟随非 option 值。
选项
示例
默认命令
当不传任何命令时,vext 默认执行 start:
Cluster 模式
如果配置中启用了 cluster,vext start 会自动进入 Cluster 模式,由 Master 进程管理多个 Worker 进程:
或通过环境变量启用:
预加载(Preload)自动注入
vext start 和 vext dev 会自动解析两类 preload 来源:
- 已安装依赖包中声明的
vext.preload - 应用项目根目录中的
preload/
在子进程启动前,这些脚本会统一通过 --import 注入。例如 @devcodex/opentelemetry 可利用包级 vext.preload 在应用代码加载前自动初始化 OpenTelemetry SDK;应用项目本身也可以直接在根目录 preload/ 中放置脚本做启动前环境桥接。
首期项目级 preload 规则:
- 目录固定为项目根
preload/ - 非递归扫描
- 项目级 preload 先执行,包级 preload 后执行
.mjs/.js直接注入.ts/.mts会在启动前编译到.vext/preload/*.mjs再注入vext dev下若preload/里的文件发生变化,会触发 cold restart
详见 预加载 (Preload)。
启动期配置 Provider
如果项目存在 src/config/bootstrap.ts,vext start / vext dev 会在配置 validate / freeze 前执行其中声明的 bootstrap config provider,并将 provider 返回的 patch 合并到最终配置中。优先级为:default < config profile < local < provider < CLI。
Cluster 模式下,Master 会把本轮 provider patch 传递给 Worker 复用,避免同一启动周期内 Master / Worker 看到不同远程配置。
package.json 脚本
:::tip 配置 profile 选择
vext start、vext build 和 vext deploy assets 默认读取 production profile,vext dev 默认读取 development profile。需要切换到自定义 profile 时:
- CLI 参数:
vext start --config sg-sit - 环境变量:
VEXT_CONFIG=sg-sit vext start
profile 名匹配 src/config/{profile}.ts(build 后对应 dist/config/{profile}.js)。
每条命令最多传入一次 --config。start、dev、build 与 deploy assets 遇到重复参数时会直接失败,不会静默采用最后一个值。
vext stop — 停止服务
停止正在运行的 Cluster 模式服务。通过读取 PID 文件发送停止信号。
用法
vext stop 不支持位置参数。--pid-file 必须跟随非 option 路径值。
选项
示例
vext stop 仅在 Cluster 模式下可用。单进程模式下直接使用 Ctrl+C 或发送 SIGTERM 信号即可优雅关闭。
vext reload — 滚动重启
触发 Cluster 模式的零停机滚动重启(Rolling Restart)。逐个重启 Worker 进程,确保服务始终可用。
用法
vext reload 不支持位置参数。--pid-file 必须跟随非 option 路径值。
选项
示例
滚动重启流程
代码更新后执行 vext build + vext reload,无需停机即可完成版本更新。适合需要高可用性的生产环境。
vext status — 查看运行状态
查看 Cluster 模式下的服务运行状态,包括 Master 进程和各 Worker 进程的信息。
用法
vext status 不支持位置参数。--pid-file、--port、--host 等取值参数必须跟随非 option 值。
选项
示例
输出示例
全局选项
所有命令都支持以下全局选项:
推荐的 package.json 脚本
常见问题
vext start 报错 "dist/ not found"
需要先执行 vext build 编译 TypeScript 代码。vext start 从 dist/ 加载编译后的 JavaScript 文件。
如果启用了前端,vext start 还要求存在 dist/client/index.html。
开发时应该用 vext dev 还是 vext start?
日常开发使用 vext dev,它直接加载 src/ 下的 TypeScript 文件,支持热重载,无需手动编译。vext start 用于生产环境。
如何指定 Node.js 版本?
VextJS 要求 Node.js >= 20.19.0。推荐在项目根目录创建 .node-version 或 .nvmrc 文件指定版本:
vext stop / vext reload / vext status 不工作?
这三个命令仅在 Cluster 模式下可用。确保配置中启用了 cluster.enabled: true 或使用了 VEXT_CLUSTER=1 环境变量,且服务通过 vext start 启动。
下一步
- 了解 热重载 的三层策略细节
- 配置 前端指南
- 学习 Cluster 多进程 的完整配置
- 查看 配置 中端口、日志等选项
- 探索 项目结构 的约定