Aller au contenu principal

· 3 minutes de lecture
Harry Chen

升级请参考 如何更新 Midway 中描述,请不要单独升级某个组件包。

很高兴给大家介绍我们的 3.11 新版本。

安全性更新

Upload 组件增加了安全性性能,在 file 上传模式下,我们发现在某些情况下文件的后缀和实际内容不匹配,导致可能会在服务器被动执行的安全性漏洞。

新版本我们增加了一个 MIME 配置,可以在上传时检查扩展名之外,额外检查 MIME 的类型,会更加安全。

export default {
// ...
upload: {
// ...
// 仅允许下面这些文件类型可以上传
mimeTypeWhiteList: {
'.jpg': 'image/jpeg',
}
},
}

更多细节可以查看我们的 Upload 组件

New Feature

精细化的 Mock 能力

基于框架新提供的 @Mock 装饰器,可以方便的在不同的阶段进行数据模拟。同时作为逻辑的一部分,这个功能可以在开发和测试期被自动执行,方便用户的开发期模拟数据。

文档请参考 数据模拟

中间件的 Match/Ignore

Middleware 的功能进一步增强,match 和 ignore 现在可以是 stringregexpfunction 或者他们的数组组合形式。

本地定时任务组件

之前我们提供了 bull 组件,用于分布式定时任务,在某些场景下,我们依旧需要单机的定时任务来赋值完成一些事项,原有的 task 组件实现了 cron 的部分,我们将其分离为 cron 组件,继续提供能力支持。

文档请参考 cron 组件

标签组件

一种抽象化的服务端能力,用于数据筛选和处理。

文档请参考 标签组件

· 4 minutes de lecture
Harry Chen

新年快乐。

升级请参考 如何更新 Midway 中描述,请不要单独升级某个组件包。

这个版本更新了许多东西,请耐心看完。

Breaking

首先是 Breaking 的部分,这部分并非是框架本身的 API 变更,而是依赖或者行为可能会影响少部分用户,需要注意的部分。

  • 1、 @midwayjs/consul 依赖的 consul 模块从 0.x 升级到 v1 正式版,API 可能有更新(consul.acl 变更为 consul.acl.legacy),具体请查看 文档
  • 2、@midwayjs/jwt 依赖的jsonwebtoken 模块由于安全性问题,从 v8 升级到 v9,API 可能有更新,更多情况请查看 文档
  • 3、由于新增的 @Pipe 功能,@midwayjs/validate 新版本无需使用 @Validate 装饰器即可校验,可能会影响一部分之前未编写装饰器但是新版本却被验证的场景,具体请看下面关于 @Pipe 的介绍或者相关的文档。

New Feature

Pipe

新版本新增了一项 Pipe 能力,可以使参数装饰器的能力更进一步。

藉由此能力,新版本的 Validate 组件不再需要 @Validate 装饰器,代码会更加简洁。

旧:

@Controller('/api/user')
export class HomeController {

@Post('/')
@Validate()
async updateUser(@Body() user: UserDTO ) {
// user.id
}
}

新:

@Controller('/api/user')
export class HomeController {

@Post('/')
async updateUser(@Body() user: UserDTO ) {
// user.id
}
}

针对非 DTO 类型的校验,现在也可以使用 Pipe 进行处理,如果是字符串,会自动转为数字,并进行校验。

@Controller('/api/user')
export class HomeController {

@Post('/update_age')
async updateAge(@Body('age', [ParseIntPipe]) age: number ) {
// ...
}
}

当然 Pipe 的功能不仅如此,更多功能请查看 完整文档

TypeORM Logger

当 typeorm 组件未配置 logger 属性时,新版本会自动创建一个 typeormLogger 用于存储执行的 sql。

默认配置为:

midwayLogger: {
clients: {
typeormLogger: {
lazyLoad: true,
fileLogName: 'midway-typeorm.log',
enableError: false,
level: 'info',
},
},
}

lazyLoad 为新增的属性,可以使 logger 在一开始仅保留配置,等实际 getLogger 时才做初始化。

@Singleton 装饰器

简化原有的写法:

旧:

@Scope(ScopeEnum.Singleton)
@Provide()
class SingletonService {}

新:

@Singleton()
class SingletonService {}

app.getNamespace API

通过 app 上新增的 getNamespace API ,可以获取到当前的 app 归属框架的类型。

比如:

import { Application } from '@midwayjs/web';

