news 2026/10/9 2:09:40

Midway 部署阿里云函数计算(FC)实战指南:触发器开发、本地测试与 Serverless Devs 部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Midway 部署阿里云函数计算(FC)实战指南:触发器开发、本地测试与 Serverless Devs 部署
  • 后端
  • 微服务
  • 云原生

【免费下载链接】midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

项目地址:https://gitcode.com/gh_mirrors/mi/midway
点击查看免费下载

本文以 Midway 的 Serverless 能力为主线,系统讲解如何将 Midway 应用部署到阿里云函数计算(Function Compute,简称 FC)。内容包括内置运行时下的纯函数开发(Event、HTTP、API Gateway、Timer、OSS、MNS 六类触发器)、基于@midwayjs/fc-starter的本地开发与单元测试、基于 Serverless Devs 的s.yaml配置与一键部署脚本,以及自定义运行时下标准 Web 应用(Koa/Express/Egg)监听 9000 端口的上云方案。读完本文,你将掌握从触发器编写、本地验证到云端部署的完整闭环,并理解 fc-starter 底层的请求识别与分发机制。

阿里云 Serverless 与函数计算(FC)概述

阿里云 Serverless 是国内最早提供 Serverless 计算服务的团队之一,依托阿里云强大的云基础设施能力持续进行技术突破,淘宝、支付宝、钉钉、高德等均已将 Serverless 应用到生产业务,云上 Serverless 产品也已在数万家企业中落地。

阿里云 Serverless 包含多个产品,例如函数计算 FC、轻量应用服务器 SAE 等。本文主要使用其中的**函数计算(FC)**部分,围绕函数触发器的使用、测试与部署展开。

三种部署类型

根据函数运行容器形态的不同,阿里云函数计算提供了多种部署方式,常见的三种类型对比如下:

名称功能限制说明部署介质
内置运行时(Built-in runtime)不支持流式请求和响应;不支持过大的请求和响应只能部署函数接口,无需自定义端口,平台构建 zip 包进行部署zip 包部署
自定义运行时(Custom Runtime)—可以部署标准应用,启动 9000 端口,使用平台提供的系统镜像,构建 zip 包进行部署zip 包部署
自定义容器(Custom Container)—可以部署标准应用,启动 9000 端口,自行控制全部环境依赖,通过 Dockerfile 进行部署Dockerfile 部署

其中"内置运行时"面向纯函数场景,最简单直接;"自定义运行时 / 自定义容器"面向需要完整 Web 框架(Koa、Express、Egg 等)的标准应用。平台侧还提供了多种函数创建方式(控制台、CLI、IDE 等),开发者可根据习惯选择。

纯函数开发:基于内置运行时的触发器编写

下面以内置运行时部署的纯函数为例,介绍六类常用触发器的编写方式。所有触发器都通过@ServerlessTrigger装饰器直接绑定在方法上,函数类通过@Provide()注册到 IoC 容器,并通过@Inject()注入@midwayjs/faas提供的Context。

触发器的核心:@ServerlessTrigger与ServerlessTriggerType

@ServerlessTrigger装饰器定义在@midwayjs/core中,其第一个参数是触发器的类型。从源码中的枚举定义(packages/core/src/interface.ts)可以看到:

export enum ServerlessTriggerType { EVENT = 'event', HTTP = 'http', API_GATEWAY = 'apigw', OS = 'os', CDN = 'cdn', LOG = 'log', TIMER = 'timer', MQ = 'mq', KAFKA = 'kafka', HSF = 'hsf', MTOP = 'mtop', SSR = 'ssr', }

本文涉及的 Event、HTTP、API_GATEWAY(apigw)、TIMER、OS(OSS)、MQ(MNS)均在其中。装饰器对每种触发器类型都有对应的重载签名(见 packages/core/src/decorator/faas/serverlessTrigger.ts),HTTP与API_GATEWAY类型还需要传入path、method等路由元数据,其余事件类型一般只传类型本身。

Event 触发器

Event 触发器发布的是一个不含触发器的纯函数,是最简单的类型。你可以直接通过 event 手动触发参数,也可以在平台上绑定其他触发器。示例代码如下:

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.EVENT) async handleEvent(event: any) { return event; } }

方法的入参即平台下发的原始事件,返回值会直接作为函数执行结果返回。

HTTP 触发器

