[Typescript]用装饰器封装Express服务(2)-服务入口

163 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

设计

服务启动,需要做的工作如下:

  • 1.接收服务参数,如启动的端口,扫描的路径.
  • 2.根据类装饰器(注解)分别实例化各个组件/bean,并添加入相应的Application缓存中.
  • 3.处理添加WsService路由
  • 4.处理添加PreComponent组件/bean
  • 5.处理添加Controller路由
        // 1.扫描路径
        application.scanBean().then(() => {
            // 2.添加wsController
            application.LoadWsController();
            // 3.添加前置组件(中间件)
            application.loadPreComponents();
            // ->添加普通组件
            // 4.添加 Controller
            application.LoadController();
            // 5.启动端口
            application.start();
        })
    }

实现

  1. 入口类装饰器

首先定义一个类,如TestApp.ts,作为项目的启动入口,使用@EnableApplication()装饰器触发一系列初始化工作

import { EnableApplication } from "./core";
// 项目使用.env文件
import dotenv from 'dotenv'
dotenv.config()

// 入口类
@EnableApplication({ port: +process.env.appPort, scanPath: ['/busi', '/sys'] })
class TestApp {

}
  1. @EnableApplication()可接收的参数有服务启动的port以及需要扫描的项目路径
import { application } from "../ioc/ApplicationContext"
import { Express } from 'express'
import express from 'express'

export const EnableApplication = (p?: { port?: number, scanPath?: string[] }): ClassDecorator => {
console.log(`========================= start EnableApplication========================`)
    return (targetClass: any) => {
        if (p) {
            if (p.port) {
                application.appPort = p.port
            }
            if (p.scanPath && p.scanPath.length > 0) {
                application.scanPath = p.scanPath
            } else {
                application.scanPath = ['']
            }

        }
        console.log(`========================= start Application========================`)
        // 实例化一个Expres
        const app: Express = express()
        application.app = app

        // 1.扫描路径
        // 在扫描完成之后,再进行其他初始化的工作
        application.scanBean().then(() => {
            // 2.添加wsController
            application.LoadWsController();
            // 3.添加前置组件(中间件)
            application.loadPreComponents();
            // ->添加普通组件
            // 4.添加 Controller
            application.LoadController();
            // 5.启动端口
            application.start();
            console.log(`========================= finish Application========================`)
        })

    }
}

如果没有传递参数,则可以使用默认的port,扫描路径为启动类同级的所有目录及其子孙代目录;实例化一个Express对象,保存至Application(后文解释)上下文中;执行scanBean方法,扫描项目各个文件.在完成扫描后,添加和构建各个组件&路由服务;最后启动端口服务.