Skip to main content

Release 3.9.0

· 3 minute read
Harry Chen
Maintainer of Midway

大促积攒了约两周的需求,统一在 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', // 后缀匹配
]
},
// ...
// ...
}
}
}

Release 3.8.0

· 2 minute read
Harry Chen
Maintainer of Midway

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 的兼容判断,框架整体性能提升约一倍。

移除 node v12 相关的依赖

· One minute read
Harry Chen
Maintainer of Midway

由于最近 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"
}

Release 3.7.0

· 2 minute read
Harry Chen
Maintainer of Midway

Features

1、支持了自定义的 web 参数装饰器

在 Web 场景下,我们已经有 @Query@Body 等参数装饰器,但是用于依旧有自定义的需求,如果这个时候通过现有的参数装饰器去定义会较为繁琐。

新版本提供了一个快速定义装饰器的能力,从而可以快速获取 ctx 属性。

import { createRequestParamDecorator } from '@midwayjs/core';

// 实现装饰器
export const Token = createRequestParamDecorator(ctx => {
return ctx.headers.token;
});

// 使用装饰器
export class UserController {
async invoke(@Token() token: string) {
console.log(token);
}
}

2、koa 组件新增 serverTimeout 配置

通过配置 serverTimeout 的值,可以定义服务端超时时间。

比如 1s 超时。

export const koa = {
serverTimeout: 1000,
}

3、多数据源时提供一个默认数据源的选项

原有 typeorm 等数据库,如果指定了多个数据源,会默认以最后一个配置的数据源作为默认数据源。

默认数据源在 InjectEntityModel 时可以不指定名字。

新版本可以通过显式的配置默认数据源,使得这个行为更可控。

比如:

// config.default.ts
export const typeorm = {
dataSource: {
abc: {},
bcd: {}
},
defaultDataSourceName: 'bcd',
}

这样在使用时,如果不指定 InjectEntityModel 的第二个参数,则会在 bcd 这个 dataSource 中查询 Entity。

3、新增了验证码组件

通过新增的验证码组件,可以生成在登录中常见的图片,计算表达式等类型的验证码。

效果如下:

Bugfix

修复了一个 import 顺序不一致,导致主框架获取错误的情况。

比如:

import * as bull from '@midwayjs/bull';
import * as koa from '@midwayjs/koa';

@Configuration({
imports: [koa, bull]
})
export class MainConfiguration {}

由于内部初始化是使用 require 的属性,即使 imports 的顺序固定,实际 bull 的 application 还是会变为 mainApp,这个时候去引入中间件,都会加到 bull 上,而不是 koa 上。

其他的更新

  • prometheus 支持用户定义 Histogram
  • faas 调整了 triggerFunction 方法的参数
  • 常态化依赖升级

Jest v29 更新

· One minute read
Harry Chen
Maintainer of Midway

最近由于 axios 组件的升级,可能在单测时会出现下面的报错。

原因为脚手架自带的 jest v26 不支持 package.json 中的 exports 逻辑。

解决方法:

  • 1、将 package.json 中的 jest 版本从 v26 更新为 v29
  • 2、将 @midwayjs/cli 的版本升级为 1.3.16 版本以上,也可以升级到 2.0

示例如下:

{
"devDependencies": {
"@midwayjs/cli": "^2.0.1",
"@types/jest": "^29.2.0",
"jest": "^29.2.2",
"ts-jest": "^29.0.3",
// ...
}
}