如何開發(fā)自己的第一個 Serverless Component

serverless-components

by yugasun from https://yugasun.com/post/serverless-fullstack-vue-practice.html
本文可全文轉(zhuǎn)載,但需要保留原作者和出處。

前言

上一篇 基于 Serverless Component 的全棧解決方案 介紹 Serverless Component 是什么和如何使用 Serverless Component 開發(fā)一個全棧應(yīng)用遗契。但是目前社區(qū)還不夠完善,當(dāng)我們需要一個還沒有的組件時囚衔,怎么辦呢喜滨?

與其向官方提交 issue鳄抒,說明需求知允,不如自己動手?jǐn)]一個撒蟀,豈不快哉~

Serverless Component 運行機制

在開始開發(fā)之前,我們先來了解下 Serverless Component 的運行機制:

每個 Serverless Component 實際上就是一個 npm 包温鸽,你可以通過 npm install 命令直接安裝保屯。當(dāng)我們在一個依賴 Serverless Component 的應(yīng)用中,執(zhí)行命令 serverless --debug 部署時涤垫,它首先會讀取 serverless.yml 文件中的 component 參數(shù)指定組件模塊姑尺,它會像安裝 npm 包一樣,自動安裝到本地蝠猬,然后自動注入該組件模塊切蟋,同時執(zhí)行組件中的 default 函數(shù)(之后會講到),從而完成部署流程吱雏。

開發(fā)步驟

一個完整組件的開發(fā)流程應(yīng)該包括以下流程:

  1. 明確功能需求
  2. 定義組件配置:輸入和輸出參數(shù)
  3. 組件開發(fā):default 函數(shù)敦姻、remove 函數(shù)(可選)
  4. 測試組件
  5. 發(fā)布 npm 包

接下來將按照以上步驟,一步一步實現(xiàn)騰訊云 CDN 組件歧杏。

1. 明確功能需求

騰訊云 CDN 控制臺 已經(jīng)提供了手動配置加速域名的功能,但是作為一名懶惰的程序員迷守, “手動” 一直都是我嘗試規(guī)避的問題犬绒。于是去看了看騰訊云文檔,看看官方有沒有提供相應(yīng)便捷的方式兑凿。果不其然騰訊云 API 已經(jīng)提供了相關(guān)接口凯力,那么我們?yōu)槭裁床唤柚?API 實現(xiàn)一個能夠幫助我們自動配置的 CDN 組件呢?

需求很明確:開發(fā)一個能夠自動配置 CDN 加速域名的組件礼华,幫助我們節(jié)省手動配置時間咐鹤。

2. 定義組件配置

要實現(xiàn) CDN 域名的添加,需要借助2個騰訊云API 接口:新增加速域名圣絮、HTTPS 配置祈惶。通過閱讀這兩份接口文檔,總結(jié)出一份配置說明文件 config.md ,內(nèi)容如下:

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 就是組件的輸入?yún)?shù)捧请,其實這些參數(shù)都是從接口文檔中拷貝出來而已凡涩,實際開發(fā)時,需根據(jù)自己組件功能疹蛉,定制化配置就好活箕。

無服務(wù)框架的配置都是 yaml 文件,所以在定義組件配置時可款,需要將 API 的參數(shù)做好 yaml 規(guī)范映射育韩。比如 yaml 文件中,符號 - 是用來定義數(shù)組的闺鲸。如果對 yaml 語法還不太熟座慰,可以參考這份 YAML 語言教程

組件輸入定義好了翠拣,還需要定義輸出內(nèi)容版仔,只需要大致的組織 API 請求返回結(jié)構(gòu)就行,盡量簡潔明了:

{
    host: 'abc.com',
    hostId: '123'
    origin: 'www.test.com',
    cname: 'www.test.com.cdn.dnsv1.com',
    https: true
}

3. 組件開發(fā)

對于一個標(biāo)準(zhǔn)的 Serverless Component 误墓,結(jié)構(gòu)如下:

// serverless.js
const { Component } = require('@serverless/core')
class MyComponent extends Component {
  /*
   * Default (必須)
   * - default 是用來執(zhí)行蛮粮、準(zhǔn)備和更新你的組建的函數(shù)
   * - 執(zhí)行命令 `$ serverless` 會運行此函數(shù)
   * - You can run this function by running the "$ serverless" command
   */
  async default(inputs = {}) {
    return {}
  }

