应用

一个应用即是一个继承 App 的类。

配置应用

通过覆盖 App 类上的配置属性值来自定义应用,同时,应用还提供多个生命周期以供扩展。完整的应用配置选项可以参考 IAppConfig

import { App, IAppConfig } from 'bwcx-ljsm';

class OurApp extends App {
  // 应用根目录
  protected baseDir = __dirname;

  // 需要被容器扫描和装配的文件 glob(基于 `baseDir`,具体概念请参考依赖注入章节)
  protected scanGlobs = [
    './**/*.(j|t)s',
    '!./**/*.d.ts',
  ];

  // 监听端口
  protected port = 3000;

  // 监听 hostname
  protected hostname;

  // 退出超时时间
  protected exitTimeout = 5000;

  // 要加载的插件
  protected plugins = [];

  // 要加载的全局中间件
  protected globalMiddlewares = [];

  // 要加载的全局守卫
  protected globalGuards = [];

  // 默认响应处理器
  protected responseHandler: IAppConfig["responseHandler"];

  // 数据校验选项
  protected validation: IAppConfig["validation"] = {};

  // 应用初始化前
  async beforeInit() {}

  // 应用装配前
  async beforeWire() {}

  // 应用装配完成后
  async afterWire() {}

  // 应用启动前
  async beforeStart() {}

  // 应用成功启动后
  async afterStart() {}

  // 应用退出前
  async beforeExit() {}
}

引导应用

对于一个实例化的应用对象,调用 bootstrap() 以启动引导,应用将自动完成初始化、插件激活、路由装配等流程。所有围绕 initwire 的生命周期钩子均会被执行。

大多数情况下,你可能会将 Controller 和其他业务逻辑放置在和 App 不同的模块中以更好地组织代码,这时需要先执行依赖扫描(app.scan())以保证引导时所有依赖都已备妥。

const app = new OurApp();
app.scan();
app.bootstrap(); // 注意,这是一个异步操作,其会返回应用装配数据

启动应用

对于已完成引导的应用,调用 start() 以启动服务器,所有围绕 start 的生命周期钩子均会被执行。另外,在服务器接收到非强制退出信号时,beforeExit 钩子会被执行,可以在此进行一些清理工作。其最长等待时间由 exitTimeout 配置项决定。

app.start(); // 这也是一个异步操作,会返回已监听的 http.Server 对象

TIP

尚不支持多应用,每个进程仅可存在一个被引导的应用。

停止应用

你可以手动停止已启动应用,这将会关闭所有连接并关闭监听。

app.stop(); // 这还是一个异步操作

清理应用

在某些时候,你可能要清理 app 实例在装配和启动中带来的副作用(如注册的进程退出钩子),在确保应用已停止后即可执行清理,这对诸如服务端 HMR 等场景可能会有用。需要注意的是,这个操作并不会清理已扫描的依赖,如需重置容器,请使用 resetContainer()

app.clear();