评论

抛砖引玉(2): Cloudbase Framework 助力改善微信云开发的体验

改善微信云开发的开发体验

抛砖引玉(2): Cloudbase Framework 助力改善微信云开发的体验

本文基于 CloudBase CLI 1.7.0 & CloudBase Framework 1.8.1
如有建议和意见,欢迎提出 (2021.06.21)

前言

书接上回 抛砖引玉:一种改善微信云开发 , 开发者体验的思路

那篇文章,主要解决的是,公共逻辑代码的复用问题,和公共npm包的问题

而手段则是通过 rollup 这类的打包工具,去预先处理云函数的代码,语法,以及依赖包

用前端的说法,就是把 src 打包到 dist 里, 最后我们实际上部署的就是 dist 里面的函数目录文件


然而之前的思路, 在我们整个 改善微信小程序开发者体验 这个大方向上,也只是做了一小部分。

因为它并没有把云函数的一些的基础的管理功能,给去 UI

当我们编写了大量云函数时,还是要去 微信IDE 上,一个一个点击上传并部署,然后再去云开发控制台,一个一个切换流量灰度,显然重复性工作多且繁琐。

于是我们就需要另外一种利器,来帮助我们更好的管理部署我们的函数项目。

那就是 Cloudbase Framework

Cloudbase Framework 和 Serverless Framework

在说 Cloudbase Framework 前也顺便聊聊 Serverless Framework

本人恰好对两者都有一些浅薄的认识

从个人的观点来看:

  • Serverless Framework 在腾讯云体系中,主要用来管理多个云产品的,比如 SCF云函数, COS对象存储,API网关,CDN,DB 等等,换句话说,只要是 腾讯云开放出来的 capi 能进行管理的, Serverless Framework 也都可以进行管理。
  • Cloudbase Framework 主要用来管理 Cloudbase 自身的功能,不过由于自己就是多个云服务的集合了 (auth, db ,scf,cos,static host,SAE 等等), 所以也能够做很多的事情了。

一句话总结,Serverless Framework 部署的应用,在腾讯云控制台中,往往要不停的在多个云产品中,切来切去来完成一些运维操作,
Cloudbase Framework 进它本身的云开发产品就可以了 (笑~)

配置

两个 Framework 的配置也是大同小异

一个是 cloudbaserc.json , 一个是 serverless.yml ,不过都可以使用变量占位符 {{}} 来做动态配置, 不过 json格式本身不支持注释。

组件

另外 serverless components 就不多说了,之前也写了不少的文章了

cloudbase Framework 本身也有 plugin 的机制,可以用来部署很多现有的框架

笔者在这里,尝试部署了一个 koa 项目,发现里面 tcbindex.js 还是借用的 serverless-http 这个包,来完成 http请求 转化成 event 的操作的

// tcbindex.js
module.exports.main = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  const entry = (() => {
    const result = require('./app.js');
    return result;
  })();
  const serverless = require('serverless-http');
  let app = entry;

  // support for async load app
  if (entry && entry.tcbGetApp && typeof entry.tcbGetApp === 'function') {
    app = await entry.tcbGetApp(event, context);
  }

  return serverless(app, {
    binary: [
      'application/javascript',
      'application/octet-stream',
      'application/xml',
      'font/eot',
      'font/opentype',
      'font/otf',
      'image/*',
      'video/*',
      'audio/*',
      'text/comma-separated-values',
      'text/css',
      'text/javascript',
      'text/plain',
      'text/text',
      'text/xml',
    ],
  })(event, context);
};

更多细节这里就先简述了, 有兴趣的朋友,可以看一下我的另外一篇文章 初探 SCF 的 Web function 和 Custom image

基于Output

基于上篇文章的输出 , Cloudbase Framework 就可以帮助我们对打包出来的云函数进行管理运维操作了

笔者主要使用的是它的云函数插件 @cloudbase/framework-plugin-function 来帮助我方便的管理微信云函数

为什么不用其他的插件?

因为在许多的场景上,是需要去获得微信的上下文的

而这个上下文机制,是通过 wx-server-sdk + wx.cloud.callFunction 来实现的

wx-server-sdk 本质也是 cloudbase 的封装

其中获取上下文的代码如下所示

// webpack + ts 打包后的 wx-server-sdk 部分代码
function getWXContext() {
    const apiName = 'getWXContext';
    const wxContext = {};
    if (!process.env.WX_CONTEXT_KEYS)
        return wxContext;
    try {
        const contextKeys = process.env.WX_CONTEXT_KEYS.split(',');
        for (const key of contextKeys) {
            if (!key)
                continue;
            if (isContextKeyInBlacklist(key))
                continue;
            let val = process.env[key];
            if (val === undefined)
                continue;
            if (isNumber(val)) {
                val = parseInt(val);
            }
            if (key.startsWith(WX_PREFIX) && key.length > 3) {
                wxContext[key.slice(3)] = val;
            }
            else {
                wxContext[key] = val;
            }
        }
        wxContext.ENV = process.env.TCB_ENV || process.env.SCF_NAMESPACE;
        if (process.env.TCB_SOURCE) {
            wxContext.SOURCE = process.env.TCB_SOURCE;
        }
        return wxContext;
    }
    catch (e) {
        const error = error_1.returnAsFinalCloudSDKError(e, apiName);
        throw error;
    }
}
exports.default = getWXContext;