  /*
   * Remove (可選)
   * - 如果你的組件需要刪除基礎(chǔ)設(shè)施,推薦你添加他
   * - 執(zhí)行命令 `$ serverless remove` 會運行此函數(shù)
   */
  async remove(inputs = {}) {
    return {}
  }

  /*
   * Anything (可選)
   * - 如果你想發(fā)布帶有額外功能的組件谜慌,你可以將邏輯寫在一個函數(shù)里然想,函數(shù)名可以自定義
   * - 執(zhí)行命令 `$ serverless anything` 會運行此函數(shù)
   */
  async anything(inputs = {}) {
    return {}
  }
}
module.exports = MyComponent

了解了組件的結(jié)構(gòu),接下來欣范,就開始開發(fā)吧~

3.1 初始化項目

創(chuàng)建項目目錄 tencent-cdn变泄,執(zhí)行 npm init 初始化項目,根據(jù)命令指引恼琼,填寫相關(guān)信息就行:

$ 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 文件妨蛹,復(fù)制上面的模板代碼到 serverless.js 文件中。

3.2 編寫 default 函數(shù)

default 函數(shù)代碼晴竞,這里就不貼出來了蛙卤,有點多 o(╯□╰)o。

主要思路就是噩死,根據(jù) inputs 輸入?yún)?shù)颤难,規(guī)范成接口請求參數(shù),然后請求接口已维,執(zhí)行配置就好行嗤。

對于騰訊云 API,所有的接口請求都需要鑒權(quán)垛耳,所以這里需要先實例化一個 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',
})

注意:關(guān)于請求云 API 庫 @tencent-sdk/capi 說明文檔已經(jīng)很全面了飘千,當(dāng)然你也可以在這里看到 源碼.

它需要傳入 SecretIdSecretKey既琴、ServiceType 三個參數(shù)占婉,SecretIdSecretKey 可以通過 this.context.credentials.tencent 來獲取,執(zhí)行 serverless 命令在執(zhí)行時甫恩,它會根據(jù)用戶項目根目錄配置的 .env 文件逆济,自動注入到 this.context.credentials.tencent 上。ServiceType 是當(dāng)前服務(wù)類型磺箕,這是騰訊云 API 定義的奖慌,針對不同業(yè)務(wù)配置相應(yīng)參數(shù)就行。

注意:不同的云服務(wù)商掛到 this.context.credentials 上的屬性也是不一樣松靡,比如這里騰訊云是 tencent简僧,AWS 是 aws,目前支持的所有云服務(wù)商的屬性配置源碼雕欺,在這里可以找到岛马,@serverless/cli

然后請求 新增加速域名 接口:

// cdnInputs 就是我們組裝好的請求參數(shù)
await AddCdnHost(capi, cdnInputs)

這里有個重點:請求 新增加速域名 接口成功返回后,CDN 并不會立即部署成功屠列,這個是需要時間的啦逆,所以我們執(zhí)行后,需要輪訓(xùn)當(dāng)前新增域名的狀態(tài)笛洛,當(dāng)為部署成功時夏志,我們才能進行之后的邏輯。

3.3 組件狀態(tài)保存

Serverless Component 在執(zhí)行 default 函數(shù)時苛让,它會產(chǎn)生一些狀態(tài)沟蔑,比如新增 CDN 域名成功后,會產(chǎn)生一個 hostId狱杰,我們可以保存在 this.state 對象中瘦材,通過執(zhí)行 this.save() 函數(shù),它會將 this.state 保存到項目根目錄的 .serverless 文件夾中一個名為 Template.MyCDN.jsonMyCDN 是我定義的當(dāng)前 Serverless 應(yīng)用的名稱)文件中浦旱,方便之后在做組件建刪除時使用宇色。

3.4 編寫 remove 函數(shù)

Serverless Component 刪除的邏輯,就是再 serverless remove 命令時颁湖,它會讀取 default 函數(shù)執(zhí)行保存到 .serverless 中的狀態(tài)文件,并注入到 this.state 上 , 然后我們可以根據(jù) state 中的值進行移除例隆,比如我這里會用到 host, 因為 刪除加速域名接口 需要傳遞 host 參數(shù)甥捺。