@Controller()
class HomeController {

@App()
app: Application;

async invoke() {
// this.app.getNamespace() => 'egg'
}
}

其他的一些变化

  • 1、调整@midwayjs/core 默认 logger level 为 info,的 coreLogger 在服务器环境继续保留 warn
  • 2、faas 模块新增一些自定义触发器类型
  • 3、在 jest 测试环境下,初始化的报错之前会被 jest 吞掉,新版本会通过 console.error 进行输出
  • 4、修复 configuration 的 stop 生命周期,将以 imports 顺序的逆序执行
  • 5、修复 bootstrap 使用 sticky 模式时,文件上传时的错误
  • 6、支持 swager 的属性多类型展示
  • 7、在 midway-bin dev 下,应用在本地开发时也可以快速使用 --ssl 来启动 https 服务

· 4 minutes de lecture
Harry Chen

大促积攒了约两周的需求,统一在 v3.9.0 发布。

升级请参考 如何更新 Midway 中描述,请不要单独升级某个组件包。

Breaking

从 v3.9.0 开始,Midway 仅支持 Node.js >=12.11.0 版本。

Features

1、bootstrap 新增进程模型

从 v3.9.0 开始,为了应对 socket.io 在 pm2 场景下的粘性会话,我们新增一种 master-worker 模型支持。简单来说,将由 pm2 来启动 midway 的 master,在 master 启动 worker,这样可以相对自由的定制 master 中的逻辑。

原有的 Bootstrap 之外,新增了一个 ClusterManager 来处理进程,示例如下:

const { ClusterManager, Bootstrap } = require('@midwayjs/bootstrap');

const clusterManager = new ClusterManager({
// 执行的子进程文件
exec: __filename,
// 进程数
count: 2,
});

if (clusterManager.isPrimary()) {
// 启动主进程
clusterManager.start();
} else {
// 原有子进程执行
Bootstrap.run();
}

关于 socket.io 的粘性会话,我们将在 socket.io 组件中介绍更多。

2、增加 @InjectClient 支持

为 ServiceFactory 类型添加一个 @InjectClient 装饰器,方便在多客户端的的时候选择注入。

比如使用多个 redis 组件的时候。

原来:

import { RedisServiceFactory } from '@midwayjs/redis';
import { join } from 'path';

@Provide()
export class UserService {

@Inject()
redisServiceFactory: RedisServiceFactory;

async save() {
const redis1 = this.redisServiceFactory.get('instance1');
const redis2 = this.redisServiceFactory.get('instance2');

//...

}
}

现在可以通过注入来简化。

import { RedisServiceFactory } from '@midwayjs/redis';
import { InjectClient } from '@midwayjs/core';

@Provide()
export class UserService {

@InjectClient(RedisServiceFactory, 'instance1')
redis1: RedisService;

@InjectClient(RedisServiceFactory, 'instance2')
redis2: RedisService;

async save() {
// this.redis1.set(...)
// this.redis2.set(...)
}
}

注意,所有继承于 ServiceFactory 的多实例组件都可以使用上述方法。

3、casbin 支持 watcher 抽象

除了社区的 casbin-redis-watcher,我们也提供了复用 redis 连接的 watcher,为了减少包,后续所有的 casbin/redis 相关的功能都将复用 casbin-redis-adapter 包。

使用示例:

import { MidwayAppInfo } from '@midwayjs/core';
import { join } from 'path';
import { createAdapter, createWatcher } from '@midwayjs/casbin-redis-adapter';

export default (appInfo: MidwayAppInfo) => {
return {
keys: '123456',
redis: {
clients: {
'node-casbin-official': {
host: '127.0.0.1',
port: 6379,
password: '',
db: '0',
},
'node-casbin-sub': {
host: '127.0.0.1',
port: 6379,
password: '',
db: '0',
}
}
},
casbin: {
// ...
policyAdapter: createAdapter({
clientName: 'node-casbin-official'
}),
policyWatcher: createWatcher({
pubClientName: 'node-casbin-official',
subClientName: 'node-casbin-sub',
})
},
};
}

由于 pub/sub 连接需要不同,这里定义了两个客户端,和 adapter 存储复用其中一个连接。

4、DataSource 的不同路径支持

为了解决不同用户的使用习惯,我们支持了大多数可能的通配形式,现在你可以在 DataSource 中使用很多以前的格式。

比如:

export default {
mysql: {
dataSource: {
dataSource1: {
// ...
entities: [
'entity', // 特定目录
'**/abc/**', // 仅获取包含 abc 字符的目录下的文件
'abc/**/*.ts', // 特定目录 + 通配
'abc/*.entity.ts', // 匹配后缀
'**/*.entity.ts', // 通配加后缀匹配
'**/*.{j,t}s', // 后缀匹配
]
},
// ...
// ...
}
}
}

· 3 minutes de lecture
Harry Chen

v3.8.0 是在经过大促之后的第一个 minor 版本,积攒了很多新的能力。

升级请参考 如何更新 Midway 中描述,请不要单独升级某个组件包。

Features

1、etcd 组件

新增了一个 etcd 组件,方便用户使用,文档稍后提供。

import { ETCDService } from '@midwayjs/etcd';

@Provide()
export class UserService {

@Inject()
etcdService: ETCDService;

async invoke() {

const fooValue = await this.etcdService.get('foo').string();
console.log('foo was:', fooValue);
// ...
}
}

更多细节请查看 文档

2、ServiceFactory 支持设置默认客户端

ServiceFactory 提供了标准的多客户端能力,在默认的客户端中,我们可以设置非 default 的客户端作为默认客户端来使用。

这项能力支持 ServiceFactory 扩展出来的所有组件,包括 axios/cos/oss/redis/tablestore 等,用户自定义的组件也可以通过简单的适配享受到该能力。

比如,我们定义了多个 redis 客户端。

export default {
// ...
redis: {
clients: {
default: {
// ...
},
default2: {
// ...
},
},
},
}

默认注入的 RedisService 永远为 default 指向的客户端,而新版本我们可以通过设置默认的客户端名,来选择默认的客户端。

比如:

export default {
// ...
redis: {
clients: {
default: {
// ...
},
default2: {
// ...
},
},
defaultClientName: 'default2'
},
}

那么实际获取的 redisService 中是 default2 这个实例。


@Provide()
export class UserService {

@Inject()
redisService: RedisService;

async invoke() {
// this.redisService 中包裹的是 default2
}
}

3、数据源类型增加 @InjectDataSource 装饰器

为了简化获取数据源的过程,我们提供了一个新的 @InjectDataSource 装饰器,支持 mikro/sequelize/typeorm。

比如:

import { InjectDataSource } from '@midwayjs/typeorm';
import { DataSource, Repository } from 'typeorm';

@Provide()
export class UserService {

@InjectDataSource()
defaultDataSource: DataSource;

async invoke() {

// ...
}
}

也可以指定数据源。

import { InjectDataSource } from '@midwayjs/typeorm';
import { DataSource, Repository } from 'typeorm';

@Provide()
export class UserService {

@InjectDataSource('default')
defaultDataSource: DataSource;

async invoke() {
// ...
}
}

Bugfix

  • 1、修复 windows 下 entity 通配扫描,之前 windows 下的 entity 如果使用了通配符,会扫描失败,导致 entity 无法正确的加入到数据源中,新版本修复了该问题。
  • 2、bull 的 Queue 定义处理问题,现在文档已经做了修改,注入的类型可以由 IQueue 变为 BullQueue

Performance

移除了 babel 编译出的 class 的兼容判断,框架整体性能提升约一倍。

· 2 minutes de lecture
Harry Chen

由于最近 node v18 标记为 LTS,社区相关的相关的依赖都移除了 node v12 的支持,导致 Midway 的基建,单测已经无法正常的执行。

虽然 Midway 框架本身支持在 Node v12 下运行,但是例如 jest 等工具的最新版本已经无法执行。经过内部讨论后决定,在 Github Action 中移除 Midway 以及相关库的 Node v12 的单测,为此,相关的依赖会进行调整,包括:

  • 1、脚手架的变更
    • @midwayjs/cli 升级为 ^2.0.0
    • jest@types/jestts-jest 升级为 v29 版本
    • typescript 升级为 4.8.x
  • 2、Midway 本身
    • 移除 node v12 的 github action 执行
    • 鉴于部分环境的情况,继续经验支持 node v12 的运行,有 node v12 的问题可以 issue 提问

依赖的变更可以参考:

"devDependencies": {
"@midwayjs/cli": "^2.0.0",
"@types/jest": "^29.2.0",
"jest": "^29.2.2",
"ts-jest": "^29.0.3",
"typescript": "~4.8.0"
}