import type { Server } from "node:http"; import { DevCompiler } from "./compiler.js"; import type { CompileStats } from "./compiler.js"; import { HotSwappableHandler } from "./hot-swappable-handler.js"; import { SoftReloader } from "./soft-reloader.js"; import type { AppInternals } from "../app.js"; import type { VextApp } from "../../types/app.js"; import type { VextServerHandle } from "../../types/adapter.js"; /** * dev-bootstrap.ts — Dev 模式启动编排(Phase 2B Soft Reload 版) * * 此文件在 ColdRestarter fork 的子进程中执行,负责: * * 1. 初始化 DevCompiler(esbuild 首次全量编译 src/ → .vext/dev/) * 2. 从编译产物目录加载配置(.vext/dev/config/) * 3. createApp 创建框架实例 * 4. 加载 i18n、plugins、middlewares、services、routes * 5. 注册内置中间件 + 错误处理 + 404 * 6. 创建 HTTP server(http.createServer + HotSwappableHandler) * 7. 创建 SoftReloader 并注册 IPC reload 消息监听 * 8. 通过 IPC 发送 `{ type: 'ready' }` 通知主进程 * 9. 注册信号处理 + 进程退出清理 * * 与生产模式 bootstrap 的区别: * * | 差异点 | 生产 bootstrap | dev-bootstrap | * |------------------|--------------------------|---------------------------| * | 代码来源 | src/ 或 dist/ | .vext/dev/(esbuild 产物) | * | TS 加载 | tsx / 已编译 JS | esbuild 预编译为 CJS | * | HTTP server | adapter.listen() | http.createServer() | * | handler 包装 | 无 | HotSwappableHandler | * | 进程通信 | 无 | IPC(ready / reload) | * | 配置加载目录 | src/config | .vext/dev/config | * | loader 加载目录 | src/ | .vext/dev/ | * | Soft Reload | 无 | SoftReloader(Tier 1/2) | * * Phase 2B 能力: * - HotSwappableHandler 包装 handler,支持原子替换 * - SoftReloader 封装完整 Soft Reload 流程(编译→清缓存→i18n→服务→路由→swap) * - IPC 消息监听:接收主进程的 `{ type: 'reload', files: [...] }` 指令 * - 级联爆炸检测 → 通过 IPC 请求 Cold Restart * - 失败回退 → 旧 handler 通过闭包继续服务 * * @module lib/dev/dev-bootstrap * @see 11d-bootstrap-cli.md §4(Dev 模式 Bootstrap) * @see 11d-bootstrap-cli.md §2(Bootstrap 改造) * @see 11d-bootstrap-cli.md §3(createApp reload 能力) * @see 11b-soft-reload.md §7(完整流程伪代码) * @see IMPLEMENTATION-PLAN.md 任务 2.4 / 2.8 */ /** * devBootstrap 返回结果 * * 包含启动后的资源引用,主要用于测试和调试。 */ interface DevBootstrapResult { /** VextApp 实例 */ app: VextApp; /** HTTP server 实例 */ server: Server; /** 服务器句柄(含 host/port/close) */ serverHandle: VextServerHandle; /** 框架内部方法 */ internals: AppInternals; /** DevCompiler 实例(可用于 dispose) */ compiler: DevCompiler; /** * 编译统计信息(首次全量编译耗时和文件数) */ compileStats: CompileStats; /** * HotSwappableHandler 实例(Phase 2B) * * 用于原子替换 requestHandler。 * Soft Reload 成功后调用 hotHandler.swap(newHandler)。 */ hotHandler: HotSwappableHandler; /** * SoftReloader 实例(Phase 2B) * * 封装完整的 Soft Reload 流程。 * IPC 消息 `{ type: 'reload', files: [...] }` 触发 softReloader.reload()。 */ softReloader: SoftReloader; } /** * devBootstrap 选项 */ export interface DevBootstrapOptions { /** * 用户项目根目录(绝对路径,包含 src/ 和 tsconfig.json) */ projectRoot: string; /** * 编译产物输出目录(可选,默认 /.vext/dev) * * 允许在测试中自定义输出路径,避免污染项目目录。 */ outDir?: string; /** * tsconfig.json 路径(可选,默认 /tsconfig.json) */ tsconfig?: string; /** * 是否禁用 IPC 通知(测试用) * * 当 true 时不调用 process.send(),避免在非 fork 场景下报错。 */ skipIpc?: boolean; } /** * devBootstrap — Dev 模式完整启动编排 * * 在 ColdRestarter fork 的子进程中执行。 * 完成 esbuild 编译 + 框架初始化 + HTTP 启动 + IPC 就绪通知。 * * 流程: * 不可重载阶段: * 0. DevCompiler.start() → 全量编译 src/ → .vext/dev/ * 1. loadConfig(outDir/config) → 从编译产物加载配置 * 2. createApp(config) → 创建 app + internals * 3. loadI18n(outDir/locales) → 加载 i18n 语言包 * 4. loadPlugins(app, outDir/plugins) → 加载并执行插件 setup() * * 可重载阶段(首次执行): * 5. loadMiddlewares(outDir/middlewares) → 加载中间件定义 * 6. loadServices(app, outDir/services) → 加载并注入服务 * 7. loadRoutes(app, outDir/routes) → 加载路由并注册到 adapter * 8. 注册内置中间件 + 错误处理 + 404 * 9. lockUse() → 锁定 app.use() * * Server 启动(Phase 2B — HotSwappableHandler): * 10. adapter.buildHandler() → 获取请求处理函数 * 10b. new HotSwappableHandler(handler) → 包装为可热替换 * 11. http.createServer(hotHandler.handle) → 创建 server * 12. server.listen() → 开始监听 * * Soft Reload 初始化(Phase 2B): * 12b. 创建 SoftReloader 实例(注入所有依赖) * 12c. 注册 IPC reload 消息监听 * * 就绪通知: * 13. IPC 发送 { type: 'ready' } * 14. 注册信号处理 * 15. 执行 onReady 钩子 * * @param options 启动选项 * @returns 启动后的资源引用 * @throws 任何启动步骤失败时抛出错误(由 dev-entry.ts 的 catch 处理) */ export declare function devBootstrap(options: DevBootstrapOptions): Promise; export {};