继simple-cloudbase后,simple-cloudbase-router
也提上了开发日程。
在笔者使用它们2
个 npm 包,迁移了 2 个小程序的所有云函数后,发布了 Router
的 0.1.0-beta
版本。
这个包的设计思路主要参考了 koa-compose
并利用 event
建立一套中间件分发机制,可以说专为云开发而定制的。
和 simple-cloudbase
这个CLI
工具,主要负责单函数与多函数工程化打包不同,simple-cloudbase-router
主要工作是在单个函数内部,建立一套逻辑分发机制,从而让它能够做更多的事情。这种思路比较适合目前 单个云函数的冷启动时间较长这样一个状况。
yarn add simple-cloudbase-router@latest
# or
npm i simple-cloudbase-router@latest
simple-cloudbase
)// app.ts
import { cloud } from '~/common/tcb'
import { Application } from 'simple-cloudbase-router'
import type { ICustomContext } from './type'
import { commonRouter } from './routers'
const app = new Application<ICustomContext>()
app.use((ctx, next) => {
ctx.cloud = cloud
ctx.wxContext = cloud.getWXContext()
next()
})
app.use(commonRouter.routes())
app.on('error', (_err, ctx) => {
console.error(ctx.event)
})
export default app
// index.ts
import app from './app'
export async function main(event: any, content: any) {
return await app.serve(event, content)
}
完整示例见examples/modern
当然,它也能够不配合 simple-cloudbase
, 不经过打包,直接 Commonjs require
来使用它。
// app.js
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const { Application } = require('simple-cloudbase-router')
const app = new Application()
const commonRouter = require('./routers/common')
app.use((ctx, next) => {
ctx.cloud = cloud
ctx.wxContext = cloud.getWXContext()
next()
})
app.use(commonRouter.routes())
app.on('error', (_err, ctx) => {
console.error(ctx.event)
})
module.exports = app
// index.js
const app = require('./app')
exports.main = async (event, context) => {
return await app.serve(event, context)
}
完整示例见examples/raw
建议还是配合 simple-cloudbase
一同使用,以保证一个良好的开发体验。
Ts/ESM
示例可通过 simple-cloudbase
打包后调用 tcb
部署
CJS
同样,既可通过 tcb
部署,也可以直接通过微信开发者工具上传部署。
不论是 Application
还是 Router
,它们都可以对 IBaseContext
进行扩展。即 Application<IExtendContext = {}>
和 Router<IExtendContext = {}>
。
这在 use
中间件时尤为有效,如:
// wxContext Middleware
app.use((ctx, next) => {
ctx.cloud = cloud
ctx.wxContext = cloud.getWXContext()
next()
})
// 在 ctx 上挂载了 'wx-server-sdk' 实例
// 那么就可以定义
import type { ICloud } from 'wx-server-sdk'
import Cloud from 'wx-server-sdk'
export type ICustomContext = {
wxContext:ICloud.WXContext
cloud:typeof Cloud
}
// 然后在 app 实例化时, 扩展泛型
const app = new Application<ICustomContext>()
// 这样就可以生成智能提示了,Router 同理
和 http
场景不同,Router App
的上下文是经过简化的,主要如下
ctx.event = event // 函数初始入参 event
ctx.context = context // 函数初始入参 context
// event 中包含 $url 和 data, $url 为路由,data为参数
ctx.url = event.$url // 路由
ctx.data = event.data ?? {} // 函数初始入参 event
ctx.status = 200 // 状态码
ctx.body = {} // 返回值
wx.cloud.callFunction({
name,
data: {
$url: url, // 路由
data, // 参数
},
});
默认返回结构为,状态码 + 数据 ,可通过中间件调整
return {
status: ctx.status,
data: ctx.body
}
export function createCallFunction(name: string) {
return async (url?: string, data?: Record<string, any>) => {
const { result } = await wx.cloud.callFunction({
name,
data: {
$url: url,
data,
},
});
// do sth with result.status
return (result as Record<string, any>).data;
};
}
export const blogCallFunction = createCallFunction("blog");
export function getOpenId(): Promise<{ openid: string; unionid: string }> {
return blogCallFunction("common/getOpenId");
}
项目处于进一步测试阶段,如果您有建议或者意见,或者使用中遇到的各种问题,欢迎来 Github
提出。