3.5 完善說明文檔

開源項目的 README 一定要寫的清晰明了,方便開發(fā)者順利的使用和開發(fā)镀层。

4. 測試組件

到這里我們組件的基本開發(fā)完成了镰禾,在發(fā)布之前皿曲,還得進行本地測試,Serverless Framework 提供了一個很好地本地調(diào)試方法吴侦,就是應(yīng)用的 serverless.ymlcomponent 可以指定本地項目路徑屋休,比如在 tencent-cdn 目錄下,創(chuàng)建 test 文件夾备韧,然后新增 serverless.yml 配置如下:

MyCDN:
  component: ../
  inputs:
    host: abc.com
    ...

這里的 ../ 就是相對路徑劫樟,因為 tencent-cdn 組件的 serverless.js 文件在 tencent-cdn 根目錄下,之后我們就可以進入 test 目錄织堂,執(zhí)行部署和移除操作叠艳,來測試我們的組件了。

注意:雖然一個 Serverless Component 是一個 npm 模塊易阳,我們可以通過 package.json 中的 main 屬性指定項目中任意的文件入口附较,但是如果沒有 serverless.js 文件,serverless 命令是沒法通過 component 指定的本地路徑調(diào)試的潦俺。

5. 發(fā)布 npm 包

發(fā)布 npm 包拒课,首先需要你擁有一個 npm 賬號,請先前往 npm官網(wǎng) 注冊事示,然后本地執(zhí)行 npm login 登錄你的賬號早像。

經(jīng)過測試沒問題,就可以執(zhí)行 npm publish 就可以發(fā)布到 npm 倉庫了很魂。

源碼

最終實現(xiàn)源碼:@serverless/tencent-cdn扎酷。

組件引用(補充)

每個組件實例,都會有個 load 方法遏匆,我們可以通過此方法來加載其他組件法挨,如下:

const cdnComp = await this.load('@serverless/tencent-cdn', 'cdnComp');

借助此功能,我們可以實現(xiàn)很多高階組件幅聘,比如 @serverless/tencent-website 就是一個很好地案例凡纳。

至于如何組合你的組件,實現(xiàn)自己的需求帝蒿,就靠你自己去天馬行空了荐糜,是不是已經(jīng)躍躍欲試了?快來社區(qū)貢獻你的一份力量吧~

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葛超,一起剝皮案震驚了整個濱河市暴氏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绣张,老刑警劉巖答渔,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侥涵,居然都是意外死亡沼撕,警方通過查閱死者的電腦和手機宋雏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來务豺,“玉大人磨总,你說我怎么就攤上這事×ぃ” “怎么了蚪燕?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長敬拓。 經(jīng)常有香客問我邻薯,道長,這世上最難降的妖魔是什么乘凸? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任厕诡,我火速辦了婚禮,結(jié)果婚禮上营勤,老公的妹妹穿的比我還像新娘灵嫌。我一直安慰自己,他們只是感情好葛作,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布寿羞。 她就那樣靜靜地躺著,像睡著了一般赂蠢。 火紅的嫁衣襯著肌膚如雪绪穆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天虱岂,我揣著相機與錄音玖院,去河邊找鬼。 笑死第岖,一個胖子當(dāng)著我的面吹牛难菌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔑滓,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼郊酒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了燎窘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蹄咖,失蹤者是張志新(化名)和其女友劉穎荠耽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比藻,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡铝量,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了银亲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慢叨。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖务蝠,靈堂內(nèi)的尸體忽然破棺而出拍谐,到底是詐尸還是另有隱情,我是刑警寧澤馏段,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布轩拨,位于F島的核電站,受9級特大地震影響院喜,放射性物質(zhì)發(fā)生泄漏亡蓉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一喷舀、第九天 我趴在偏房一處隱蔽的房頂上張望砍濒。 院中可真熱鬧,春花似錦硫麻、人聲如沸爸邢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杠河。三九已至,卻和暖如春浇辜,著一層夾襖步出監(jiān)牢的瞬間券敌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工奢赂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留陪白,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓膳灶,卻偏偏與公主長得像咱士,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轧钓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351