阿里云的 HTTP 触发器与 API Gateway 是两套独立的体系,HTTP 触发器独立于 API 网关,专门服务于 HTTP 场景,相比 API 网关更容易使用和配置。示例:

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.HTTP, { path: '/', method: 'get', }) async handleHTTPEvent(@Query() name = 'midway') { return `hello ${name}`; } }

这里通过@Query()参数装饰器从 query string 中取出name参数,并提供了默认值'midway'。

API Gateway 触发器

API 网关在阿里云函数体系中比较特殊,它类似于创建一个无触发器函数,再通过平台网关将其绑定到特定路径。示例:

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.API_GATEWAY, { path: '/api_gateway_aliyun', method: 'post', }) async handleAPIGatewayEvent(@Body() name) { return `hello ${name}`; } }

Timer 定时触发器

定时任务触发器用于定期执行函数。需要注意的是:测试完函数后请及时关闭触发器的自动执行,避免产生过多扣费。

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; import type { TimerEvent } from '@midwayjs/fc-starter'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.TIMER) async handleTimerEvent(event: TimerEvent) { this.ctx.logger.info(event); return 'hello world'; } }

事件结构:Timer 消息返回的结构由TimerEvent类型描述,形如:

{ "triggerTime": "2024-01-01T00:00:00.000Z", "triggerName": "timer", "payload": "" }

其中triggerTime为触发时间的 JSON 格式字符串,triggerName为触发器名称,payload为定时任务配置的负载参数。

OSS 触发器

