Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【腾讯云Serverless】腾讯云Serverless + Typescript实践

【腾讯云Serverless】腾讯云Serverless + Typescript实践

原创
作者头像
Juli
发布于 2019-08-22 07:24:27
发布于 2019-08-22 07:24:27
151.9K02
代码可运行
举报
运行总次数:2
代码可运行

目的

最近serverless愈来愈火,我刚好在培训,比较有时间去尝试一些新东西,所以趁这个时候去使用下serverless,尝试使用typescript和nodejs开发,部署在腾讯云scf上的一个小工具,探讨下typescript + nodejs + scf的最好实践模式,并同时抛钻引玉,希望有同学提供更好的方案。

项目介绍

想法

由于本人平时会追一些小说,动漫,电视剧等,但是它们更新的时候,我一般是不感知的,都是等我得空或者睡前的时候,我才会去它们的网站去查看下它们是否更新。如果有这么一个工具,能够在它们更新的时候,告知我,它更新了,更新了啥,那么我就不需要老是用手机去查询,对我起到了一定的便利作用。

这放在我没有接触到serverless之前,我的想法是这样的:写一个这么的程序是不难,但是我得去买个机器去部署啊;如果有问题不能及时发现同时又得上机器查日志;还得自己去控制程序定时爬取的逻辑等等等。总的来说就是,实现与维护一个这样的程序的成本远大于了其带给我的便利,让我有想法却懒于行动。

但是了解serverless的概念后,以上提到阻碍我行动的问题变得不再是问题,例如部署难题,使用serverless就是使用云供应商提供的开发者工具创建函数,打包上传代码即部署成功;又例如定时爬取逻辑,使用其提供的定时触发器能力即可,都大大方便了我的开发,让我更专注于代码实现。这里我不会很官方地去说serverless的概念以及好处,仅是从一个开发者的角度去阐述我的想法。

实践
  • 流程图 程序的整个流程图如下图所示,逻辑很简单,这个项目的目的不在于实现一个多厉害的功能,而在于ts + node + scf的实践方式的探索。
  • 开发 开发能在scf运行的nodejs程序的其实与传统的开发nodejs程序在语言编写上并没有太大区别。比较明显的不同在于,我们开发时得有一个入口的函数,比如像这样:

更具体的入门文档,可以看此处,跟着文档一步步学习编写一个简单的函数。接下来回归正题。

  • 环境搭建
    • 首先为了方便开发,建议安装腾讯云scf提供的命令行工具或者vscode插件。但是这里我开发的时候vscode插件还没发布,所以这里主要使用命令行工具,命令行工具的安装与使用的文档,具体可以看此处
    • 安装好后,使用 scf init具体参数得去看文档填写,这个提个建议,scf init提供交互式操作,采取问答的模式去创建)创建一个项目、项目文件很简单,一共就四个文件,前三个,应该不多做介绍。第四个文件template.yaml称为模板文件,简单来说是描述这个函数的文件,比如函数的环境变量,触发器类型等等,具体还是前往文档处查看吧。
    • 接下来,就是正常配置tsconfig.json,如果没有安装typescript的同学请去官网安装,然后tsc --init就可以快速生成一个tsconfig.json,然后根据自己的需求配置即可。
    • 然后,就是编写npm scripts。 主要就三个操作,build,dev,deploy。 可以使用npm scripts把typescript的编译和scf cli的本地调试,打包和部署串联在一起,使需要敲打的命令简洁和语义化
    • 最后,将本地仓库与远程仓库关联起来。(这里提一个优化:有一种场景是用户已经创建了一个git仓库,现在需要将仓库里的代码写成scf模式下的代码,并配合scf cli使用,目前scf cli只支持init一个完整的项目,如果支持在一个已有项目中快速生成调试和部署的yaml,对开发者来说是一个比较方便的功能
  • 编码

我的主要逻辑代码分为上面的文件。

  • index,没什么好说的,就是一个入口文件,负责组合其余模块的逻辑。
  • config以及config_extra,config_extra文件放了我的隐私配置,例如redis的host,port和密码以及邮件服务的授权码等,这些配置通过配合.gitignore是不会提交到远程git仓库,而config文件则是引入config_extra文件中的配置,并与一些通用配置进行merge,然后输出到各个模块。(注:此处也可以好好利用scf提供的环境变量功能,很适合这种场景,具体文档
  • config_extra_demo,告诉别的开发者,config_extra文件应该如何编写。
  • mailer,封装邮件服务的初始化以及发送邮件方法
  • redis,封装redis的连接以及同步set以及get方法
  • task,暂时简单封装了下初始化以及执行的通用逻辑。但日后该工具扩展,此处仍得考虑如何抽象以及通用化。
  • util,封装了一些公用方法,例如封装了retry方法,来包装一些异步函数。

上面简单介绍下主要逻辑代码的文件,具体的实现,有兴趣可以移步到 github地址 查看

  • 调试 上面也有提到我编写的npm scripts里有npm run dev的一条。本人开发这个项目时,调试都执行npm run dev来进行调试。这里提一下,测试环境一般是需要和正式环境隔离的。所以可以新建一个 env.json文件,里面填写 { "NODE_ENV": development } 并将npm script中的dev命令改成 npm run build && scf local generate-event timer timeup | scf native invoke --template template.yaml --env-vars env.json 然后在配置文件中根据process.env.NODE_ENV变量来判断是测试环境还是正式环境,并填写对应环境依赖的服务的配置即可。
  • 部署 上面讲了这么多,其实都不是我最想表达的,因为我并没有在上面遇到一些很棘手的问题。而在部署的时候,我才发现在使用typescript时,无法在腾讯云scf目前的部署要求以及项目的文件目录管理中做到完美的配合

后面和同事讨论后,还是有不错的方法是达到两者的平衡。下面是我的多次尝试的一个过程。 如果不使用typescript,仅使用js编写nodejs程序,则不需要编译的过程,部署函数时,只需要打包然后部署即可;但是使用typescript后,则多了一步将ts代码编译成js代码的步骤。为了管理好项目的文件目录,我倾向于ts和js文件分别存放在不同的文件夹,例如,src文件夹存放ts文件,dist则是编译后得到的js文件。我一开始的文件目录便是如此。

  • 第一次尝试 文件目录:

tsconfig.json 指定编译src文件夹下的ts文件,输出到dist文件夹

template.yaml CodeUri指向dist文件夹

根据上面的配置,在本地调试是可以的。但是当部署到云上,测试是失败的。如果大家熟练的话可以立刻发现问题所在,打包没有把node_modules打包进去。主要逻辑代码依赖的第三方库全都找不到,测试当然失败了。

  • 第二次尝试 根据第一次尝试,我使用npm scripts的pre钩子,在执行部署前,编辑ts代码,同时把node_modules拷贝到dist文件夹,然后再打包部署解决了这个问题。 package.json

copy_node_modules.js

dist文件夹下的文件

虽然这样做可以运行了,在本地文件目录管理合理,但是提交到云上的代码是编译后的,基本没啥可读性,就是一坨能运行的东西,项目代码也不完整。所以个人认为,最完美的是本地开发的项目代码和交到云上的项目代码是一致的,不需要通过额外的脚本去阉割。虽然目前腾讯云scf控制台的webIDE还只是能看入口文件,不过之后会接入cloud studio,起码可以看到整个代码文件夹的每个文件,说不定以后就支持在线支持typescript编译(虽然不知道可不可能)。所以本人开始了第三次尝试。

  • 第三次尝试 我有一个想法:template.yaml中指定的Handler,即入口函数,从index.main_handler 写成 文件夹/index.main_handler,即入口函数可以在某个文件夹里。 我在template.yaml处的Handler写成dist/index.main_handler,CodeUri写成了根目录,这样就可以打包整个文件夹,然后指定Handler为dist文件夹的index文件的main_handler函数。 template.yaml

本地调试时,是成功的! 但是在部署的时候,

额,好吧,我觉得是这个方案是不行的了,因为不符合scf的要求,通过不了校验。

  • 第四次尝试 这是我第四次尝试。但是不是最完美的,在文件管理退了一步,允许ts和编译后的js放在一起。这样能做到把整个项目都打包上去,而且可运行,但是ts和js放在一起,文件管理不太合理。修改的地方如下: index.ts文件从src文件夹移动到根目录 tsconfig.json 编辑根目录下的index.ts和src文件夹下的ts文件,剔除node_modules,输出到根目录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
![image](https://user-images.githubusercontent.com/23744602/61192443-e1a6ba80-a6e6-11e9-98f9-c79aaed5cfa3.png)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template.yaml
​
CodeUri改成根目录,Handler改成 index.main_handler,即跟cli生成的一样
​
![image](https://user-images.githubusercontent.com/23744602/61192437-d9e71600-a6e6-11e9-96ae-b298715c0d2d.png)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
编译后结果
​
![image](https://user-images.githubusercontent.com/23744602/61192447-e9665f00-a6e6-11e9-926c-43eaea8c0302.png)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
最后部署到云上scf,是可以运行的,而且是把整个项目都打包了上去,日后腾讯云scf接入了cloud studio,webIDE看到的文件架构和本地看到的文件架构是一致的。
  • 第五次尝试 兜兜转转,有时候问题解决很简单。和组内同事讨论后,一位大佬同事点出: 可不可以在根目录写一个index文件,然后调用编译后的index文件的入口方法?。 一语惊醒梦中人!是的,一开始就没注意到,还可以这样解决,思维一直在一个圈子里绕来绕去,没有跳出来。这样做的成本很低,而且能达到了我之前说到的理想状态: 本地开发的项目代码和交到云上的项目代码是一致的,不需要通过额外的脚本去阉割 实施方法即是,把typescript文件放在src文件夹下,编辑后的js文件放在dist文件夹下,在根目录编写一个index.js文件,文件里的main_hanlder方法调用编译后的index文件的入口函数,下面是一些核心代码。 index.js

tsconfig.json

template.json

编译后结果

成果

简单展示下代码线上运行后的结果。

总结

上面说了这么多,这里给一个总结就是:

虽然腾讯云scf没有原生支持typescript,但是经过一些方法还是可以做到两者的完美配合

首先本地开发是没啥问题的,上面提到的尝试,都是为了能够在本地调试成功的同时可以部署到云上。

主要是部署的问题,其中可行的三个尝试:

第一个是通过一些额外的方法去适配,但是做不到云上的项目和实际的项目的一致,如第二次尝试。

第二个是文件管理上退了一步,不做到极致的分明,如第四次尝试。

第三个是在根目录写一个index.js文件,调用具有真正逻辑的入口函数,做个转发,如第五次尝试,也就是本人认为目前最好的实践方式。

最后,以上的五个尝试,是本人开发的时候的想法与实践,也许不太正确,有误欢迎大家来批评。如果大家有更好的方法,欢迎讨论。五次尝试的源码都在github仓库,前四次尝试均有对应分支,master分支为第五次尝试。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
美国队长的盾(二)五角星
前面我们已经把四个同心圆画好了(美国队长的盾(一) 同心圆),就缺“画龙点睛”之笔的五角星了。那么今天我们就来纯手工打造这样一个五角星。
生信交流平台
2020/08/06
1.2K0
美国队长的盾(二)五角星
靠数学“拿了”两次诺贝尔奖,彭罗斯从“铺地砖”帮忙发现2011年化学奖的秘密
晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 诺贝尔奖没有数学奖,但是如果数学足够好的话,可以拿两次诺贝尔奖: 帮别人拿一次,自己再拿一次。 刚刚获得诺贝尔奖的英国数学家罗杰·彭罗斯(Roger Penrose)就是这样。 今年,彭罗斯凭借数学在广义相对论和黑洞研究中的应用,获得了诺贝尔物理学奖。 而在几十年前,彭罗斯的另一项数学发现曾帮助别人获得过诺贝尔奖。 2011年,以色列科学家丹尼尔·舍特曼(Daniel Shechtman)因为发现准晶体获得了当年的诺贝尔理综化学奖。 准晶体于
量子位
2023/03/10
8550
靠数学“拿了”两次诺贝尔奖,彭罗斯从“铺地砖”帮忙发现2011年化学奖的秘密
数学原来这么有趣,66组超炫动图唤醒你的思维!
无论怎样,看完这一组动图,你不仅能够感受到数学美丽的一面,同时也会对我们常见的公式定理有更深刻、直观的理解!
IT阅读排行榜
2019/01/23
1.3K0
数学原来这么有趣,66组超炫动图唤醒你的思维!
Python之turtle模块-正多边形
前面我们用turtle画了正方形,也就是正四边形,虽然我们平时不这么叫它。我们今天来画正多边形。顾名思义就是边数大于等于三条,并且每条边的长度都一样。美国的五角大楼就是正五边形。
生信交流平台
2020/08/06
2K0
Python之turtle模块-正多边形
MFC绘图小实验(2)
1,以正五边形的5个顶点为基础,隔点存储构成五角星。填充模式采用WINDING。五角星边界线为5个像素宽的蓝色实线,内部使用红色填充。 CRect rect; //定义矩形 GetClientRect(&rect); //获得客户区矩形 pDC->SetMapMode(MM_ANISOTROPIC); //设置映射模式 pDC->SetWindowExt(rect.Width(),rect.Height()); //设置窗口 pDC->SetViewportE
Zoctopus
2018/06/04
1.6K0
python与分形0015 - 【教程】五星红旗
不知不觉,今天又周五,513330都快破6了,倒金字塔加仓都加到地下室了,真是服气了。
滚神大人
2021/12/09
8750
python与分形0015 - 【教程】五星红旗
OpenCV-Python学习(13)—— OpenCV 多边形填充与绘制(cv.fillPoly、cv.polylines)
1. 知识点 学习 cv.polylines 函数的使用; 学习 cv.fillPoly 函数的使用。 2. 绘制折线或多边形 cv.polylines 函数说明 2.1 函数使用 cv.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) → img 2.2 参数说明 参数 说明 img 表示要在其上绘制矩形的图像的img对象。 pts 表示一个或多个点集。 isClosed 表示标志,决定所绘制的多边形是否闭合。若为
Rattenking
2022/11/14
4.3K0
OpenCV-Python学习(13)—— OpenCV 多边形填充与绘制(cv.fillPoly、cv.polylines)
网页CAD二次开发实现圆转多边形的详细教程
在线CAD SDK的集成过程中,甲方客户可能有实现圆转多边形功能的需求,作为开发者如何利用WEB CAD SDK展现此功能效果呢?本章节我们重点讲述一下。
梦想云图网页CAD
2024/04/09
1910
网页CAD二次开发实现圆转多边形的详细教程
三角形的内角和等于180°?不对!
导读: “三角形内角和等于180°”,这对于我们来说是再熟悉不过的一个常识,陈省身教授从一个不同的角度去看待这个问题,并将这个问题延伸推广,于1944年,找到了一般曲面上封闭曲线方向改变量总和的公式(高斯—比内—陈公式),把几何学引入了新的天地,被誉为划时代的贡献。
IT阅读排行榜
2018/08/17
1.3K0
Flutter 绘制番外篇 - 圆中取形
对一些有趣的绘制 技能和知识, 我会通过 [番外篇] 的形式加入《Flutter 绘制指南 - 妙笔生花》小册中,一方面保证小册的“与时俱进” 和 “活力”。另一方面,是为了让一些重要的知识有个 好的归宿。
张风捷特烈
2022/03/18
8030
Flutter 绘制番外篇 - 圆中取形
Android关于Path你所知道的和不知道的一切
张风捷特烈
2024/01/26
3000
Android关于Path你所知道的和不知道的一切
OpenGL ES 2.0 (iOS)[03]:熟练图元绘制,玩转二维图形
文章的大前提是,你得有《OpenGL ES 2.0 (iOS): 一步从一个小三角开始》的基础知识。
半纸渊
2018/09/04
1.7K0
OpenGL ES 2.0 (iOS)[03]:熟练图元绘制,玩转二维图形
requireJs的使用,以canvas绘制星空为例
RequireJS是符合AMD规范(Asynchronous module definition异步模块加载)一种js加载方式,目的是为了防止加载js的时候阻塞html页面渲染,其使用非常简单。 首先要去下载一个require.js,网址:http://requirejs.org/docs/download.html 在html文件中引入require.js: <script type="text/javascript" data-main="js/main" src="js/require.js" de
lonelydawn
2018/02/09
1.2K0
requireJs的使用,以canvas绘制星空为例
绘图-UIBezierPath
UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径.此类是Core Graphics框架关于path的一个OC封装。 所以 UIBezierPath 是基于 Core Graphics 实现的一项绘图技术。
進无尽
2018/09/12
1.4K0
绘图-UIBezierPath
小游戏系列之五环盾牌
本节主要介绍pygame的初级教程,以及如何用pygame去绘制奥运五环及美国队长盾牌。
公众号guangcity
2019/09/20
8840
小游戏系列之五环盾牌
Android关于Path你所知道的和不知道的一切
零、前言 1.canvas本身提供了很多绘制基本图形的方法,普通绘制基本满足 2.但是更高级的绘制canvas便束手无策,但它的一个方法却将图形的绘制连接到了另一个次元 3.下面进入Path的世界,[注]:本文只说Path,关于绘制只要使用Canvas.drawPath(Path,Paint)即可 4.本文将对Path的所有API进行测试。 ---- 一、引:认识Path 例1.绘制网格 在Canvas篇我用Path画过一个网格辅助,在这里分析一下 moveTo相当于抬笔到某点,lineTo
张风捷特烈
2018/12/07
2.6K0
大学课程 | 计算机图形学,基于MFC和二维变换的画图软件
本文描述了二维复合变换的基本方法和思想,根据鼠标位置坐标获取起始点pStart和终止点pEnd的坐标,设计实现每个基本图形的画图方法,根据pStart和pEnd即可确定基本图形的控制点,进而绘制对应图形。规范化齐次坐标以后,图形几何变换可以表示为图形控制点点集合的规范化齐次坐标矩阵与二维变换矩阵相乘的形式,分别设置二维变换矩阵的参数信息,设计实现对应的方法,即可实现图形的二维变换功能。
Justlovesmile
2021/12/14
2.6K0
大学课程 | 计算机图形学,基于MFC和二维变换的画图软件
开源计划之--Android绘图库--LogicCanvas
在html5时,我用JavaScript封装了一个HTML5的canvas库。
张风捷特烈
2018/09/02
1.4K0
开源计划之--Android绘图库--LogicCanvas
手 Q 人脸识别动画实现详解
该文介绍了如何通过自定义View和动画实现圆形进度条的绘制,主要利用了Canvas、Path、Paint等类进行实现。同时介绍了如何实现圆形进度条在Canvas上的动画展示,包括自定义动画、ObjectAnimator、属性动画等。同时,还介绍了如何实现圆形进度条和圆形图片的切换,主要利用了自定义属性动画和ObjectAnimator进行实现。该文还介绍了如何实现圆形进度条的长度调节和点击调节,主要利用了自定义调节器和动画监听器进行实现。最后,该文介绍了如何将圆形进度条应用到圆形图片的展示上,主要利用了自定义圆形图片控件和圆形进度条组件进行实现。
QQ空间开发团队
2017/11/02
4.9K1
手 Q 人脸识别动画实现详解
用SVG实现一个优雅的提示框
Tooltips常被称为提示框(或信息提示框),提示框能够以较强的交互性、自由度为用户提供相应的提示信息。今天我们要聊的不是如何实现强大的交互行为,而是来看看如何以最好的方式来还原他们的视觉效果,并且能适用于不同的场景。
ConardLi
2020/06/10
2.6K0
用SVG实现一个优雅的提示框
相关推荐
美国队长的盾(二)五角星
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验