可以看到,上下文是通过环境变量去注入的,我们本地也可以通过模拟 WX_ 这些环境变量,来达到我们 mock 的目的。

另一个控制台

除了微信IDE里的那个控制台,腾讯云的Cloudbase云开发中也能对微信环境下的资源进行管理,而且功能上更加的强大。

首先我们使用小程序的账户去登陆腾讯云,(开通云开发的时候,会给你开一个腾讯云账号)

进入云产品 -> Cloudbase 云开发,可以看到我们在小程序中创建的环境,和web不同,小程序的环境,会被打上的特殊标记

进入一个小程序环境,可以看到里面的用户管理功能在小程序环境无效,

数据库,云函数 和IDE云开发里的对应功能是一样的

在这里操作造成的效果,同样和微信IDE云开发控制台是一样的

而且在腾讯云的控制台还提供了更多的功能,比如 layer http访问服务 等等

现有项目里嵌入 Cloudbase Framework

这个很简单,我们只需要在里面加一个配置文件 cloudbaserc.json 就可以

接着把之前的函数给注册进配置文件中去

// 例如
{
  "version": "2.0",
  "envId": "{{env.ENV_ID}}",
  "framework": {
    "name": "business-card-miniprogram",
    "plugins": {
      "function": {
        "use": "@cloudbase/framework-plugin-function",
        "inputs": {
          "functionRootPath": "./dist",
          "functionDefaultConfig": {
            "timeout": 5,
            "envVariables": {},
            "runtime": "Nodejs10.15",
            "memorySize": 128
          },
          "functions": [
            {
              "name": "article-service"
            }
          ]
        }
      }
    }
  }
}

详细的配置也都在 这里

如果想要更强的操作性,可以参考我的这篇文章动态生成这个 json 文件, 思路见serverless framework 模块化部署

配置的模板变量 & 模式切换 也很方便

# 切换变量
.env
.env.dev
.env.prod
.env.[xxx]

# 部署
tcb framework deploy --mode dev
tcb framework deploy --mode prod
tcb framework deploy --mode xxx

serverless framework 则是 serverless deploy --target ./path/to/config.yml

部署完成之后,在我们的微信IDE下,右键对应环境的云函数目录,点击同步云函数,我们刚刚部署的函数就出现了。

这样就省去了一部分我们操作UI的时间,然而目前切换流量灰度,似乎无法通过这里的配置项进行切换,还是有些需要进行手动操作的部分的。

目前存在的不足

目前还是存在一些缺点的:

  1. 本地调试比较麻烦
  2. 过度依赖云端自动安装 node_modules 的能力,导致上传部署比较缓慢

缺点1: 的话,目前可以直接在微信IDE里,手动安装 npm 包来解决,就是麻烦点

缺点2: 名义上可以使用层layer解决,然而在一些情况下,使用 层layer 也可能存在一定的问题,原因主要在于开发平台。

像我这样的大部分微信小程序开发者,都是使用 windows 作为开发平台的,

这时候去 npm i/yarn 安装的包,抛开 js 本身,也有可能带有很多二进制文件,它们往往是和平台绑定的,比如 windows 就安装 windows 的版本,而云函数容器里面实际上都是 CentOS , 一个 win 下的二进制,怎么在 linux 下跑呢?

这时候,使用 云端自动安装 node_modules 反而没问题,而 layer 就会遇到本地和云端 平台环境不一致,导致云上运行失败的 issue 了。

点赞 1
收藏
评论

1 个评论

  • Kindear
    Kindear
    2021-06-22
    基本没见过
    
    
    这时候去 npm i/yarn 安装的包,抛开 js 本身,也有可能带有很多二进制文件,它们往往是和平台绑定的,比如 windows 就安装 windows 的版本,而云函数容器里面实际上都是 CentOS , 一个 win 下的二进制,怎么在 linux 下跑呢?
    
    2021-06-22
    赞同
    回复 1
    • ice breaker
      ice breaker
      2021-06-22
      比如像 nodejieba, puppeteer 这种包,在不同的系统平台,都有各自的二进制文件,这时候我们在windows平台打包上传的layer,在云函数下面绑定就用不了,因为云函数是linux环境
      2021-06-22
      1
      回复
登录 后发表内容