为何从eggjs升级到midwayjs的原因详解

目录
  • 引言
  • midwayjs简介
  • 为什么不是nestjs
  • IoC机制与装饰器
  • 总结

引言

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

最近笔者在维护一个旧的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 装饰器告诉容器,我需要将某个实例注入到属性上。

通过这两个装饰器的搭配,我们可以方便的在任意类中拿到实例对象,就像上面的 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

以上就是为何从eggjs升级到midwayjs的原因详解的详细内容,更多关于eggjs升级midwayjs的资料请关注我们其它相关文章!

(0)

相关推荐

  • Nodejs环境Eggjs加签验签示例代码

    加签验签概念 加签: 用Hash函数把原始报文生成报文摘要,然后用私钥对这个摘要进行加密,就得到这个报文对应的数字签名.「注意啦,加签过程要包含一些特殊的私有的东西,比如个人私钥.」 通常来说呢,请求方会把「数字签名和报文原文」一并发送给接收方. 验签: 接收方拿到原始报文和数字签名后,用「同一个Hash函数」从报文中生成摘要A.另外,用对方提供的公钥对数字签名进行解密,得到摘要B,对比A和B是否相同,就可以得知报文有没有被篡改过. 如下使用Egg.js示例代码 // 获取签名 router.p

  • React+EggJs实现断点续传的示例代码

    技术栈 前端用了React,后端则是EggJs,都用了TypeScript编写. 断点续传实现原理 断点续传就是在上传一个文件的时候可以暂停掉上传中的文件,然后恢复上传时不需要重新上传整个文件. 该功能实现流程是先把上传的文件进行切割,然后把切割之后的文件块发送到服务端,发送完毕之后通知服务端组合文件块. 其中暂停上传功能就是前端取消掉文件块的上传请求,恢复上传则是把未上传的文件块重新上传.需要前后端配合完成. 前端实现 前端主要分为:切割文件.获取文件MD5值.上传切割后的文件块.合并文件.暂

  • 为何从eggjs升级到midwayjs的原因详解

    目录 引言 midwayjs简介 为什么不是nestjs IoC机制与装饰器 总结 引言 今天突然发现园区的银杏叶突然全黄了,想起来两周前到临安去玩的时候还是青黄交加的一片呢.虽然最近温度似乎也没怎么降,但从最近路边的落叶上看,真的是深秋了,可能就再需要一场秋雨,杭州就要开始入冬了吧 最近笔者在维护一个旧的node项目,项目基于eggjs开发的,数据库是mysql,缓存redis,消息中间件用的是rocketMQ.项目早期用的是js,在改造typescript的过程中,越来越感觉到eggjs对t

  • IOS 数据库升级数据迁移的实例详解

    IOS 数据库升级数据迁移的实例详解 概要: 很久以前就遇到过数据库版本升级的引用场景,当时的做法是简单的删除旧的数据库文件,重建数据库和表结构,这种暴力升级的方式会导致旧的数据的丢失,现在看来这并不不是一个优雅的解决方案,现在一个新的项目中又使用到了数据库,我不得不重新考虑这个问题,我希望用一种比较优雅的方式去解决这个问题,以后我们还会遇到类似的场景,我们都想做的更好不是吗? 理想的情况是:数据库升级,表结构.主键和约束有变化,新的表结构建立之后会自动的从旧的表检索数据,相同的字段进行映射迁移

  • 在linux下升级软件包版本等方法详解

    Linux环境下,要想查看某个软件(package)是否安装. rpm包方式安装的,使用 rpm -qa | grep "软件或者包的名字". yum方式安装的, yum list installed | grep "软件或者包的名字". 升级软件包版本. 我们经常会遇到依赖其他版本包的情况(一般是更新的版本),这时候我们需要升级包. 1.卸载后安装新的包. 首先要根据文首提到的查看软件包是否安装的方式查看你是否安装了这个软件,若没有安装,找到路径后使用wget命令

  • SQL Server2008 Order by在union子句不可直接使用的原因详解

    按照要求,每个取top 20,既然是随机的取,那么就SQL Server Order by newid()就是了,然后把所有数据union起来就得了.所以我立即给出了答案: selecttop 20 *fromxxxwheretype=1orderbynewid() union selecttop 20 *fromxxxwheretype=0orderbynewid() 但是在sql 查询分析器种不对,语法有错,我乍一看,好像没有问题吧: selecttop 20 *fromxxxwherety

  • 详解Java中NullPointerException异常的原因详解以及解决方法

    NullPointerException是当您尝试使用指向内存中空位置的引用(null)时发生的异常,就好像它引用了一个对象一样. 当我们声明引用变量(即对象)时,实际上是在创建指向对象的指针.考虑以下代码,您可以在其中声明基本类型的整型变量x: int x; x = 10; 在此示例中,变量x是一个整型变量,Java将为您初始化为0.当您在第二行中将其分配给10时,值10将被写入x指向的内存中. 但是,当您尝试声明引用类型时会发生不同的事情.请使用以下代码: Integer num; num

  • 分析Springboot中嵌套事务失效原因详解

    首先两个事务方法,其中一个调用另一个. @Transactional(rollbackFor = Exception.class) public void trance() { try { trance1();//调用下一个事务方法. } catch (Exception e) { e.printStackTrace(); } User user = new User(); ShardingIDConfig shardingIDConfig = new ShardingIDConfig(); u

  • C++ STL标准库std::vector扩容时进行深复制原因详解

    目录 引子 查找原因 解决方法 结论 引子 但是笔者却发现了一个奇怪的现象,std::vector扩容时,对其中的元素竟然进行的是深复制.请看示例代码: #include <iostream> #include <vector> struct Test { Test() {std::cout << "Test" << std::endl;} ~Test() {std::cout << "~Test" <

  • React Diff算法不采用Vue的双端对比原因详解

    目录 前言 React 官方的解析 Fiber 的结构 Fiber 链表的生成 React 的 Diff 算法 第一轮,常见情况的比对 第二轮,不常见的情况的比对 重点如何协调更新位置信息 小结 图文解释 React Diff 算法 最简单的 Diff 场景 复杂的 Diff 场景 Vue3 的 Diff 算法 第一轮,常见情况的比对 第二轮,复杂情况的比对 Vue2 的 Diff 算法 第一轮,简单情况的比对 第二轮,不常见的情况的比对 React.Vue3.Vue2 的 Diff 算法对比

  • Angular2平滑升级到Angular4的步骤详解

    前言 Angular4终于在两天前发布了正式版本,那么怎么升级呢?其实Angular2和Angular4之间属于平滑过渡,并不像1和2之间颠覆性的重写代码. Angular4现已发布  http://www.jb51.net/article/109685.htm 为什么跳过Angular 3? 根据Angular团队首席开发Igor Minar的说法:随着Angular 2的发布,Angular团队引入了语义化版本控制规范,即:将语义化版本用三组数字来表示,按照major.minor.patch

  • CentOS中升级Python版本的方法详解

    CentOS升级Python2.6到Pythno2.7 最近在Linode上弄Python.出现ValueError: zero length field name in format这样的错误: 翻看文档之后发现只要升级Python到2.7以上版本就能解决问题. 用 Pythno -V 看了一下目前Centos上的版本是2.6的. CentOS6系列里面默认安装的都是Python2.6的版本 所以我们可能会出现这样的错误 ValueError: zero length field name i

随机推荐