写点什么

如何定制化开发 Serverless Framework 的 Component ?

  • 2020-08-09
  • 本文字数:2642 字

    阅读完需:约 9 分钟

如何定制化开发Serverless Framework的Component ?

在使用 Serverless Framework 开发者工具时,无论是哪家云计算运营商与社区都会提供很多组件供我们选择。虽然这些组件可以在一定程度上解决绝大部分问题,但是在某些时候,我们还可能存在一些定制化需求,那么这个时候可能就需要我们自己来定制化开发 Component。

开发一个全局变量组件

Serverless Framework Plugin 是可以设置全局变量,在之后的一些引用中可以直接使用全局变量。但是在 Component 中没有全局变量的概念,这就导致一个问题:如果有多个函数,每个函数都有数据库的配置,难道是要把数据库的配置写多次吗?


有人说,不用写多次,我们完全可以使用.env来解决这个问题。例如,在每个函数中通过include引入某个未知的.env,将一些配置信息放到这里,就可以解决这个问题。


但是这会引发新的问题,如果有多个.env文件怎么处理?例如,有一个.env.test,还有一个.evn.dev,那么是要批量替换这个引入的文件,还是修改文件名?所以,在稍微复杂一点的环境中,还是需要一个全局变量来控制一些事情。


通过实现一个 Component 来解决全局变量问题,解决全局变量问题再与.env方案结合,我认为是在生产中获得更大便利的最优解:


  • 首先第一步,需要明确组件具体功能:


实现一个全局组件,用户可以配置全局信息,之后的项目可以以直接引用,如果有修改,直接修改全局变量的配置就好。


  • 接下来明确yaml的结构:


这个结构相对来说就很自由了,我的设想是:


GlobalComponent:  component: 'serverless-global'  inputs:    key: value
复制代码


其中,组件名称是serverless-global,组件的字段可以自定义,主要就是key-value形式。


  • 然后是针对功能和yaml定义动作,主要动作是,在程序执行时,将用户定义的key-value完整输出,这样用户就可以在其他组件中引用,例如:


GlobalComponent:  component: 'serverless-global'  inputs:    region: ap-beijing    ScfComponent_1:  component: '@serverless/tencent-scf'  inputs:    region: ${GlobalComponent.region}    ScfComponent_2:  component: '@serverless/tencent-scf'  inputs:    region: ${GlobalComponent.region}
复制代码


  • 最后就是项目的开发。


一个标准的 Serverless Component 格式是这样的:


// serverless.jsconst { Component } = require('@serverless/core')class MyComponent extends Component {  /*   * default (必须) : 执行命令 `$ serverless` 会运行此函数   */  async default(inputs = {}) {    return {}  }
/* * remove (可选) : 执行命令 `$ serverless remove` 会运行此函数, 如果在default中保存了状态,那么此处也必须要存在,否则会报错 */ async remove(inputs = {}) { return {} }
/* * others (可选):其他功能 */ async others(inputs = {}) { return {} }}module.exports = MyComponent
复制代码


对于 GlobalComponent 而言,是不是只需要把用户的输入内容(input),输出就好?


全局变量组件第一个版本的代码如下:


// serverless.jsconst { Component } = require('@serverless/core')class GlobalComponent extends Component { async default(inputs = {}) {   return inputs }}module.exports = GlobalComponent
复制代码


由于在实际生产中,全局变量组件可能会有一些额外用法,例如是否可以在全局变量组件中直接引入某些 Yaml 等操作?…



这种做法是比较常见的,因为可能存在多套配置,完全可以在这里进行不同配置文件的引入。


我们可以对上面的代码进行进一步完善:


// serverless.jsconst { Component } = require('@serverless/core')const yamljs = require('yamljs')
class GlobalComponent extends Component { async getOutput(inputs = {}, output) { const reg = /\${file\(.*?\)}/g for (const key in inputs) { const regResult = reg.exec(inputs[key]) if (regResult) { const inputPath = inputs[key].slice(7, -2) // const file = inputPath[0] == '/' ? inputPath : path.join(process.cwd(), inputPath) const yaml = yamljs.load(inputPath) const jsonStr = JSON.stringify(yaml) const jsonTemp = JSON.parse(jsonStr, null) if (jsonTemp) { output[key] = await this.getOutput(jsonTemp, {}) } } else { output[key] = inputs[key] } } return output }
async default(inputs = {}) { const output = {} await this.getOutput(inputs, output) return output }}
module.exports = GlobalComponent

复制代码


至此,我们就完成了一个全局变量组件的开发。


