前言
自上一篇文章Nodejs:摆脱黑工坊发展出一款基础企业级框架写到,如何封装Nodejs的Koa框架之后,反响还算不错,多谢大家的支持。
不过,上次的文章由于发表在知乎,由于知乎排版非常难看,所以大家都没看爽。
经过几个星期的努力,每晚抽出一些时间,终于把教程重新写好了,这次的教程稍微有些改动,那就是使用Typescript封装一款装饰器风格的Web框架。
具体是怎么样的呢?看图。
起因
最近一直在尝试、研究eggjs
。大量使用typescript
去编写逻辑(准备写一篇文章讲述一下一些坑)
在写egg的路由的时候,体验大概是这样的:
还不错,但是有两个不爽的地方:
- 找地址:在编写controller的时候,有时候会忘记这个controller到底是什么地址,是什么method…
- 每次写完逻辑,会忘记把controller的方法map到router.ts中去,也就是我图中说的,要来回切换文件修改。
官方的说法是,把路由集中化管理,使得我们更好的管理这些路由地址。
但是在实际中,我个人最理想的方式就是看见controller,就能知道这个函数是对应的什么地址和method。我不知道这是不是我python写多了的原因,实际上egg
强大的插件机制能够实现这一点,我打算最近搞一款egg插件,支持装饰器。
然后呢,我对其进行了小小的改造,使得eggjs能够支持装饰器路由,先来看看效果:
嘿嘿,好不错对不对?
至于怎么实现的,其实也很简单,直接在router导出的函数运行期间,用装饰器自动收集所有的路由,就可以了。
刚了一波源码
直接修改router行为,这个貌似不是太优雅,所以我在思考是不是能够自定义一个egg loader或者写一个egg-xxx插件什么的。
框架的定制那自然必须要对框架底层有所了解
因此一言不合,我直接去刚了一波源码,所以就有了这个教程,这个教程也算是我看了egg部分源码以后的一些心得,为了能够融汇贯通,我自己也仿照着写了一个,造了一波轮子。
但是和之前我造的轮子不同,这一次我记录下了整个造轮子的过程。写成了教程,分享给大家啦。
教程特色
相比上次的教程,有几大改进。
- Typescript:使用TS写成,使用装饰器(@)进行路由。
- 面向对象:controller和service全部以类方式书写
- 如何拓展koa的实例和koa的context对象
- 讲解controller和service的生命周期(与egg相同)
- 使用高级Api去处理controller和service的实例,实现高性能
- 更好的观看体验,在gitbook上。
- 每一个步骤的代码,我都保存下来了
- 免费的,但是是骗星的,觉得有收获,就点个星,给点动力
- 持续更新中…写了80%,还差实战部分以及多进程架构与进程间通信
目录
项目地址,书就在里面了:
项目地址:使用Typescript封装一款装饰器风格的Web框
- 大项目的标配Typescript
- 自动编译TS与服务器自动重启
- 路由拆分
- 引入Controller与Service的概念
- Controller的实现
- Service的实现
- 优雅的处理硬编码(配置)
- 小总结
- 路由去中心化
- 项目目录结构的变化
- (非必要)插件的实现
- 企业框架还欠缺的东西
- 抽离自己的框架burn.js
每一章节的后面都有对应的代码:
为了阅读更加舒适,我已经将教程写在Gitbook之中。
最后
诶,又来写了一个轮子,这款轮子是是系列教程《使用Typescript封装一款装饰器风格的Web框架》配套框架,全部使用Typescript编写完成。
在教程中,你将比较深入的了解到如何使用typescript&js的面向对象封装,将koa一步步的封装成为一款类egg.js的框架。
这样,你能就更深入的了解eggjs,根基更加牢固,本教程也算是eggjs typescript的一个前置教程吧。
喜欢的,给点星星,是你给我最大的支持,感谢。
我使用Typescript装饰器封装了一个node工具 iwinter 项目地址,使用装饰器对路由进行封装,简洁优雅; 目前支持: 1、支持路径装饰器 Path 及 权限拦截 2、支持 GET POST PUT DELETE 方法,可使用装饰器 @GET @POST @PUT @DELETE 3、支持获取路径参数、查询参数、post请求体及原始请求对象 PathParam, QueryParam, BodyParam, ReqParam, ResParam, CtxParam, NextParam, OriginParam 4、支持在 Express 或 Koa 中使用 使用示例:
import {Controller, Path, GET, POST, PathParam, BodyParam, CtxParam, NextParam, OriginParam} from 'iwinter';
import {PostModel} from '../models/PostModel';
import {auth} from '../auth';
@Path('/api/posts', auth)
class PostController extends Controller {
@GET
@Path('/:name/:id', (ctx, next)=> ~~ctx.params.id > 20) //Path(path:string, permission: Function)
getAllPosts(@PathParam('id') id: number, @PathParam('name') name: string, @CtxParam('ctx') ctx: any){
//ctx.response.redirect('/users');
return [{
id: id, name, content: 'test', author: 'test', comments: []
}];
}
@POST
@Path('/add')
async addPost(@BodyParam('post') post: object){
let newPost = new Post(post);
let result = await newPost.save();
return result;
}
}
export default PostController;
感觉跟你这个框架很配啊,是否考虑合作一波 : )
@yvanwangl 装饰器参数被标记为以后会有breaking change,不是很看好。而且,我的目的是为了在egg上做。
我以为你自己封装了一个框架,是时候研究一下egg了
@yvanwangl 加油。egg可以拓展的。
@yvanwangl 何必这么麻烦,已经有现成的框架了: https://docs.nestjs.com 而且原生支持 GraphQL
https://github.com/notadd/notadd/tree/next 我们写了个小项目,可以参考,也欢迎star
@这个是restful风格的
@yvanwangl restful 被 GraphQL 替代是趋势啊~ github 新版接口就是。GraphQL 就是下一代的 restful~
@新生事物要替代也是有一个阶段和周期的,话不能说太满
@yvanwangl 还是看看大厂的态度吧。GraphQL 不仅解决了restful 多次请求的问题,也解决了restful 不适合复杂业务的问题,趋势是阻挡不了的,用了就明白了。
@zuohuadong 我去年已经在用了
非常简洁的语言解释了框架由来,赞
@215566435 默默的问一句,封装框架思路怎么来的?
可以给 Egg 提一个 RFC
@hi363138911 首先,你要有自己的实践。
- 你在写第一个项目的时候,代码会非常的垃圾,遇到很多的问题。然后你摸不着头脑,一直写,直到代码不能维护。
- 直到有一天,勤奋的你看了某个教程,感受到了,很多东西都可以进行封装,然后你就尝试着去封装你原来很垃圾的代码
- 封装完成以后,你又发现,你看到了某个框架,比如egg的封装办法,你又用egg的模式,封装了你的代码
- 轻车熟路以后,你就构建出了一个类eggjs的框架,然后你去读eggjs代码的时候,特别轻松。
- 你已经学会了如何封装,就像天猪说的,用不用egg其实没事,重点是他的思想
- 用egg好了,它帮你封装好了,得心应手。
@215566435 谢谢,现在是进行 3 阶段路上
膜拜大佬!