likes
comments
collection

我是为何从eggjs升级到midwayjs的

作者站长头像
站长
· 阅读数 12

本文正在参加「金石计划 . 瓜分6万现金大奖」

今天突然发现园区的银杏叶突然全黄了,想起来两周前到临安去玩的时候还是青黄交加的一片呢。虽然最近温度似乎也没怎么降,但从最近路边的落叶上看,真的是深秋了,可能就再需要一场秋雨,杭州就要开始入冬了吧

最近笔者在维护一个旧的node项目,项目基于eggjs开发的,数据库是mysql,缓存redis,消息中间件用的是rocketMQ。项目早期用的是js,在改造typescript的过程中,越来越感觉到eggjs对typescript兼容性不好,加上midwayjs的Ioc机制是开发中的一个爽点,还是决定畅通不如短痛,升级midwayjs

midwayjs简介

先放官方文档传送门

Midway 是阿里巴巴 - 淘宝前端架构团队,基于渐进式理念研发的 Node.js 框架,通过自研的依赖注入容器,搭配各种上层模块,组合出适用于不同场景的解决方案

先看看关键字,依赖注入,对于前端同学来说,这是个相对陌生的点。也难怪,日常开发中这些使用的确实不多,java同学会了解的相对多一点,毕竟IoC能力是Java Spring 体系中非常重要的核心,而这也是MidWay的核心竞争力了。另外Midway全量使用TypeScript,结合TS装饰器,让开发体验有质的提升。项目使用中类型推导很好用,这对日常维护能起到非常正面的作用。可以先看一个官方的简单🌰

import { Provide, Inject, Get } from '@midwayjs/decorator';

// user.controller.ts
@Provide()  // 实际可省略
@Controller()
export class UserController {

  @Inject()
  userService: UserService;

  @Get('/')
  async get() {
    const user = await this.userService.getUser();
    console.log(user);      // world
  }
}

@Provide 的作用是告诉依赖注入容器,我需要被容器所加载。 @Inject 装饰器告诉容器,我需要将某个实例注入到属性上。

我是为何从eggjs升级到midwayjs的 通过这两个装饰器的搭配,我们可以方便的在任意类中拿到实例对象,就像上面的 this.userService。

为什么不是nestjs

社区内还有类似的nestjs框架,两者都是走的IoC方式,两者都是框架的封装(midwayjs-->eggjs-->koajs,nestjs-->express.js,当然midwayjs支持切换依赖的web框架),提供一些开发中过于模版化的能力,简化日常开发中的配置复杂度,让你更能专注于业务,两者并没有什么本质上的区别。midwayjs是阿里的团队开源的,nestjs是国外Trilon团队的,性能上没有做对比,应该也不会有太大的差异,没必要太纠结具体去用哪个框架

所以笔者并不太在意到底用什么框架,但是团队内的同学更熟悉eggjs,eggjs到midwayjs的学习曲线相对平滑,而且midway的文档更友好一些,基于后续维护成本的考虑,在体验并没有打折的情况下,就选定了midwayjs了

接下来先看看IoC机制,以及Typescript装饰器是什么

IoC机制与装饰器

IoC(Inversion of Control)即是“控制反转”,这并非是一种技术,是面向对象编程的一种设计思想。在Java中,IoC意味着你将设计好的对象交给容器控制,而不是在对象内直接控制,理论很抽象,看一下伪代码

/***** 下面为 Midway 内部代码 *****/
const container = new MidwayContainer();
container.bind(UserController);
container.bind(UserService);

在请求时,会动态实例化这些 Class,MidwayContainer就是依赖注入容器,midwayjs的依赖注入的实现是injection,社区还有一些其他的实现这里就不再赘述了

说到了IoC,然后不得不提的就是装饰器,当前装饰器提案已经进入到了Stage 3阶段,在标准化上也算有些进展

装饰器是一种特殊的声明,可附加在类、方法、访问器、属性、参数声明上。

装饰器使用 @expression 的形式,其中 expression 必须能够演算为在运行时调用的函数,其中包括装饰声明信息。其本质就是一个函数,它能够动态地修改被装饰的类或类成员,在这些部分的值未定义时进行初始化,或在这里已有值时,在值实例化后执行一些额外的代码。比如:

// @Controller 装饰器告诉框架,这是一个 Web 控制器类型的类,而 @Get 装饰器告诉框架,被修饰的 home 方法,将被暴露为 / 这个路由,可以由 GET 请求来访问。
import { Controller, Get } from '@midwayjs/decorator';

@Controller('/')
export class HomeController {

  @Get('/')
  async home() {
    return "Hello Midwayjs!";
  }
}

本文是深入midwayjs的第一篇,简单介绍一下IoC和装饰器相关的知识,先挖个坑,后续做一些更深入的分享

总结

midwayjs对于typescript强支持,让项目的可维护性提高了一个档次,而且midwayjs在20年的时候就已经升级了midway-serverless体系,其实已经拥有了除了作为后端应用之外的能力了。后续随着项目的升级,笔者还会继续去分享midwayjs背后一些深入的技术点,以及踩过的坑

参考资料 控制反转(IOC)和依赖注入(DI)的关系 Decorate your code with TypeScript decorators

本文正在参加「金石计划 . 瓜分6万现金大奖」