作者:小爝
链接:https://www.zhihu.com/question/389662868/answer/1450706998
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先我的typescript用的时间蛮久了,但是我并不是一个type大师,所以虽然用了很久的typescript来写后端服务,但是也不是很精通各种type的用法。

一直以为语言和工具是被人用,而不是人被语言工具所束缚,所以硬说ts哪里写后端好,我还是要力推装饰器这个特性。

大家都知道,用nodejs来写后端,net,http,https模块是必须要接触的,后来有人觉得太麻烦,封装了一个叫express的库,后来又有人设计了koa,更方便的解决了中间件的编写问题。

基本上大家以为这也就走到头了,直到ts的出现,装饰器的支持,nestjs出现了。大部分写了很久的nodejs的人都是用习惯了弱类型的,突然切换到了强类型(any除外)上后确实是有一些三观改造的感觉。

终极的web框架是什么样子我不太确定,但是IoC确实是个好东西,很多人和库都在nodejs的web框架上开始尝试使用这种技术来改造自己的设计。

这里我简单的来说一下,大概简单理解是个什么东西。

我们利用typescript的装饰器特性,帮助你定义的class来自动注入框架内部的IoC容器,把类的依赖,引用,初始化委托给了web框架自身。

这样我们就大大的降低了一些隐形的维护成本,比如我们不再需要把一坨controller导来导去的做定义初始化。我们也不需要再过程式的设计路由里的函数,传递复杂的request context。

说白了,一般的IoC web框架都是利用了这一点来设计的,既我定义一个web服务的方方面面,你来做具体的实现,我来帮你来调用和组合(内部也会有内置的DI)

看到没有,大型项目中这种设计非常的受用,解放了大量的无用的逻辑维护成本,也增强了代码的复用性和OOP程度。

我18年的时候就写了一个基于koa的纯typescript web框架,但是当时并没有用依赖注入的方式来做这个设计,而是选择了自己维护依赖再动态初始化的方法,后来我用了inversifyJS来重新设计了这一套实现。

我们从里面看一个最简单的例子:

@service()
class Logger {
  public ctx!: DarukContext;
  public info(msg) {
    let path = this.ctx.path;
    console.log(msg, path);
  }
}

@controller()
class Index {
  @inject("Logger") public logger;
  @get("/index")
  public async index(ctx: DarukContext, next: Next) {
    ctx.body = "index";
    this.logger.info("access");
  }
}

我们定义了一个logger的service,由于service的类是可以方便获取ctx的,我们在其他的service或者controller里就可以不再反复的传递这个ctx参数到下一个调用方法中。这对日志染色和追踪好处也很多。

而更明显的好处是,我们可以方便的测试我们的各种service,只需要mock一个ctx给他执行即可。

更多概念上的解释可以参考我发的文档地址,Daruk 目前我可以说是上手成本最小也更偏向koa开发者用户体验的typescript web framework框架了。

因为他真的是只需要一个ts-node和tsc就可以上手开发编写web服务的框架,不需要脚手架,不强制目录结构,又可以帮你把代码维护成类组织形式的框架了。

如果对这个typescript框架感兴趣欢迎私信我,拉大家进讨论组,一起学习ts,一起做更好的typescript web服务框架。

最后,项目地址:

https://www.zhihu.com/question/389662868/answer/1450706998