评论

simple-cloudbase-router 发布了Beta版本

simple-cloudbase-router 发布了Beta版本

simple-cloudbase-router 发布了Beta版本

前言

simple-cloudbase后, simple-cloudbase-router 也提上了开发日程。

在笔者使用它们2个npm包,迁移了2个小程序的所有云函数后,发布了 Router0.1.0-beta 版本。

Function as Application

这个包的设计思路主要参考了 koa-compose 并利用 event 建立一套中间件分发机制,可以说专为云开发而定制的。

simple-cloudbase 这个CLI工具,主要负责单函数与多函数工程化打包不同,simple-cloudbase-router 主要工作是在单个函数内部,建立一套逻辑分发机制,从而让它能够做更多的事情。这种思路比较适合目前 单个云函数的冷启动时间较长这样一个状况。

如何使用?

安装

yarn add simple-cloudbase-router@latest
# or
npm i simple-cloudbase-router@latest

快速开始示例

Ts/ESM (with 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 来使用它。

Commonjs(Raw)

// 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 = {} // 返回值

小程序 event 入参

wx.cloud.callFunction({
      name,
      data: {
        $url: url, // 路由
        data, // 参数
      },
    });

云函数 return 数据

默认返回结构为, 状态码 + 数据 ,可通过中间件调整

    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 提出。

文档地址

项目地址

点赞 0
收藏
评论
登录 后发表内容