文章仅代表作者本人的认知,如有谬误,欢迎指正。 本篇文章建议配合 @serverless/components 源码 食用
对于我们使用 Serverless Framework
的开发人员来说 sls
无疑是最常用的命令了
然而,当我们翻开 serverless
的源码一看,就会发现,cli 入口处实际上做了一个分支选项
const componentsV1 = require('@serverless/cli')
const componentsV2 = require('@serverless/components')
// Serverless Components v1 CLI (deprecated)
if (componentsV1.runningComponents()) return () => componentsV1.runComponents()
// Serverless Components CLI
if (componentsV2.runningComponents()) return () => componentsV2.runComponents()
@serverless/cli
作为 components
v1 版本,目前已经废弃
@serverless/components
是 components
v2 版本,也是 Serverless Framework
推出的最新解决方案
@serverless/components
和 @serverless/cli
相比有很多的优势:
Components v1 版本是本地版本,组件部署后,产生的状态存储在本地,如果切换开发机,会导致状态丢失,而且使用前都需要从 npm
拉到本地,依赖本地的开发环境。
Components v2 版本是云端版本,解决了这些痛点,状态在云端,模板在云端,我们只需要选择我们的组件,调用云服务就能轻松的完成部署工作
我们先把 @serverless/components
clone 到本地,(笔者为 3.9.2
版本)
这个文件中,有 2 个需要注意的地方:
"bin": {
"components": "./bin/bin"
},
这也就是说 当我们全局安装 @serverless/components
的时候,就可以直接使用components
命令了,它的本质其实就是 sls
的 v2 版本(见上面的代码块)
假设我们的项目,完全是使用 components
v2 版本构建的,那么大可直接安装此包,并且使用 components
命令来取代 serverless
命令
@serverless/platform-client
@serverless/platform-client-china
@serverless/utils
@serverless/utils-china
ps: 这些包 Github 上没有,我们可以直接在
node_modules/@serverless
中发现他们
platform-client
这类包实际上就是真正核心的 Sdk
了
utils
则是工具类
不过有意思的是,看上去名字长得差不多,包里面的内容却大相径庭
这里我把它分类为: 国内
,国外
*.serverless-dev.com
, *.serverless-platform.com
域名的请求上,他们自己也提供了很多的特色服务.china
的包,我们可得,serverless in china
就是一套 @tencent-sdk/capi
能力的封装,同时我们也可以在 utils-china/sdk
中发现很多的官方的 api 网关的地址 (地域:上海 & 广州)通过之前的 bin/bin
这个入口,我们来到了 src/cli/index.js
值得注意的是 isChinaUser()
国内有自己的 loadTencentGlobalConfig
逻辑和我们自己的 commands-cn
命令 (笑~)
我们为了更加贴合国内的使用方式,就只看 commands-cn/index.js
部分代码
可以看到目前主要有一下代码:
run
包含 deploy
remove
bind role
login
等等一系列命令info
用 org/stage/app/name
从服务端拉信息init
模板项目初始化dev
单实例调试模式registry
注册模板地址,默认地址目前可以去 utils-china/sdk/serverless/index.js
找到,还有就是 publish
, unpublish
最终都会转换为此命令。help
使用帮助param
(目前似乎没啥用 components -h
也没有显示此命令)credentials
全局凭证,是时候抛弃扫二维码和 .env
了 (笑~)我们挑选 2 个典型来讲,一个是 run
一个是 dev
deploy
就是我们最常用的部署命令了
从代码上看,先是做了一些验证格式化 validateAndFormat
然后用 preRunSrcHook
来处理 inputs.src
为 object/string
的各种情况
接着走 cache
方法,压缩上传我们的代码包,先 fast-glob
匹配一波,然后 adm-zip
压缩成 zip
and axios.put
上传 cos
最终在 utils-china/library/sls/v20200205/sls_client.js
中发请求告诉服务端这些信息,完成部署
和 deploy
一样,最终被转化为 library
的调用
TencentCAM.BindRole.BindRole
-> forceBindQCSRole
先调用是否支持调试的 doesRuntimeSupportDebug
, 从代码上看,只支持 nodejs
且版本大于等于 10.15
的版本
不得不说
nodejs
在这方面就是有天然优势
支持在线调试的,就 使用 tencentDebuggger.remoteDebug
, 然后创建 WshubClient
进行调试
不支持就利用 ws
创建一个 WebSocket
链接,和服务端的 log
打通,输出到本地的命令行
比较值得一说的就是 startTencentRemoteLogAndDebug
了
在线调试这里也利用 socket.io-client
连接远程服务端
我猜内部应该是,单实例 nodejs
通过 inspect
把调试的 ws link
暴露在外部,通过 token
鉴权,然后通过本地的 ws client
连接上,再映射到本地的 9222
端口:
const Client = function (options) {
const {
Url,
Token,
logType = 'error',
localPort = 9222,
debugRemotePort = 9000,
logRemotePort = 3332,
timeout,
} = options;
// 日志类型,verbose或者info,测试阶段建议verbose
this.logger = createLogger(logType);
// 映射的本地端口,默认9222
this.localPort = localPort;
// 远端调试端口,默认9000
this.debugRemotePort = debugRemotePort;
// 远端日志端口,默认3222
this.logRemotePort = logRemotePort;
// 连接wshub的超时时间
this.timeout = timeout;
this.Url = Url;
this.Token = Token;
};
看了这么多的代码,我们了解了这个 命令行工具 的本质
这样,我们可以利用这一点,创建出符合我们自己需求的,CLI,Web 和 Gui 客户端
platform-client-china/src/instance.js
-> deploy
-> run
-> api.instance.run
再到 platform-client-china/src/api.js
-> run
又到了 utils-china/sdk/serverless/index.js
-> runComponent
再到了 utils-china/library/sls/v20200205/sls_client.js
-> RunComponent
在 vscode 中创建自己的 workspace.code-workspace
, 添加 global
级别的 serverless
和 @serverless
路径
使用
npm -g bin
/yarn global bin
输出全局bin
路径 ps: npm 和 yarn 的全局包安装位置有可能不同,取决于当时安装serverless
的工具
然后使用 vscode JavaScript Debug Terminal
, 直接敲命令 components dev
/ npm run sls:dev
等等,就可以直接命中断点
npm -g bin
/ yarn global bin
输出全局 bin
路径
ps: npm 和 yarn 的全局包安装位置有可能不同,取决于当时安装serverless
的工具
然后使用 vscode JavaScript Debug Terminal
, 直接敲命令 components dev
/ npm run sls:dev
等等,就可以直接命中断点