by yugasun from yugasun.com/post/server… 本文可全文轉載,但須要保留原做者和出處。html
上一篇 基於 Serverless Component 的全棧解決方案 介紹 Serverless Component 是什麼和如何使用 Serverless Component 開發一個全棧應用。可是目前社區還不夠完善,當咱們須要一個尚未的組件時,怎麼辦呢?vue
與其向官方提交 issue
,說明需求,不如本身動手擼一個,豈不快哉~git
在開始開發以前,咱們先來了解下 Serverless Component 的運行機制:程序員
每一個 Serverless Component 實際上就是一個 npm
包,你能夠經過 npm install
命令直接安裝。當咱們在一個依賴 Serverless Component 的應用中,執行命令 serverless --debug
部署時,它首先會讀取 serverless.yml
文件中的 component
參數指定組件模塊,它會像安裝 npm
包同樣,自動安裝到本地,而後自動注入該組件模塊,同時執行組件中的 default
函數(以後會講到),從而完成部署流程。github
一個完整組件的開發流程應該包括如下流程:web
接下來將按照以上步驟,一步一步實現騰訊雲 CDN 組件。shell
騰訊雲 CDN 控制檯 已經提供了手動配置加速域名的功能,可是做爲一名懶惰的程序員, 「手動」 一直都是我嘗試規避的問題。因而去看了看騰訊雲文檔,看看官方有沒有提供相應便捷的方式。果不其然騰訊雲 API 已經提供了相關接口,那麼咱們爲何不借助 API 實現一個可以幫助咱們自動配置的 CDN 組件呢?npm
需求很明確:開發一個可以自動配置 CDN 加速域名的組件,幫助咱們節省手動配置時間。json
要實現 CDN 域名的添加,須要藉助2個騰訊雲API 接口:新增長速域名、HTTPS 配置。經過閱讀這兩份接口文檔,總結出一份配置說明文件 config.md
,內容以下:api
MyCDN:
component: '@serverless/tencent-cdn'
inputs:
host: abc.com
hostType: cos
origin: www.test.com
backupOrigin: www.test.com
serviceType: web
fullUrl: on
fwdHost: ww.test.com
cache:
- type: 0
rule: all
time: 1000
- type: 0
rule: all
time: 1000
cacheMode: simple
refer:
- type: 1
list:
- 'qq.baidu.com'
- '*.baidu.com'
accessIp:
type: 1
list:
- '1.2.3.4'
- '2.3.4.5'
https:
certId: 123
cert: 123
privateKey: 123
http2: off
httpsType: 2
forceSwitch: -2
複製代碼
其中 inputs
就是組件的輸入參數,其實這些參數都是從接口文檔中拷貝出來而已,實際開發時,需根據本身組件功能,定製化配置就好。
無服務框架的配置都是
yaml
文件,因此在定義組件配置時,須要將 API 的參數作好yaml
規範映射。好比yaml
文件中,符號-
是用來定義數組的。若是對 yaml 語法還不太熟,能夠參考這份 YAML 語言教程。
組件輸入定義好了,還須要定義輸出內容,只須要大體的組織 API 請求返回結構就行,儘可能簡潔明瞭:
{
host: 'abc.com',
hostId: '123'
origin: 'www.test.com',
cname: 'www.test.com.cdn.dnsv1.com',
https: true
}
複製代碼
對於一個標準的 Serverless Component ,結構以下:
// serverless.js
const { Component } = require('@serverless/core')
class MyComponent extends Component {
/* * Default (必須) * - default 是用來執行、準備和更新你的組建的函數 * - 執行命令 `$ serverless` 會運行此函數 * - You can run this function by running the "$ serverless" command */
async default(inputs = {}) {
return {}
}
/* * Remove (可選) * - 若是你的組件須要刪除基礎設施,推薦你添加他 * - 執行命令 `$ serverless remove` 會運行此函數 */
async remove(inputs = {}) {
return {}
}
/* * Anything (可選) * - 若是你想發佈帶有額外功能的組件,你能夠將邏輯寫在一個函數裏,函數名能夠自定義 * - 執行命令 `$ serverless anything` 會運行此函數 */
async anything(inputs = {}) {
return {}
}
}
module.exports = MyComponent
複製代碼
瞭解了組件的結構,接下來,就開始開發吧~
建立項目目錄 tencent-cdn
,執行 npm init
初始化項目,根據命令指引,填寫相關信息就行:
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (cdn-module) tencent-cdn
version: (1.0.0)
description: Tencent Cloud CDN Component
entry point: (index.js) serverless.js
test command:
git repository:
keywords: cdn,serverless,serverless-component,serverlesscomponent,tencent
author: yugasun
license: (ISC) MIT
About to write to /Users/yugasun/Desktop/Develop/serverless/cdn-module/package.json:
{
"name": "tencent-cdn",
"version": "1.0.0",
"description": "Tencent Cloud CDN Component",
"main": "serverless.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"cdn",
"serverless",
"serverless-component",
"serverlesscomponent",
"tencent"
],
"author": "yugasun",
"license": "MIT"
}
Is this OK? (yes)
複製代碼
而後新建 serverless.js
文件,複製上面的模板代碼到 serverless.js
文件中。
default
函數代碼,這裏就不貼出來了,有點多 o(╯□╰)o。
主要思路就是,根據 inputs
輸入參數,規範成接口請求參數,而後請求接口,執行配置就好。
對於騰訊雲 API,全部的接口請求都須要鑑權,因此這裏須要先實例化一個 Capi
,以下:
import { Capi } from '@tencent-sdk/capi'
const capi = new Capi({
SecretId: this.context.credentials.tencent.SecretId,
SecretKey: this.context.credentials.tencent.SecretKey,
ServiceType: 'cdn',
})
複製代碼
注意:關於請求雲 API 庫 @tencent-sdk/capi 說明文檔已經很全面了,固然你也能夠在這裏看到 源碼.
它須要傳入 SecretId
、SecretKey
、ServiceType
三個參數,SecretId
和 SecretKey
能夠經過 this.context.credentials.tencent
來獲取,執行 serverless
命令在執行時,它會根據用戶項目根目錄配置的 .env
文件,自動注入到 this.context.credentials.tencent
上。ServiceType
是當前服務類型,這是騰訊雲 API 定義的,針對不一樣業務配置相應參數就行。
注意:不一樣的雲服務商掛到
this.context.credentials
上的屬性也是不同,好比這裏騰訊雲是tencent
,AWS 是aws
,目前支持的全部雲服務商的屬性配置源碼,在這裏能夠找到,@serverless/cli
而後請求 新增長速域名 接口:
// cdnInputs 就是咱們組裝好的請求參數
await AddCdnHost(capi, cdnInputs)
複製代碼
這裏有個重點:請求 新增長速域名
接口成功返回後,CDN 並不會當即部署成功,這個是須要時間的,因此咱們執行後,須要輪訓當前新增域名的狀態,當爲部署成功時,咱們才能進行以後的邏輯。
Serverless Component 在執行 default
函數時,它會產生一些狀態,好比新增 CDN 域名成功後,會產生一個 hostId
,咱們能夠保存在 this.state
對象中,經過執行 this.save()
函數,它會將 this.state
保存到項目根目錄的 .serverless
文件夾中一個名爲 Template.MyCDN.json
(MyCDN
是我定義的當前 Serverless 應用的名稱)文件中,方便以後在作組件建刪除時使用。
Serverless Component 刪除的邏輯,就是再 serverless remove
命令時,它會讀取 default
函數執行保存到 .serverless
中的狀態文件,並注入到 this.state
上 , 而後咱們能夠根據 state
中的值進行移除,好比我這裏會用到 host
, 由於 刪除加速域名接口 須要傳遞 host
參數。
開源項目的 README 必定要寫的清晰明瞭,方便開發者順利的使用和開發。
到這裏咱們組件的基本開發完成了,在發佈以前,還得進行本地測試,Serverless Framework 提供了一個很好地本地調試方法,就是應用的 serverless.yml
中 component
能夠指定本地項目路徑,好比在 tencent-cdn
目錄下,建立 test
文件夾,而後新增 serverless.yml
配置以下:
MyCDN:
component: ../
inputs:
host: abc.com
...
複製代碼
這裏的 ../
就是相對路徑,由於 tencent-cdn
組件的 serverless.js
文件在 tencent-cdn
根目錄下,以後咱們就能夠進入 test
目錄,執行部署和移除操做,來測試咱們的組件了。
注意:雖然一個 Serverless Component 是一個 npm 模塊,咱們能夠經過
package.json
中的main
屬性指定項目中任意的文件入口,可是若是沒有serverless.js
文件,serverless
命令是無法經過component
指定的本地路徑調試的。
發佈 npm 包,首先須要你擁有一個 npm 帳號,請先前往 npm官網 註冊,而後本地執行 npm login
登陸你的帳號。
通過測試沒問題,就能夠執行 npm publish
就能夠發佈到 npm 倉庫了。
最終實現源碼:@serverless/tencent-cdn。
每一個組件實例,都會有個 load
方法,咱們能夠經過此方法來加載其餘組件,以下:
const cdnComp = await this.load('@serverless/tencent-cdn', 'cdnComp');
複製代碼
藉助此功能,咱們能夠實現不少高階組件,好比 @serverless/tencent-website 就是一個很好地案例。
至於如何組合你的組件,實現本身的需求,就靠你本身去天馬行空了,是否是已經躍躍欲試了?快來社區貢獻你的一份力量吧~
這裏有個騰訊雲 Serverless Component 開發模板,能夠幫你快速開發一個 Serverless Component。