写点什么

如何定制化开发 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:351879

评论

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

ps2024新功能 修图软件ps 2024 beta 25.0安装 Photoshop激活版

mac

PhotoShop 图像处理软件 苹果mac Windows软件 ps2024

云行|算赋山水涪州,天翼云中国行·重庆涪陵站活动成功举办!

天翼云开发者社区

人工智能 云计算

一文搞懂ThreadLocal原理

树上有只程序猿

多线程 ThreadLocal

浪潮云参编的《数字政府网络安全合规性指引》正式发布

云安全

“国云入闽 数耀鹭岛”,中国电信天翼云创新助力数字福建新征程!

天翼云开发者社区

人工智能 云计算

Presto 设计与实现(十四):SQL 查询过程总结

冰心的小屋

sql 数据湖 presto 设计与实现

英特尔锐炫显卡助力玩家高帧率畅玩《重生边缘》,尽享超清画质

E科讯

实信达:基于鲲鹏DevKit开发综合档案管理系统,档案管理更便捷

彭飞

引爆用户参与:消息重弹,让您的推送不再被忽略

MobTech袤博科技

前端 智能投放 Androdi 智能推送

释放开发人员生产力:“文档级”代码了解一下?

飞算JavaAI开发助手

代码质量 开发工具 开发人员

中国移动云能力中心:基于鲲鹏DevKit开发移动云云数据库,让数据并行访问更高效

彭飞

软件测试/测试开发丨Jenkins Pipeline 学习笔记

测试人

软件测试 jenkins CI/CD pipeline 测试开发

2023年软件开发领域的发展趋势

树上有只程序猿

软件开发

荣誉拉满!国云向新,“算”出新未来!

天翼云开发者社区

云计算

Vue低代码 -- 走进低代码

互联网工科生

Vue 低代码

【原理篇】Supabase 权限模型 Part2

张文平

Serverless API sdk 权限控制 Supabase

适配器模式:如何让不兼容的接口变得兼容

越长大越悲伤

设计模式 适配器模式

Acrobat Pro DC 2023 for mac(专业PDF编辑软件)v2023.003.20244中文直装版

mac

windows Acrobat Pro DC 2023 苹果mac PDF编辑和管理软件

火山引擎边缘云助力智能科技赋予生活更多新意

火山引擎边缘云

对象存储 视频 边缘云

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