Egg-Typescript使用教程和实践(持续连载中)
发布于 3 个月前 作者 215566435 2845 次浏览 最后一次编辑是 2 个月前 来自 分享

Eggjs以微内核+各种loader的机制实现了一个拓展性极高的企业级框架,帮我们省去了很多开发业务代码时不必要的操作。

使用Eggjs配合typescript可以实现更多各种神奇的操作,例如我们一直想要的装饰器,依赖注入等等Java的东西,假以时日,eggjs能跟spring一战,使得我们热爱的nodejs能在后端开发中占据一席重要之地。

抱着不断学习精进的心态,我尝试写了这本小电子书:Egg-Typescript使用教程和实践,以把我在egg中使用ts的各种实践和坑与大家一起分享。

阅读姿势

  • 本书会以穿插eggjs/koa源码的方式进行讲解,因此需要有一个基础的同学
  • 讲解typescript的时候,最好有一些基础

为此,我在之前已经写过两篇文章:

当然,如果不阅读前置文章,其实也没关系,因为《Egg-Typescript使用教程和实践》会从实践中一步步讲解,懂最好,不懂也没关系。

书籍目录

书放在ebook文件夹中

  1. 为什么使用typescript?
    1. javascript在大型项目中的缺点
    2. typescript学习资料
  2. eggjs的typescript环境搭建
    1. 项目目录介绍
    2. 一些typescript的配置
    3. 小范围内理解eggjs加载机制
  3. typescript在egg中的基本使用
    1. 自动编译+重启
    2. service编写
  4. egg-typescript 装饰器的使用
    1. 装饰器概念和基本使用
    2. 拓展知识,面向切面编程
    3. 装饰器的思考
    4. 为eggjs封装一个装饰器路由插件
    5. json序列化和参数校验
    6. 鉴权
  5. egg ts 实战:fitness dashboard … 多谢大家支持。
27 回复

但是egg-bin目前只能观察js代码的变化,不能观察ts的,想要自动重启ts代码,需要我们做额外的工作

这句有点不准确:

  • 监控代码变更是在 egg-development 做的
  • 默认是监控所有变更的
  • 现在的问题是,ts 变更后,没有地方去触发 tsc 编译。

解决方法:

  1. 一种是 tsc 也 watch,然后 egg-development 配置一个 ts 文件的 ignore
  2. 一种是 agent 或 parent 里面监听重启事件来 触发 ts compile
  3. 一种是 egg-bin 这块扩展下
  4. 甚至还可以是 egg-core 支持加载 ts 文件,在开发期用 ts-code 无需编译

这块还没想好,目前内部的一些实践是方法 1

多谢指出错误@atian25 ,方案4,egg-core变动可能有点多,我之前的想法是在egg-bin拓展一下。

@215566435

这里我比较纠结的是要不要内置到 egg-bin 里面(有点倾向)

如果不内置那就是:写一个 egg-bin-ts 来扩展 egg-bin dev --ts 这样的。但遇到的问题就是 DRY 了,因为我们内部有 @ali/egg-bin 本身就是继承了 egg-bin 了,这样的话扩展就要 2 个地方都写。

--ts 主要是要做几件事:

  • 先执行一遍 compile
  • 自动生成 d.ts 解决应用目录下的 service , controller 等的提示
  • 启动原来的 dev
  • 监控代码变更后重新 compile (这个目前是在 egg-development 的,时序不太一致)

@atian25 这个设想跟我类似,不过不知道你们已经有一个@ali/egg-bin。最后另外加一个:编译错误崩溃 😄

@215566435 也许需要考虑下 egg-bin 也支持插件扩展的方式,类似 FIS,现在只能继承方式,而不是组合,有点不方便。

@atian25 wow,思路可以,我都没想到。egg-bin插件拓展方式可以一战!写完之后我试试。

@215566435

方案4,egg-core变动可能有点多

其实还好,就是一个 match,https://github.com/eggjs/egg-core/blob/master/lib/loader/file_loader.js#L123

但 edge case 如用户自己调用的 loader,写死了 js 后缀的,就不行。

然后就是 egg-core 边界的问题了。

说实话引入装饰器有点麻烦,要改 egg-bin,因为装饰器要用 es7,那么就需要引入 babel,更好的还是在启动的时候引入 register,自己编译需要多一层 watch,感觉多此一举,把装饰器加到控制器上,需要记录 metadata,然后在 loadController 的时候再扫出来,添加到 router 上,所以 loadController 肯定是要继承覆盖一次的。或者这个装饰器直接就加到路由上,比如 @Get(’/add/:id’) 在,直接就写成 router.get(’/add/:id’, app.contrller[methodName]),这样会简单很多。

@MiYogurt 其实引入装饰器难度不大,直接写成插件就可以了。而且不用改egg-bin阿。

@atian25 看到了,我多加研究。

@MiYogurt 安利下这个,装饰器,注解,管道,看守器 GraphQL都有~ https://docs.nestjs.cn

@MiYogurt 我个人是把 装饰器 和 TS 分开对待的,TS 对代码质量很有帮助,而 装饰器 只是语法糖,可选,两个并不是捆绑关系。

@zuohuadong 我并没有说装饰器没用,但它不是必需品,只是语法糖而已。

PS: Decorator(装饰器)Annotation(注解) 其实是两个概念 PS2: 官网英文文档我过年前就看过一遍了。

@atian25 image.png

image.png

image.png

严格意义上确实不是一个东西,但是加上 relect-metadata 功能是一样的。

@MiYogurt 我有用过… 能实现类似的功能,只是 PS 下它们是不一样的概念。

@215566435

死马:「装饰器嘛,egg / koa 的中间件就是异步装饰器… 」

  • Controller 的 Log 来示范装饰器感觉不是很恰当,Log 用 middleware 更适合
  • Controller 里面,的 declare module 'egg' 我会倾向于放到单独的 d.ts

@atian25

  1. 嗯,第一个,可以修改一下,变成鉴权。
  2. 没错,declare module 'egg’是应该搞在index.d.ts中

怒赞,刚好练习egg做项目,这次直接一起把typescript一起学习了。

@atian25 请问为何不考虑将./app目录做成可配置,这样的ts化egg项目就基本没障碍了

@wangchaoduo 没看懂「可配置」能对 TS 化有什么帮助? 现在唯一的一点小问题是 「动态加载带来的 TS 静态分析遗漏」而已。

这个通过 d.ts 的自动生成就搞定了。可以看下 https://github.com/whxaxes/blog/issues/11

@@ Richlee2016

谢谢支持,本周应该还能出错几章,最近迁移服务有点事

回到顶部