浅谈阿里 Node 框架 Midway 在企业产品中的应用实践

什么是 Midway

Midway(中途岛)品牌是淘宝技术部(前淘宝 UED)前端部门研发的一款基于 Node.js 的全栈开发解决方案。它将搭配团队的其余产品,Pandora 和 Sandbox,将 Node.js 的开发体验朝着全新的场景发展,让用户在开发过程当中享受到史无前例的愉悦感。html

Midway 基于 阿里 Egg.js 框架二开,将 IoC 引入到框架中,借鉴 Nest.js,引入丰富的装饰器方法,提高开发中的用户体验。前端

midway 的一些特性以下。git

依赖注入( IoC )

首先想说说 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,能够用来减低计算机代码之间的耦合度。其中最多见的方式叫作依赖注入(Dependency Injection,简称 DI),还有一种方式叫“依赖查找”(Dependency Lookup)。github

经过控制反转,对象在被建立的时候,由一个调控系统内全部对象的外界实体将其所依赖的对象的引用传递给它。也能够说,依赖被注入到对象中。通俗地来讲,有点像上京东或者淘宝购买商品,你只须要在搜索框中输入你要购买的商品,能够选择它的分类、品牌、价格等参数,而后软件就会给你提供你心仪的商品,你只须要下单、购买、等着收货便可。简单明了,若是软件给你推荐的结果,你并不满意,咱们就会抛出异常,整个过程无需你本身控制,而是电商平台相似容器的结构来控制。web

全部的商品都会在电商平台中注册,你只须要告诉 Ioc 你是什么东西,你要买什么东西,而后 Ioc 就会在系统运行到你须要的时候,将你要的东西传递给你。同时也将你售卖的东西,交付给其余须要的地方,全部商品的建立、配送、销毁,所有由 IoC 控制。这就是控制反转。typescript

在这里插入图片描述

Midway 框架采用 injection 这个 Npm 包作 IoC 控制,这个包自己也是淘宝中途岛团队自主开发的,实现了依赖注入。编程

基于 Egg.js

Midway 是基于阿里开源的另外一款 Node 框架 Egg.js 为基础开发的。json

Egg.js 号称为企业级框架和应用而生,Egg 采用“约定优于配置”,规划了一套统一的约定,进行开发,我司现有产品采用 Egg.js 进行开发迭代,Egg.js 约束了一套目录规范和开发规范和插件规范,减小由于人的差别致使项目规范混乱,Egg.js 有很高的可扩展性,使用 Egg.js 提供的 loader 机制可让框架根据开发者本身的规划,定义默认配置,亦可覆盖 Egg.js 的默认配置。bash

由于 Egg.js 的这种高度可扩展性,给开发者提供了基于 Egg.js 封装上层框架的能力,而且 Egg.js 插件高度可扩展,而且现有生态较为完备,而且兼容 koa 的插件,生态环境很是优异。Egg.js 经过 Node 官方的 Cluster 模块,实现多进程模型,充分利用多核心 CPU 性能。另外 Egg.js 在淘宝双十一,和阿里绝大部分的 Web 系统中的表现,充分的说明了,Egg.js 优异的稳定性。数据结构

我的以为 Midway 选择 Egg.js 的缘由有如下几点:

  1. 底层基于 koa,提过封装上层框架能力;
  2. 双十一的并发量均可以支撑住(不要给我说,大家平台的流量可以比淘宝天猫双十一还要高);
  3. 兼容 koa 插件,Egg.js 插件也有几百个,一些使用率很高的框架由官方维护,例如,egg-mongoose、egg-sequelize 等等;
  4. 阿里维护的项目,而且阿里自身也在深度使用;
  5. 问题回答的效率,首先是国内的框架,你能够用中文提交 issue,另外就是回复效率很高(本人提过几个 issue,基本上一小时内就回复了,不知道是否是我问题简单的缘由)。

采用 Typescript

TypeScript是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,并且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。安德斯·海尔斯伯格,C# 的首席架构师,已工做于 TypeScript 的开发。

  • TypeScript 扩展了 JavaScript 的语法,因此任何现有的JavaScript 程序能够不加改变的在 TypeScript 下工做。
  • TypeScript 是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性。
  • TypeScript 支持为已存在的 JavaScript 库添加类型信息的头文件,扩展了它对于流行的库如 jQuery、MongoDB、Node.js 和 D3.js 的好处。而且咱们常用的宇宙第一编辑器 Visual studio code 也是 Typescript 开发的。
  • Typescript 可使用 Javascript 中的全部代码和概念,Typescript 是为了 JavaScript 开发更加容易而诞生的,Typescript 只从语义核心方面对 JavaScript 原有模型进行扩展,因此 JavaScript 能够无需修改,或少许修改便可和 Typescript 同时工做,也可使用编译器将 Typescript 转换为 JavaScript 代码。
  • Typescript 经过类型注解,提供编译时的静态检查,而且为函数提供了缺省参数,而且引入了模块的概念,能够把声明、数据、函数和类封装在模块中。使用 Typescript 相较于 JavaScript 有如下显著优点:
  1. 静态检查
  2. 大型项目的规范,使用 Typescript 更容易重构
  3. 协做能力
  4. 生产力,干净的 ES6 代码,自动完成和动态输入提升了开发者的工做效率

提供多种装饰器

由于 Midway 使用 Typescript 开发,因此支持装饰器方法。在 Java 开发中,装饰器模式很是常见,经过装饰器方法能够向一个现有的对象添加新的功能,而且不会改变对象的结构,装饰器和被装饰的对象能够独立,不会相互耦合。

举例说明,例如 Midway 提供了路由装饰器,能够直接经过装饰器方法声明路由。代码示例以下(代码来源于官方示例):

import { provide, controller, inject, get } from 'midway';

@provide()
@controller('/user')
export class UserController {

  @inject('userService')
  service: IUserService;

  @get('/:id')
  async getUser(ctx): Promise<void> {
    const id: number = ctx.params.id;
    const user: IUserResult = await this.service.getUser({id});
    ctx.body = {success: true, message: 'OK', data: user};
  }
}
复制代码

如上代码使用 @controller 声明这个类为控制器类,同时经过标注请求,声明了请求的方法,除了 @get 之外,Midway 还基于 koa-router 封装了 @post@del@put@patch@options@head@all,其余装饰器方法的示例能够经过 Midway 官方文档查看,本文只作简要介绍,后续本人可能会写一系列的 Midway 实战教程,敬请期待。

浅谈我司现有产品的技术痛点

我司基于 Egg.js 开发了一套通用 OA 产品(持续迭代中),在实际开发过程当中,体验仍是不错,可是也有一些开发体验很差的地方,由于使用 JavaScript 因此自动补齐,智能提示基本上是没法使用,虽然官方或我的提供了插件可是使用起来,老是有些不尽如人意,另外咱们的路由声明、多文件 多文件夹,维护起来很麻烦:好比说我要写一个新的接口,我须要先去 router 文件夹里面建立一份路由文件,而后在 /app/router.js 文件里引用这个文件。

在这里插入图片描述

而后再去控制器里面建立文件,编写方法,好几个文件,来回切换。因此我以为使用装饰器方法声明路由仍是很方便的。最开始尝试过使用第三方插件实现装饰器注册路由,可是体验不是很好,后续就没有继续使用了。

另外就是 JavaScript 语言自己的痛点,代码规范、接口声明、类型效验问题、多人同时开发,每一个人的开发习惯都不相同,因此长期迭代维护的项目可能会由于每一个人的习惯不一样,可维护性逐渐下降,咱们如今的私有化部署项目,不少低级 Bug 都是由于类型不对,数据结构不对等之类的引发。

若是真的要维护这个项目几年,JavaScript 灵活度很高,因此项目前期可使用 JavaScript 构建,以换取开发效率高,可是我以为若是不进行规范约束,后期几乎不可维护。从企业产品角度出发,由于 Typescript 面向对象编程语言的结构,保持了代码的整洁度,代码规范的一致性,所以我我的以为,在企业项目中使用 Typescript 更加适合。若是只是小型项目或我的项目,JavaScript 更适合灵活开发,开发效率更高。不过一切技术的选择都要从实际场景出发。任何不从实际场景出发的技术选型都是耍流氓。