  • 当然除了上面说的这种简单组件,在开发过程中,我们还会有一些其它需要注意的点:


  1. Serverless Framework Component 是会生成一个缓存目录.serverless,这个缓存文件怎么来的?


this.state = {}await this.save()
复制代码


可以通过上面的方法,将需要缓存的内容放入{}中,进行缓存。


  • 如何引用其他组件?


const othersComponent = await this.load('@serverless/tencent-scf', 'scf-component');
复制代码


这其中有两个参数,一个是组件的名字:@serverless/tencent-scf,另一个是本次引用的名字:scf-component,本次引用的名字怎么理解?其实就是这样,在缓存目录会生成很多组件,例如:



这是部署一个 express 之后生成的缓存目录,这里面可以看到有文件叫这个名字:Template.express.TencentFramework.apigateway.ap-guangzhou-apigateway


针对这条记录而言,其引用层为:


tencent-express 组件->tencent-framework->tencent-apigateway-mutil-region->tencent-apigateway


那么每段含义:


Template: 此处是一个统一的开头


express: 这个组件在 Yaml 中的名字



TencentFramework: 在 tencent-express 引用了 tencent-framework 时候,给本次引用的名字(可以不填写,不填写会默认)


apigateway: 在 tencent-framework 引用了 tencent-apigateway-mutil-region 时,给它的本次引用的名字(可以不填写,不填写会默认)


ap-guangzhou-apigateway: 在 tencent-apigateway-mutil-region 引用了 tencent-apigateway 时,给它的本次引用的名字(可以不填写,不填写会默认)


这样做的目的是为了让我们在进行移除等操作时,可以更好的找到资源信息。

总结

正如文章开始所说,我们在做一个项目的时候,社区和官方提供给我们的能力基本是通用的,可能无法很好地满足定制化需求,那么这个时候,我们就可以通过文中的方法开发出自己的组件。


当然有些时候,官方或者社区没有提供某种组件,我们也可以开发,成为一个贡献者。


2020-08-09 23:351827

评论

发布
暂无评论
发现更多内容

如何通过 1688 商品详情的 API 接口获取商品的详细信息

Noah

在 KubeSphere 上快速安装和使用 KDP 云原生数据平台

智领云科技

开源 大数据平台 KubeSphere KDP

让企业知识触手可及,乐享基于腾讯云ES的RAG应用实践

腾讯云大数据

ES

和鲸“101”计划领航!和鲸科技携手北中医,共话医学+AI 实验室建设及创新人才培养

ModelWhale

人工智能 大数据 健康医疗

Mint Blockchain 正式发布 Public Mainnet,面向社区开放网络!

NFT Research

blockchain NFT\ Layer 2

App Uninstaller for Mac(mac软件卸载工具) v6.3(242)中文版

Mac相关知识分享

简单剖析 HTTP 请求方法

Liam

程序员 前端 Web 后端 HTTP

软件测试学习笔记丨测试开发体系介绍

测试人

软件测试 测试开发

X-ObjectMount: 对象存储访问接入的新选择

XSKY星辰天合

对象存储 软件定义存储 XSKY

PDF Expert for Mac(PDF编辑阅读转换器) v3.8.2版

Mac相关知识分享

pdf编辑器

用海外云手机养TikTok账号稳定吗?安全吗?

Ogcloud

云手机 海外云手机 tiktok云手机 云手机海外版 tiktok运营

从开发到引入解锁小程序插件

Geek_2305a8

【进阶篇】Java 项目中对使用递归的理解分享

EquatorCoco

Java Python windows

解决网络问题,多平台同步海外直播带货

Ogcloud

海外直播专线 海外直播 tiktok直播专线 海外直播网络 TikTok跨境直播

Parallels Desktop 19 for Mac(PD19虚拟机)无需关闭SIPv19.1.0

Mac相关知识分享

虚拟机软件

Photoshop 2021 for mac(PS2021)

Mac相关知识分享

数业智能进入全球应用算法模型大赛50强

心大陆多智能体

智能体 AI大模型 心理健康 数字心理

开源研发项目管理系统

爱吃小舅的鱼

项目管理软件 项目软件管理 Redmine 禅道项目管理软件

中台框架模块开发实践-用 Admin.Core 代码生成器生成通用代码生成器的模块代码

不在线第一只蜗牛

Java 架构 中台架构

Xcode for Mac(高效开发工具)v14.3.1正式版

Mac相关知识分享

开发工具

Charles for Mac(HTTP协议抓包工具)

Mac相关知识分享

如何定制化开发Serverless Framework的Component ?_服务革新_刘宇_InfoQ精选文章