1.0.11 • Published 9 months ago

@iocore/boot v1.0.11

Weekly downloads
-
License
-
Repository
-
Last release
9 months ago

@iocore/boot

npm version

IoCore 应用程序引导模块。

提供了一个标准的启动流程 (Boot.Strap),用于加载配置、初始化应用程序、处理全局异常和优雅退出。

安装

npm install @iocore/boot @iocore/component @iocore/logger async-exit-hook yaml glob --save
# or
yarn add @iocore/boot @iocore/component @iocore/logger async-exit-hook yaml glob

依赖

  • @iocore/component: IoCore 核心组件系统。
  • @iocore/logger: 用于记录日志。
  • async-exit-hook: 用于注册异步退出钩子,确保在进程退出前能执行清理逻辑 (如 Application.terminate)。
  • yaml: 用于解析 YAML 配置文件。
  • glob: 用于查找匹配模式的文件 (在 preload 方法中使用)。

使用

通常,你的应用程序入口会继承 Boot 类,并使用静态方法 Boot.Strap 来启动。

1. 创建入口类 (例如 src/main.ts)

import 'reflect-metadata'; // 必须在顶部导入
import Boot from '@iocore/boot';
import { resolve } from 'node:path';
// 导入你需要自动加载的服务/控制器等 (确保它们使用了 @Application.Server 或 @Component.Injectable)
import './services/MyService';
import './controllers/HomeController';
// 也可以导入其他 IoCore 模块,如 Http, IORedis 等
import Http from '@iocore/http';

// 你的主应用程序类继承自 Boot
@Application.Server
class MainApp extends Boot {

  // 注入 Logger (Boot 基类已提供)
  // private readonly logger: Logger;

  // 注入其他需要的服务
  @Application.Inject(Http)
  private http: Http;

  // Boot 类已经实现了 initialize 和 terminate,但你可以覆盖它们
  // public async initialize(): Promise<void> {
  //   this.logger.info('Custom initialize logic running...');
  //   await super.initialize(); // 如果需要,调用基类实现
  // }
  // public async terminate(): Promise<void> {
  //   this.logger.info('Custom terminate logic running...');
  //   await super.terminate();
  // }

  // 可以在这里添加应用的主要逻辑,或者通过其他组件实现
  async startServices() {
    this.logger.info('MainApp started, binding routes...');
    // 例如,使用 preload 自动绑定 HTTP 控制器
    // await this.preload(
    //   resolve(__dirname, 'controllers'), // 控制器目录
    //   'controller', // 文件后缀 (匹配 *.controller.ts/js)
    //   async ({ url, clazz }) => {
    //     this.logger.debug(`Binding HTTP controller: ${url}`);
    //     // @ts-ignore 假设 clazz 是 Controller 类型
    //     await this.http.bind(url, clazz);
    //   }
    // );
  }
}

export default MainApp; // 必须默认导出入口类

2. 创建配置文件 (例如 iocore.configs.yaml)

# 日志模块配置 (如果使用了 @iocore/logger)
# (log4js 配置)

# HTTP 模块配置 (如果使用了 @iocore/http)
IOCORE_HTTP_CONFIGS:
  port: 3000
  keys:
    - "a_secure_random_key"
    - "another_secure_key"

# IORedis 配置 (如果使用了 @iocore/ioredis)
IOCORE_IOREDIS_CONFIGS:
  host: "localhost"
  port: 6379

# 其他 IoCore 模块的配置...
# MY_CUSTOM_CONFIG: value

3. 启动脚本 (例如 scripts/start.js 或直接使用 iocore cli)

// scripts/start.js
import Boot from '@iocore/boot';
import MainApp from '../src/main'; // 导入你的入口类

// 使用 YAML 文件启动
Boot.Strap('iocore.configs.yaml', MainApp);

// 或者直接传入配置对象
// Boot.Strap({
//   IOCORE_HTTP_CONFIGS: JSON.stringify({ port: 4000 }),
//   IOCORE_IOREDIS_CONFIGS: JSON.stringify({ host: '127.0.0.1', port: 6379 })
// }, MainApp);

或者使用 @iocore/cli:

npm install -g @iocore/cli # or yarn global add @iocore/cli
iocore start -e src/main.ts # 使用默认 yaml 文件
# or
iocore start myconfig.yaml -e src/main.ts # 使用指定 yaml 文件

Boot (抽象类)

继承自 Application

  • logger: Logger (注入): 提供一个 @iocore/logger 实例用于日志记录。
  • initialize(): void: 空实现。子类可以覆盖以添加自定义初始化逻辑。
  • terminate(): void: 空实现。子类可以覆盖以添加自定义终止逻辑。
  • static Strap<T extends object, U extends Boot>(yaml: string | T, clazz: INewAble<U>): void: 核心启动方法。
    • yaml: YAML 配置文件的路径,或者一个包含配置的对象。
    • clazz: 继承自 Boot 的应用程序入口类。
    • 流程:
      1. 如果 yaml 是字符串路径,读取并解析 YAML 文件。
      2. 将配置对象中的所有键值对设置为 process.env 的环境变量 (如果值不是字符串,会 JSON 序列化)。这是 IoCore 模块读取配置的主要方式
      3. 调用 Application.create(clazz) 来创建并初始化应用程序实例 (及其所有依赖)。
      4. 注册全局错误处理钩子 (uncaughtException, unhandledRejection 等),将错误信息通过注入的 logger 输出。
      5. 使用 async-exit-hook 注册一个退出钩子,确保在进程退出时调用 Application.terminate() 来优雅地关闭所有 Application 组件。
  • preload<T extends Component>(directory: string, suffix: string, callback?): Promise<void>: 辅助方法,用于动态加载和处理指定目录下的组件文件。
    • directory: 要扫描的目录路径。
    • suffix: 文件后缀名 (不含 .ts.js),例如 controller, service
    • callback: 可选的回调函数,会对每个加载的文件执行。回调参数包含 file, path, url (相对路径,去除了后缀), wrap (组件的 Wrap 实例), clazz (组件类)。
    • 逻辑: 使用 glob 查找 directory 下所有 **/*.${suffix}.{ts,js} 文件,动态 import 它们,预加载默认导出的 Component 类 (Application.preload),并执行 callback

贡献

欢迎提交 Pull Request。对于重大更改,请先开一个 Issue 来讨论您想要更改的内容。

许可证

MIT

1.0.11

9 months ago

1.0.10

9 months ago

1.0.9

9 months ago

1.0.8

9 months ago

1.0.7

10 months ago

1.0.6

10 months ago

1.0.5

10 months ago

1.0.4

10 months ago

1.0.3

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago