项目结构
本页用于判断一个文件应由谁维护、在哪里执行,以及哪些产物应由工具生成。先完成快速开始再阅读;以下默认路径以 TypeScript 全栈模板为准,可配置路径见前端配置。
目录导航
默认目录
npx vextjs create my-app 默认生成 TypeScript 全栈项目。下面列出主要源码;config 中还会生成环境和 bootstrap 配置,详见服务端项目结构。
业务文件按需要增加,模板没有预先生成下面所有目录:
需要通过固定 URL 访问的文件放 public/**。src/frontend/assets/** 中支持的图片与字体可以直接 import 到页面或组件;SSR 与浏览器共用产物 URL。资源是否内联或带 hash 取决于实际构建配置。
前端源码边界
服务端和浏览器文件必须分开。
不要从 src/frontend/** import src/services/**、数据库客户端、密钥、node:* 或 route handler。默认开启的 frontend.build.diagnostics.leakScan 会检查已知服务端路径和 Node 模块边界,但它不等于识别所有私有数据或第三方包副作用。即使文件放在共享目录,也要检查实际依赖;关闭扫描不会使服务端代码变得适合浏览器。
表中页面和组件的运行位置以开启 SSR 与 hydration 为前提;关闭某一侧渲染时,对应执行阶段也会变化。页面和组件在 SSR 阶段可能执行,渲染期间不能无条件访问 window、document 等浏览器对象。pages/_document.html 是文档模板,不能按 React 页面组件使用。
类型目录边界
TypeScript 全栈 starter 通过三层类型目录表达所有权,而不会再预设一套后端类型树:
vext typegen 的声明主体在 .vext/types/services.generated.d.ts 和 .vext/types/app-extensions.generated.d.ts;TypeScript 项目的 src/types/generated/index.d.ts 引用它们。选择哪些声明由命令选项决定,--write-manifest 还会写 .vext/manifest/services.json。工具不会重写应用维护的 shared/** 或 frontend/**,也不会因为放进这两个目录就自动保证类型可序列化。
脚手架不会预留 src/types/server/**。只被单个 route 或 service 使用的服务端类型,应放在该 owner 附近;只有应用形成真实的服务端共享边界时,再自行建立应用自定义的服务端目录。
自动生成文件
前端构建会生成浏览器入口、SSR 入口和注册表。默认布局的主要产物如下;可选功能还会产生附加文件,不应把这张图当成完整部署清单。
应用维护者编辑 src 下自己的路由、服务、UI、配置和类型,以及 public 资源;不要手写 .vext/generated/frontend/** 或生成声明。页面、layout 和错误页登记在 page-registry.ts 中;词典仅在前端国际化启用时扫描并登记到同一文件,不分别生成 layout-registry.ts 或 locale-registry.ts。
前端开发输出默认在 .vext/client/,生产输出默认在 dist/client/;frontend.outDir 可显式覆盖,CLI --outdir 的联动规则见构建指南。SSR renderer 与浏览器资源必须成套交付,不能只上传 assets/ 就认为服务端页面已发布。
Alias
前端 resolver 提供默认 alias,下面是默认配置下的映射:
在完成快速开始的组件示例后,可以这样导入已有组件:
调整 frontend.root、pages.dir、componentsDir、assetsDir 或 styles.entry 时,默认 alias 会跟随解析后的目录;@styles 指向样式入口所在目录。自定义 frontend.alias 值相对前端根解析,并可覆盖同名 alias。TypeScript 编辑器使用的 tsconfig.json 的 paths 也需保持一致,运行时 resolver 不会替你重写这份配置。
root、publicDir、entry 等路径相对项目根,而页面、组件、样式、资源路径通常相对前端根;修改目录前先核对配置中的具体字段。
静态文件
默认 publicPath: "/" 时,模板已有的 public/favicon.svg 可按下面的 URL 引用。这是可嵌入页面的组件片段:
需要展示模板标识时,同样直接引用已有 Public 资源:
这个示例使用稳定的 Public URL。也可以 import 支持的 PNG、SVG 等图片或字体;SSR 构建会复用浏览器构建确认的公开 URL,包括内联 data URL 与 CDN 前缀,不需要自行修改生成文件。
对已有、确实支持资源 import 的浏览器入口,TypeScript 若缺少资源模块声明,可在应用维护的类型目录添加声明,例如:
声明只帮助类型检查,文件仍需真实存在并属于支持的资源格式。更多格式、CSS Modules 和媒体处理见样式与资源。
public/** 会复制到前端输出目录并进入静态资源清单。不要放服务端配置或其他不应公开的文件;开发与生产的本地服务按配置的 publicPath 提供资源,CDN URL 改写另见静态资源与 CDN。
API-only 项目
创建时关闭前端:
已有项目可以在默认配置中合并下面的设置;这是一段配置片段:
frontend: false 与 { enabled: false } 都关闭内置前端构建和静态/页面处理。已有 route 中的 res.render() 也必须改成 API 响应或删除,否则会报前端未启用;关闭配置不会自动删除磁盘上已有的构建目录。
验证目录调整
在应用根目录执行已有命令:
typegen --check 检查生成文件是否与当前源码一致,并执行工具自身的诊断,不代替 TypeScript 类型检查;默认 TypeScript 模板的 npm run build 含 --typecheck,自定义 build 脚本需自行确认。确认严格构建通过、页面和导入资源都在本次构建中;启动后实际访问调整过的 URL 和资源。若只有编辑器报 alias 错误,检查 tsconfig paths;若浏览器构建报告 boundary leak,检查 UI 的完整导入链;若页面不存在,检查 page id 与 pages.dir,不要通过修改生成注册表修补。完整运行示例继续使用快速开始。