OSS 用于存储资源文件,是阿里云的对象存储产品。当 OSS 中文件被创建或更新时,会触发对应函数执行。示例:

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; import type { OSSEvent } from '@midwayjs/fc-starter'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.OS) async handleOSSEvent(event: OSSEvent) { // xxx } }

事件结构:OSS 消息返回的结构由FC.OSSEvent类型描述,完整示例:

{ "events": [ { "eventName": "ObjectCreated:PutObject", "eventSource": "acs:oss", "eventTime": "2017-04-21T12:46:37.000Z", "eventVersion": "1.0", "oss": { "bucket": { "arn": "acs:oss:cn-shanghai:123456789:bucketname", "name": "testbucket", "ownerIdentity": "123456789", "virtualBucket": "" }, "object": { "deltaSize": 122539, "eTag": "688A7BF4F233DC9C88A80BF985AB7329", "key": "image/a.jpg", "size": 122539 }, "ossSchemaVersion": "1.0", "ruleId": "9adac8e253828f4f7c0466d941fa3db81161e853" }, "region": "cn-shanghai", "requestParameters": { "sourceIPAddress": "140.205.128.221" }, "responseElements": { "requestId": "58F9FF2D3DF792092E12044C" }, "userIdentity": { "principalId": "123456789" } } ] }

MNS 消息队列触发器

MNS(消息服务)触发器用于响应消息队列中的新消息。需要注意两点:

  1. 阿里云消息队列的 Topic 和 Queue 会产生一定费用;
  2. 默认提供的消息队列格式为 JSON。
import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core'; import { Context } from '@midwayjs/faas'; import type { MNSEvent } from '@midwayjs/fc-starter'; @Provide() export class HelloAliyunService { @Inject() ctx: Context; @ServerlessTrigger(ServerlessTriggerType.MQ) async handleMNSEvent(event: MNSEvent) { // ... } }

事件结构:MNS 消息返回的结构由FC.MNSEvent类型描述:

{ "Context": "user custom info", "TopicOwner": "1186202104331798", "Message": "hello topic", "Subscriber": "1186202104331798", "PublishTime": 1550216302888, "SubscriptionName": "test-fc-subscibe", "MessageMD5": "BA4BA9B48AC81F0F9C66F6C909C39DBB", "TopicName": "test-topic", "MessageId": "2F5B3C281B283D4EAC694B7425288675" }

触发器配置的边界:代码与 s.yaml 的分工

触发器的更多配置是平台相关的,会写在s.yaml中,例如定时任务的执行时间间隔等,具体见下文部署章节。建议遵循"代码里只写与函数签名强相关的元数据,平台相关配置全部下沉到 yaml"的原则,便于后续维护。

事件类型定义与 TypeScript 类型支持

FC 相关的类型定义由适配器(adapter)导出。为了让ctx.originContext的类型定义保持正确,需要在src/interface.ts中添加一行:

// src/interface.ts import type {} from '@midwayjs/fc-starter';

同时,@midwayjs/fc-starter还提供了各类 Event 事件的类型定义,可按需导入:

// 事件类型 import type { OSSEvent, MNSEvent, SLSEvent, CDNEvent, TimerEvent, APIGatewayEvent, TableStoreEvent, } from '@midwayjs/fc-starter'; // InitializeContext 类型 import type { InitializeContext } from '@midwayjs/fc-starter';

这些类型在 packages-serverless/midway-fc-starter/src/interface.ts 中均有完整定义:OSSEvent包含events数组与单条 OSS 事件详情;MNSEvent是字符串、流式结构(MNSStreamEvent)与 JSON 结构(MNSJSONEvent)的联合类型;TimerEvent包含triggerTime、triggerName、payload三个字段;APIGatewayEvent则包含path、httpMethod、headers、queryParameters、pathParameters、body、isBase64Encoded等网关事件字段。

本地开发与测试

本地开发

HTTP 触发器与 API Gateway 类型可以通过本地npm run dev以类似传统应用的方式进行开发调试;而其他类型的触发器(Event、Timer、OSS、MNS 等)无法通过dev在本地开发,只能通过执行npm run test进行测试。

本地测试基础:createFunctionApp 与 mockContext

函数应用的测试与传统应用类似,使用createFunctionApp方法创建函数应用,使用close方法关闭。基础写法:

import { Application, Context, Framework } from '@midwayjs/faas'; import { mockContext } from '@midwayjs/fc-starter'; import { createFunctionApp } from '@midwayjs/mock'; describe('test/hello_aliyun.test.ts', () => { it('should get result from event trigger', async () => { // 创建函数应用 const app: Application = await createFunctionApp<Framework>(join(__dirname, '../'), { initContext: mockContext(), }); // ... await close(app); }); });

mockContext方法用于模拟一个 FC Context 数据结构,你也可以自定义类似结构或修改其中的部分数据,例如:

import { Application, Context, Framework } from '@midwayjs/faas'; import { mockContext } from '@midwayjs/fc-starter'; import { createFunctionApp } from '@midwayjs/mock'; describe('test/hello_aliyun.test.ts', () => { it('should get result from event trigger', async () => { // 创建函数应用 const app: Application = await createFunctionApp<Framework>(join(__dirname, '../'), { initContext: Object.assign(mockContext(), { function: { name: '***', handler: '***' } }), }); // ... await close(app); }); });

从 packages-serverless/midway-fc-starter/src/mock.ts 的源码可以看到mockContext()返回的默认结构,包含requestId、credentials(STS 临时凭证)、function(name/handler/memory/timeout/initializer 等)、service(name/logProject/logStore/qualifier/versionId)、region、accountId、logger等字段,与真实 FC 运行时的上下文对齐,测试时可据此按需覆写。

各触发器的测试方法

不同触发器有不同的测试方法,常见触发器的测试方式如下。

Event 触发器:通过getServerlessInstance获取类实例,直接调用实例方法并传入参数进行测试。

import { HelloAliyunService } from '../src/function/hello_aliyun'; describe('test/hello_aliyun.test.ts', () => { it('should get result from event trigger', async () => { // ... const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService); expect(await instance.handleEvent('hello world')).toEqual('hello world'); // ... }); });

HTTP 触发器:与应用测试类似,通过createFunctionApp创建函数应用,再用createHttpRequest发起请求。

import { HelloAliyunService } from '../src/function/hello_aliyun'; describe('test/hello_aliyun.test.ts', () => { it('should get result from http trigger', async () => { // ... const result = await createHttpRequest(app).get('/').query({ name: 'zhangting', }); expect(result.text).toEqual('hello zhangting'); // ... }); });

API Gateway 触发器:与 HTTP 测试相同,通过createFunctionApp创建函数应用,再用createHttpRequest发起请求。

import { createHttpRequest } from '@midwayjs/mock'; describe('test/hello_aliyun.test.ts', () => { it('should get result from http trigger', async () => { // ... const result = await createHttpRequest(app).post('api_gateway_aliyun').send({ name: 'zhangting', }); expect(result.text).toEqual('hello zhangting'); // ... }); });

Timer 定时触发器:与 HTTP 测试不同,通过createFunctionApp创建函数应用后,用getServerlessInstance获取整个类的实例,调用特定方法进行测试。平台传入的结构可以通过mockTimerEvent方法快速创建:

import { HelloAliyunService } from '../src/function/hello_aliyun'; import { mockTimerEvent } from '@midwayjs/fc-starter'; describe('test/hello_aliyun.test.ts', () => { it('should get result from timer trigger', async () => { // ... const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService); expect(await instance.handleTimerEvent(mockTimerEvent())).toEqual('hello world'); // ... }); });

OSS 触发器:通过createFunctionApp创建函数应用,用getServerlessInstance获取整个类的实例,调用特定方法进行测试。平台传入的结构可以通过mockOSSEvent方法快速创建:

import { HelloAliyunService } from '../src/function/hello_aliyun'; import { mockOSSEvent } from '@midwayjs/fc-starter'; describe('test/hello_aliyun.test.ts', () => { it('should get result from oss trigger', async () => { // ... const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService); expect(await instance.handleOSSEvent(mockOSSEvent())).toEqual('hello world'); // ... }); });

MNS 触发器:同样通过createFunctionApp创建函数应用,用getServerlessInstance获取类的实例后调用方法,平台传入的结构通过mockMNSEvent方法快速创建:

import { HelloAliyunService } from '../src/function/hello_aliyun'; import { mockMNSEvent } from '@midwayjs/fc-starter'; describe('test/hello_aliyun.test.ts', () => { it('should get result from oss trigger', async () => { // ... const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService); expect(await instance.handleMNSEvent(mockMNSEvent())).toEqual('hello world'); // ... }); });

可以看到,@midwayjs/fc-starter的 mock 工具(mockContext、mockTimerEvent、mockOSSEvent、mockMNSEvent、mockCDNEvent、mockSLSEvent、mockTableStoreEvent等)与真实平台事件结构完全对齐,使得单元测试无需真实云资源即可完成。

纯函数部署:内置运行时 + Serverless Devs

下面简要说明如何使用 Serverless Devs 将内置运行时的纯函数部署到阿里云。

1. 确认启动器(starter)

在项目根目录的f.yml的provider配置段中,确保启动器为@midwayjs/fc-starter:

provider: name: aliyun starter: '@midwayjs/fc-starter'

@midwayjs/fc-starter是 Midway 为阿里云函数计算提供的适配器实现(源码位于 packages-serverless/midway-fc-starter,主实现见 packages-serverless/midway-fc-starter/src/index.ts)。

2. 安装 Serverless Devs 工具

阿里云使用 Serverless Devs 工具进行函数部署,可以全局安装:

$ npm install @serverless-devs/s -g

安装后需要配置云账号密钥,密钥配置的具体步骤请参考 Serverless Devs 官方文档中的密钥配置(Key Configuration)说明。

3. 编写 Serverless Devs 描述文件

在项目根目录创建s.yaml,添加如下内容:

edition: 1.0.0 name: "midwayApp" # 项目名称 access: "default" # 密钥别名 vars: service: name: fc-build-demo description: 'demo for fc-deploy component' services: project-0981cd9b07: component: devsapp/fc props: region: cn-hangzhou service: ${vars.service} function: name: hello # 函数名 handler: helloHttpService.handleHTTPEvent codeUri: '.' initializer: helloHttpService.initializer customDomains: - domainName: auto protocol: HTTP routeConfigs: - path: /* serviceName: ${vars.service.name} functionName: helloHttpService-handleHTTPEvent triggers: - name: http type: http config: methods: - GET authType: anonymous

其中handler对应函数类名与方法的组合(如helloHttpService.handleHTTPEvent),initializer为初始化入口,triggers定义了 HTTP 触发器的方法与鉴权方式。

每次新增函数都需要调整s.yaml文件。为此,Midway 提供了@midwayjs/serverless-yaml-generator工具,用于把装饰器中的函数信息写入s.yaml:

{ "scripts": { + "generate": "serverless-yaml-generator", }, "devDependencies": { + "@midwayjs/serverless-yaml-generator": "^1.0.0", }, }

执行下面的命令,即可把现有函数信息填充到s.yaml中,并生成入口文件以便排查问题:

$ npm run generate

该工具会以函数名作为 key 在s.yaml中查找配置:

  1. 如果函数已存在,会覆盖特定字段,如 handler、http 触发器方法等;
  2. 如果函数不存在,会新增一个函数;
  3. 工具不会写入 http 路由方式,为简化后续更新,你可以提供一个/*路由(示例中即如此)。

建议用户在装饰器中只定义基础的函数名、函数 handler 以及基础触发器信息(如 http 触发器的 path 和 method),其余配置全部写在yaml中。

s.yaml的完整配置较为复杂,可参考 Serverless Devs 官方文档中的描述文件规范(Description File Specification)。

4. 编写部署脚本

由于部署包含构建、拷贝等多个步骤,可以编写一个部署脚本统一这一过程。例如在项目根目录新建deploy.sh:

#!/bin/bash set -e # 构建产物目录 export BUILD_DIST=$PWD/.serverless # 构建开始时间(毫秒) export BUILD_START_TIME=$(date +%s%3N) echo "Building Midway Serverless Application" # 打印当前目录 cwd echo "Current Working Directory: $PWD" # 打印产物目录 BUILD_DIST echo "Build Directory: $BUILD_DIST" # 安装当前项目依赖 npm i # 执行构建 ./node_modules/.bin/tsc || return 1 # 生成入口文件 ./node_modules/.bin/serverless-yaml-generator || return 1 # 如果 .serverless 目录存在,删除后重新创建 if [ -d "$BUILD_DIST" ]; then rm -rf $BUILD_DIST fi mkdir $BUILD_DIST # 将 dist、*.json、*.yml 拷贝到 .serverless 目录 cp -r dist $BUILD_DIST cp *.yaml $BUILD_DIST 2>/dev/null || : cp *.json $BUILD_DIST 2>/dev/null || : # 将入口文件移动到 .serverless 目录 mv *.js $BUILD_DIST 2>/dev/null || : # 进入 .serverless 目录 cd $BUILD_DIST # 安装线上依赖 npm install --production echo "Build success" # 在 .serverless 目录中执行部署 s deploy

可以把deploy.sh挂到package.json的deploy命令上,后续直接执行npm run deploy完成部署:

{ "scripts": { "deploy": "sh deploy.sh" } }

注意事项:

  1. deploy.sh仅在 mac 上测试过,其他平台请自行调整;
  2. 脚本内容可以根据业务逻辑调整,例如拷贝的文件等。

自定义运行时部署:标准 Web 应用上云

当纯函数无法满足需求、需要完整 Web 框架能力时,可以使用自定义运行时部署标准项目。

1. 创建项目

自定义运行时可以部署标准项目,由于需要提供 9000 端口,需要创建 Midway 的 koa/express/egg 项目。项目初始化请参考 创建第一个应用。

2. 调整监听端口为 9000

为了避免影响本地开发,仅在入口bootstrap.js中添加端口配置:

const { Bootstrap } = require('@midwayjs/bootstrap'); // 显式将用户代码作为组件引入 Bootstrap.configure({ globalConfig: { koa: { port: 9000, } } }).run()

不同框架修改端口的方式参考:

  • Koa 修改端口
  • Egg 修改端口
  • Express 修改端口

3. 平台部署配置

在阿里云函数计算控制台创建函数时:

  1. 选择运行环境,例如Node.js 18;
  2. 选择代码上传方式,例如本地上传 zip 包;
  3. 启动命令指定为node bootstrap.js;
  4. 监听端口设置为9000。

配置完成后,上传压缩包即可完成部署。

从源码看 fc-starter 的运行时机制

理解了上层用法后,深入 packages-serverless/midway-fc-starter/src/index.ts 的BootstrapStarter实现,可以更清楚地把握部署到阿里云后函数的真实执行路径。

启动与导出:onStart

BootstrapStarter继承自@midwayjs/faas的AbstractBootstrapStarter(见 packages/faas/src/starter.ts)。在onStart中:

  • 若未设置NODE_ENV,默认置为production;
  • 检测到FC_FUNC_CODE_PATH环境变量时,开启MIDWAY_SERVERLESS_REPLACE_LOGGER(用 Midway 日志替换 FC 默认上下文日志)并禁用控制台颜色(MIDWAY_LOGGER_DISABLE_COLORS),保证日志可被 FC 控制台正确采集;
  • 根据initializeMethodName(默认initializer)与handlerName生成导出的函数对象,供平台按 handler 名调用。

请求分发:onRequest 中的三类场景识别

onRequest(event, context, oldContext)是每次函数调用的统一入口,它通过事件形态区分三类场景:

  • HTTP 模式:event.constructor.name为IncomingMessage或EventEmitter,属于自定义运行时下标准 HTTP 请求直达;
  • API Gateway 模式:event.headers存在且同时包含queryParameters与httpMethod字段;
  • 事件模式:其余所有场景(Event、Timer、OSS、MNS 等)。

识别之后,HTTP/API Gateway 走this.framework.wrapHttpRequest包装为 HTTP 上下文,事件模式则构造{ originEvent, originContext, logger }这样的纯事件上下文,最终统一交给@midwayjs/faas框架的invokeTriggerFunction完成路由匹配与函数调用(见 packages/faas/src/framework.ts)。这也解释了为什么 HTTP/API Gateway 触发器可以像传统应用一样npm run dev本地开发,而事件类触发器只能通过测试验证。

事件格式化与 Buffer 处理

对于阿里云事件触发器,平台传入的入参可能是 buffer:BootstrapStarter会先toString('utf8')再尝试JSON.parse,将原始事件还原为对象后挂到ctx.originEvent上。而在 HTTP 模式下,对于post、put、delete且未带 body 的请求,会通过raw-body以10mb上限读取请求体,保证表单/JSON 提交都能被正确解析。

错误处理与响应格式化

函数执行出错时,会按SERVERLESS_OUTPUT_ERROR_STACK或运行环境(local/development)决定是否输出错误堆栈,否则返回500 + "Internal Server Error"。同时@midwayjs/faas的formatHttpResponse会根据返回内容自动推断响应类型(字符串 → text/plain、Buffer → application/octet-stream 并 base64、对象 → application/json),并组装isBase64Encoded / statusCode / headers / body标准结构(见 packages/faas/src/framework.ts)。

Mock 数据结构与测试闭环

mock.ts 中提供的mockContext、mockTimerEvent、mockOSSEvent、mockMNSEvent、mockCDNEvent、mockSLSEvent、mockTableStoreEvent与上文各触发器的真实事件结构一一对应,是本地单元测试(配合@midwayjs/mock的createFunctionApp)能够脱离云端跑通的关键。整个链路闭环为:装饰器声明触发器 → fc-starter 在云端识别事件并分发 → faas 框架匹配 handler 并执行 → mock 工具在本地还原同等结构完成验证。

小结

本文从阿里云函数计算的三种部署类型出发,完整覆盖了 Midway 在 FC 上的两条主线:一是内置运行时下的纯函数开发(六类触发器编写、类型定义、本地开发与测试),二是 Serverless Devs 驱动的自动化部署(f.yml启动器确认、s.yaml编写、serverless-yaml-generator自动生成、deploy.sh一键构建部署),并补充了自定义运行时下标准 Koa/Express/Egg 项目监听 9000 端口的上云方案。结合@midwayjs/fc-starter与@midwayjs/faas的源码实现,开发者可以清晰理解函数从"本地测试"到"云端执行"的完整调用链路,从而在实际项目中根据业务形态(纯事件处理还是完整 Web 服务)选择正确的部署路线。

  • 后端
  • 微服务
  • 云原生

【免费下载链接】midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

项目地址:https://gitcode.com/gh_mirrors/mi/midway
点击查看免费下载

相关推荐

上一篇:如何快速获取抖音内容:3种高效的批量下载方案对比
下一篇:AI-For-Beginners 迁移学习实战:用预训练 CNN 快速构建图像分类器与"理想猫"可视化

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 2:07:40

Deep-Live-Cam换脸模型配置:2个文件3步跑通

Deep-Live-Cam换脸模型配置:2个文件3步跑通 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam Deep-Live-Cam 做实时换脸&#xff0c;整套模…

作者头像 李华
网站建设 2026/10/9 2:07:23

Java手机APP信息统计分析系统:从埋点采集到看板聚合的完整实现

简介&#xff1a;这是一套面向Java后端与大数据方向学习者的手机APP信息统计分析系统源码&#xff0c;围绕用户行为数据的采集、存储、分析与可视化展开&#xff0c;适合作为课程设计、毕业设计或大数据入门项目的参考实现。资源包共57个文件&#xff0c;约56.75MB&#xff0c;…

作者头像 李华
网站建设 2026/10/9 2:04:27

模板消息错误消息优化:从错误码规范到链路追踪的工程实践

做了快十年的模板消息平台&#xff0c;我最大的体会是&#xff1a;模板这玩意儿&#xff0c;看着简单&#xff0c;真出起问题来能把人逼疯。尤其是错误消息——用户那边只收到一句"发送失败"&#xff0c;后台日志里躺着一串又臭又长的堆栈&#xff0c;模板ID、参数名…

作者头像 李华