跳到主要内容
版本:2.0.0

从 Serverless v1 迁移到 v2

本文章介绍如何从 Serverless v1.0 迁移到 Serverless v2.0。

Midway Serverless 2.0 的升级主要体现在架构和包的变化上,功能本身变化不大。

升级方式

1、全局 CLI 的升级

移除原有的 @midwayjs/faas-cli  包,不再使用 f  全局命令,改为项目下的包和命令。

$ npm uninstall @midwayjs/faas-cli -g

2、项目包版本的升级

依赖包升级。

"dependencies": {
"@midwayjs/faas": "^2.0.0"
},

开发依赖包升级(向传统应用靠拢)。

  "devDependencies": {
"@midwayjs/cli": "^1.2.45",
"@midwayjs/mock": "^2.8.7",
"@midwayjs/serverless-app": "^2.8.7",
"@midwayjs/fcli-plugin-fc": "^1.2.45",
"@types/jest": "^26.0.10",
"@types/node": "^14",
"typescript": "^4.0.0"
}
  • 1、将原有的 mocha 测试换成了 jest,所以 @types/mocha  变为了 @types/jest 。
  • 2、 @midwayjs/serverless-invoke  被移除,由于采用了应用的测试方式,不再需要。
  • 3、平台模块区分, @midwayjs/fcli-plugin-fc  该模块是用于阿里云 FC 环境的工具包,如果要发布到腾讯云 SCF 环境,请使用 midwayjs/fcli-plugin-scf 。

3、脚本的升级

向应用靠拢,提供了 dev 、 test 、 deploy  命令。

  "scripts": {
"dev": "midway-bin dev --ts",
"test": "midway-bin test --ts",
"deploy": "midway-bin deploy"
},
  • 原有的 build 命令被移除,因为部署时 deploy 会自动 build
  • 原有的 f test  命令将和开发应用相同,替换为 midway-bin test --ts
  • 原有的 f dev  和 debug,将和开发应用相同,统一使用 midway-bin dev --ts ,调试方式也相同

4、包定义变更

常见定义变更。

原有的 IFaaSApplication 变为 Application ,和应用一致从 @midwayjs/faas 包获取。

import { Application, Context } from '@midwayjs/faas';

原有的小写装饰器变为大写,和应用一致从 @midwayjs/decorator 获取。

import { App, Config } from '@midwayjs/decorator';

原有的 ILifeCycleIMidwayContainer 为容器定义,和应用一致从 @midwayjs/core 获取。

import { ILifeCycle, IMidwayContainer } from '@midwayjs/core';

5、运行

HTTP 类的函数,本地直接使用 npm run dev 运行,非 HTTP 类的函数,请使用 npm run test 进行测试开发。

可选的调整

1、@Func 装饰器升级为 @ServerlessTrigger 装饰器

现有代码依旧可以使用 @Func 装饰器兼容,新代码请使用 @ServerlessTrigger 装饰器,构建器可以通过分析 @ServerlessTrigger 装饰器,自动生成 yml 内容。

2、f.yml

使用了 @ServerlessTrigger 装饰器后,f.yml 中的 functions 字段可以移除。编译时会自动根据代码生成函数路由信息。

3、测试代码的调整

HTTP 类型的函数,使用和应用相同的封装了 supertest 的 createHttpRequest 方法创建 HTTP 客户端。

import { createFunctionApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework, Application } from '@midwayjs/serverless-app';

describe('test/hello_aliyun.test.ts', () => {
let app: Application;

beforeAll(async () => {
// create app
app = await createFunctionApp<Framework>();
});

afterAll(async () => {
await close(app);
});

it('should get result from api gateway trigger', async () => {
const result = await createHttpRequest(app).get('/').query({
name: 'zhangting',
});
expect(result.text).toEqual('hello zhangting');
});
});

除了类 HTTP 触发器之外,我们还有其他比如定时器、对象存储等函数触发器,这些触发器由于和网关关系密切,不能使用 HTTP 行为来测试,而是使用传统的方法调用来做。

import { createFunctionApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework, Application } from '@midwayjs/serverless-app';
import { createInitializeContext } from '@midwayjs/serverless-fc-trigger';

describe('test/hello_aliyun.test.ts', () => {
let app: Application;
let instance: HelloAliyunService;

beforeAll(async () => {
// 创建函数 app
app = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: createInitializeContext(), // 这里传入了 aliyun 特有的初始化上下文数据
});

// 拿到服务类
instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService);
});

afterAll(async () => {
await close(app);
});

it('should get result from event trigger', async () => {
// 调用函数方法,传入参数
expect(await instance.handleEvent('hello world')).toEqual('hello world');
});
});