使用 Midway 的意义

根据以前讲的 Midway 的特性,我简单总结了一下,使用 Midway 带来的好处,有如下几点。

  1. 使用 Midway 学习成本低,若是你以前使用过阿里的 Egg.js 框架,基本上不须要怎么学习,便可用于实际工做中
  2. 各类装饰器方法提高开发效率
  3. 使用 Typescript 使用
  4. 使用 Ioc,优化项目依赖管理
  5. 底层基于 Egg.js 兼容 Egg.js 的全部生态
  6. 采用 Typescript,强类型,面向接口编程
  7. 提供装饰器方法,简化开发

如何从 Egg 平稳迁移到 Midway

将项目从一个框架,迁移到另外一个框架,并非一件简单的事,不过把 Egg 项目重构为 Midway 还算是没有什么特别的困难,首先由于 Midway 基于 Egg.js 因此以前项目中使用的 egg 插件或 koa 插件,能够无需修改,或者少许修改,便可在 Midway 中使用,另外由于 Midway 的不少方法与 Egg.js 保持一致,因此大部分你在 Egg.js 中使用的方法,亦可在 Midway 中继续使用,目录结构这部分,与 Egg.js 大体相同,不过 Midway 在其基础上,从新对项目结构分层,将项目分为 Web 层和业务逻辑层:

├── README.md
├── README.zh-CN.md
├── dist                                ---- 编译后目录
├── logs                                ---- 本地日志目录
│   └── midway6-test                    ---- 日志应用名开头
│       ├── common-error.log            ---- 错误日志
│       ├── midway-agent.log            ---- agent 输出的日志
│       ├── midway-core.log             ---- 框架输出的日志
│       ├── midway-web.log              ---- koa 输出的日志
│       └── midway6-test-web.log
├── package.json
├── src                                 ---- 源码目录
│   ├── app                             ---- web 层目录
│   │   ├── controller                  ---- web 层 controller 目录
│   │   │   ├── home.ts
│   │   │   └── user.ts
│   │   ├── middleware (可选)            ---- web 层中间件目录
│   │   │   └── trace.ts
│   │   ├── public (可选)                ---- web 层静态文件目录,能够配置
│   │   ├── view (可选)
│   │   |   └── home.tpl                ---- web 层模板
│   ├── config
│   │   ├── config.default.ts
│   │   ├── config.local.ts
│   │   ├── config.prod.ts
│   │   ├── config.unittest.ts
│   │   └── plugin.ts
│   └── lib                             ---- 业务逻辑层目录,自由定义
│   │   └── service                     ---- 业务逻辑层,自由定义
│   │       └── user.ts   
│   ├── interface.ts                    ---- 接口定义文件,自由定义
│   ├── app.ts                          ---- 应用扩展文件,可选
│   └── agent.ts                        ---- agent 扩展文件,可选
├── test
│   └── app
│       └── controller
│           └── home.test.ts
├── tsconfig.json
└── tslint.json
复制代码

另外就是在使用 Typescript 后,开发者须要编写接口定义,和声明文件,不过我相信,你们学习一些 Typescript 知识之后,这些都不是问题。另外,是否须要重构项目也要从实际状况出发,应先实际调研,当前项目是否规范混乱,难以维护,另外就是重构的意义是否大于重构的成本。若是你的项目尚未开始实施,或刚刚开始实施,若是你想使用 Typescript 做为产品语言,我以为 Midway 能够做为你的框架选型之一,另外可能有些人会说,若是我都要写 Typescript 了,为何我不用 Nest.js 呢?我以为框架选型仍是要从实际出发,你就直接使用,而是要看,这个框架的性能,稳定性,维护团队,将来规划等等方面出发,我选择 Egg.js,选择 Midway 首先是由于它的维护团队是阿里巴巴,性能稳定,另外就是有 IoC 机制,优化了开发体验。

相关文章
相关标签/搜索