Cabloy5.0 采用 TS 对整个全栈框架进行了脱胎换骨般的大重构,并且提供了更加优雅的 ts 控制反转策略,让我们的业务开发更加快捷顺畅
后端 | 前端 | |
---|---|---|
旧版 | js 、egg2.0 、mysql | js 、vue2 、framework7 |
新版 | ts 、egg3.0 、多数据库兼容(支持 mysql 、postgresql ) | ts 、vue3 、quasar |
TS 化:这是显而易见的趋势,不必赘言
ESM 化:从目前趋势看,前端框架已经全链路 ESM 化了,但是,大多数后端框架仍然是 Commonjs 。即便是 egg3.0 也仍然是 Commonjs 。由于 egg 的定位仍然是元框架,CabloyJS5.0 在 egg 基础上仍然开发出了全量 ESM 化的业务模块化系统(在 Commonjs 之上进行 ESM 化的具体机制是什么,另有文章阐述)
基于 TS 的后端框架一般都会提供依赖容器,实现控制反转。控制反转有两种策略:依赖注入和依赖查找。CabloyJS5.0 同时支持依赖注入和依赖查找,并且通过模块范围的辅助,让依赖查找的代码更加简洁高效,下面挑几个特性举例说明:
在 CabloyJS 中,local bean 相当于 nestjs 中 service 的概念,下面创建一个 local bean
import { BeanBase, Local } from '@cabloy/core'; import { ScopeModule } from '../resource/this.js'; @Local() export class LocalHome extends BeanBase<ScopeModule> { async echo({ user: _user }) { return `Hello World!`; } }
通过@Local
声明 LocalHome 是一个 local bean
LocalHome 继承自基类 BeanBase
接下来,在 Controller 中采用依赖注入的方式来使用 LocalHome
import { BeanBase, Controller, Use } from '@cabloy/core'; import { ScopeModule } from '../resource/this.js'; import { LocalHome } from '../local/home.js'; @Controller() export class ControllerHome extends BeanBase<ScopeModule> { @Use() home: LocalHome; async echo() { const res = await this.home.echo({ user: this.ctx.state.user.op, }); this.ctx.success(res); } }
@Use
注入 LocalHome接下来,在 Controller 中采用依赖查找的方式来使用 LocalHome
import { BeanBase, Controller } from '@cabloy/core'; import { ScopeModule } from '../resource/this.js'; @Controller() export class ControllerHome extends BeanBase<ScopeModule> { async echo() { const res = await this.scope.local.home.echo({ user: this.ctx.state.user.op, }); this.ctx.success(res); } }
this.scope.local
来访问容器中的 local bean 实例看一下动画演示,提供了完整的类型智能提示:
可以为业务模块单独定义一些 Config 配置,如下:
import { CabloyApplication } from '@cabloy/core'; export const cOnfig= (_app: CabloyApplication) => { return { + prompt: 'hello world', }; };
可以在 LocalHome 中直接使用刚才定义的 config
import { BeanBase, Local } from '@cabloy/core'; import { ScopeModule } from '../resource/this.js'; @Local() export class LocalHome extends BeanBase<ScopeModule> { async echo({ user: _user }) { + return this.scope.config.prompt; - return `Hello World!`; } }
this.scope.config
来访问当前业务模块中的 config 配置看一下动画演示,提供了完整的类型智能提示:
可以为业务模块定义语言资源,比如,这里分别定义英文和中文两种语言资源
英文
export default { HelloWorld: 'Hello World', };
中文
export default { HelloWorld: '您好世界', };
可以在 LocalHome 中直接使用刚才定义的语言资源
import { BeanBase, Local } from '@cabloy/core'; import { ScopeModule } from '../resource/this.js'; @Local() export class LocalHome extends BeanBase<ScopeModule> { async action({ user: _user }) { + // 自动判断当前语言 + const message = this.scope.locale.HelloWorld(); + // 强制使用英文资源 + const message1 = this.scope.locale.HelloWorld.locale('en-us'); + // 强制使用中文资源 + const message2 = this.scope.locale.HelloWorld.locale('zh-cn'); + return `${message}:${message1}:${message2}`; - return this.scope.config.prompt; } }
this.scope.locale
来访问当前业务模块中的语言资源看一下动画演示,提供了完整的类型智能提示:
可以为业务模块定义错误码
export enum Errors { + Error001 = 1001, }
可以为错误码定义语言资源,比如,这里分别定义英文和中文两种语言资源
英文
export default { + Error001: 'This is a test', HelloWorld: 'Hello World', };
中文
export default { + Error001: '这是一个错误', HelloWorld: 'Hello World', };
可以在 LocalHome 中直接使用刚才定义的错误枚举值,并抛出异常
import { ScopeModule } from '../resorce/this.js'; @Local() export class LocalHome extends BeanBase<ScopeModule> { async action({ user: _user }) { + // 直接抛出异常 + this.scope.error.Error001.throw(); - return this.scope.config.prompt; } }
this.scope.error
来访问当前业务模块中的错误枚举值看一下动画演示,提供了完整的类型智能提示:
Cabloy4.0 中就已经提供了大量业务能力,比如:工作流引擎、表单引擎、权限引擎、字段权限、多级缓存、模块化体系、分布式架构、多租户引擎,等等。随着 Cabloy5.0 Typescript 的赋能,这些业务能力也随之有了全新的表现
欲了解更多,请关注每晚 8 点 B 站直播:濮水代码
![]() | 1 isbase 2024-04-05 23:55:03 +08:00 看起来用法没有 tegg 简洁 |
2 zachwei 2024-04-06 08:35:45 +08:00 好像 Java |
![]() | 3 iPhone15 2024-04-06 13:01:54 +08:00 via iPhone ![]() 对这些概念完全不感冒,我信仰 FP |
![]() | 5 mmdsun 2024-04-06 21:52:07 +08:00 via iPhone ![]() @uni 后端 FP 的话看看 Vert.X 、Spring Webflux ?不过不支持 js 就是了,Java 、kotlin 、Groovy 语言 |
![]() | 7 newghost 2024-04-07 12:36:11 +08:00 看 react hooks 去继承化是趋势,使用继承会导致 JS 的内存对象原型链依赖过长,不利于内存的快速回收,加大内存泄露的风险 都用上装饰器了,像 extend BeanBase<ScopeModule> 其实都可以写进装饰器里。否则就太像 JAVA 了 |