雲計算

如何打造一款標準的JS-SDK

0 前言

本文主要介紹如何基於JavaScript來開發SDK,任何基於JS的場景都可以用類似的思路來解決,無論是移動端H5還是服務端純NodeJS。文中會提及一些設計原則以及實現技巧,並結合 嶽鷹全景監控平臺SDK 這個實際案例來展示如何應用它們。

1 SDK是什麼

SDK全稱是“Software Development Kit”,直譯就是軟件開發工具集。說的再通俗點就是一個面向開發者,針對特定領域的軟件包。比如 Java SDK(JDK),就是一個Java領域的軟件包。基於它,開發人員就可以快速構建自己的Java應用。比較規範的SDK一般都會包含若干的API、開發工具集和說明文檔。

JS-SDK也無外於此,不過鑑於JS語言本身的特性,基於Ta封裝的SDK更多常見於UI組件庫、統計分析、web服務接口封裝、前端穩定性和性能監控等場景。上一小節提到的 嶽鷹全景監控平臺SDK 即屬於前端穩定性和性能監控這一領域範疇的SDK。

2 設計原則

如何設計SDK,其實更多取決於你的場景,或者SDK最終的用途。比如實現一個給網頁調用的SDK與用於服務端的SDK就有明顯的差異,但這之間確實存在著一些共通的原則,或者方法論:

  • 最小可用性原則,即用最少的代碼,如無必要勿增實體
  • 最少依賴原則,即最低限度的外部依賴,如無必要勿增依賴

進一步闡述,即我們打造的SDK要符合以下的要求

2.1 滿足功能需求

SDK一般都是偏於面向某個領域,所以,同時在設計和實現的時候明確職責和邊界很重要,同時還應該足夠精簡,專注領域內的業務。

2.2 足夠穩定

  • 絕不能導致宿主應用崩潰,這是最基礎也是最嚴格的要求
  • 較好的性能,比如SDK體積應儘量小,運行速度儘量快
  • 可測試,保障每一次變更
  • 向後兼容,不輕易出現 Breakchange

2.3 少依賴,易擴展

  • 最小程度的第三方依賴,儘可能自行實現,確實無法避免則最小化引入
  • 插件化,最大限度支持擴展
  • Hook機制,滿足個性化訴求

3 如何實現

下面我們將通過剖析 嶽鷹前端監控SDK 的設計過程,來看看上述的設計原則是如何應用到實際的開發過程中的。

3.1 明職責,定邊界

前面章節提到, 嶽鷹前端監控SDK 是前端穩定性和性能監控的SDK,主要面向前端H5領域。因此,稍加分析即可得出以下結論

  • 前端領域,穩定性方面主要的關注點

    • JS異常
    • 資源加載異常
    • API請求異常
    • 白屏異常
  • 性能方面,核心的關注點

    • 白屏時間
    • 可交互時間(TTI)
    • 首屏時間
    • FP / FMP / FCP 等

上述監控內容實際上都相對獨立,因此我們可以把Ta們橫向劃分為如下幾大部分:

明確了SDK的邊界以及各部分的職責,結合前端監控的特性,我們可以開始設計SDK的整體框架了。

3.2 築框架,夯基礎

俗話說千里之行始於足下,因此築牢基礎十分重要。總得來說,我們需要做好下面幾點

  • 首先確定SDK的引用形式
    SDK整體而言是一個大模塊,前端模塊有多種表現形式:ES Module、CommonJS、AMD/CMD/UMD,而在引用方面則大體分 CDN和 NPM兩種。即無論我們實現的是哪種形式的模塊,最終都是通過CDN或者NPM的方式提供給用戶引用。
import wpkReporter from 'wpkReporter'

// CommonJS
const wpkReporter = require('wpkReporter')

// AMD,requireJS引用
require.config({
  paths: {
    "wpk": "https://g.alicdn.com/woodpeckerx/jssdk/wpkReporter.js",
  }
})
require(['wpk', 'test'], function (wpk) {
  // do your business
})

乍看有點眼花,但事實上今時今日的前端工程領域,已有很多利器可以幫助我們達到目的。比如 webpack,通過簡單的配置就可以構建出一個UMD的bundle。

module.exports = {
  output: {
    filename: '[name].js',
    path: `${__dirname}/dist`,
    globalObject: 'this',
    library: '[name]',
    libraryTarget: 'umd'
  }
} 

綜上,我們可以通過 webpack將 SDK構建為一個UMD bundle,這樣可以自動適配所有形式的模塊。同時我們也將同時提供 CDN和 NPM兩種引用方式,給用戶更多選擇。

  • 確定SDK的版本管理機制
    現有較成熟的版本管理機制當屬 語義化版本號 ,表現形式為 {主版本}.{次版本}.{補丁版本},簡單易記好管理。

一般重大的變更才會觸發主版本號的更替,而且很可能新舊版本不兼容。次版本主要對應新特性或者較大的調整,因此也有可能出現breakchange。其他小的優化或bugfix就基本都是在補丁版本號體現。
看到此處,是否有點似曾相識的感覺?沒錯,所有NPM模塊都遵循語義化版本規範,因此結合第一點,我們可以將SDK初始化為一個NPM模塊,結合webpack的能力就可以實現基礎的版本管理及模塊構建。

  • 確定SDK的基礎接口
    接口是SDK和用戶溝通的橋樑,每一個接口對應著一個獨立的SDK功能,並且有明確的輸入和輸出。我們可以先來看看嶽鷹前端監控SDK的核心接口有哪些?
wpk.report(logData)
wpk.reportJSError(error)
wpk.reportAPIError(apiData)
// 配置變更
wpk.setConfig(data)
// SDK診斷
wpk.diagnose()
// 添加插件
wpk.addPlugin(plugin)

總結接口的設計原則,如下

  • 職責單一
    一個接口只做一件事情
  • 命名簡單清晰,參數儘量少但可擴展
    好的接口命名就是最好的註釋,一看即明其用處

參數儘可能適用 Object封裝

  • 做好參數校驗和邏輯保護

3.3 領域分析,模塊劃分

定邊界的時候,我們已經清楚劃分了SDK的幾個關鍵的部分:全局異常、API異常、頁面性能和白屏,實際上監控SDK通常也會內置對頁面流量的監控,以方便用戶對異常的影響面做出評估。這幾個核心的關鍵組成部分,每一塊都對應一個專業的領域,因此對應到SDK也是每一個獨立的模塊。
除了這些核心的偏領域的模塊,SDK還需要有更基礎的與領域無關的模塊,包括SDK內核(構造方法、插件機制、與下游服務的交互、上報隊列機制、不同環境的管理等等)和工具類庫。
我們可以先看一下嶽鷹前端監控SDK最後的整體模塊劃分:

  • SDK底層提供基礎的能力,包括上面提到的內核、插件機制的實現、工具類庫以及暴露給用戶的基礎API
  • 可以看到,我們前面提到的所有模塊都以插件的形式存在,即各領域的功能都各自鬆散的做實現,這樣使得底層能力更具通用性,同時擴展能力也更強,用戶甚至也可以封裝自己的插件。
  • Biz部分更多是對於不同宿主環境的多入口適配,當前支持瀏覽器、Weex以及NodeJS。

3.4 測試覆蓋,線上無憂

SDK是一個基礎服務,相對於前臺業務而言可能更底層些。其影響面跟應用的範圍是正比的關係,更多的用戶意味著更大的責任。所以SDK的質量保障也是很重要的一個環節。
嶽鷹前端監控SDK的質量保障策略很簡單,只有兩條

  • 核心接口100%的單元測試覆蓋率
  • 發佈卡點:再小的版本發佈也需要走集成測試迴歸

事實上,除了核心接口,工具類庫的所有功能我們都實現了 100%的單元測試覆蓋,我們採用的前端測試工具是輕量好用的 Jest 。

test('isError: real error', function () {
  var err = new Error('this is an error')
  expect(util.isError(err)).toBeTruthy()
})

3.5 細節打磨,極致體驗

  • 快捷引入

    • 極盡所能提高用戶引用的效率
    • 一行代碼,快速引入,享用監控全家桶功能
<script>
  !(function(c,i,e,b){var h=i.createElement("script");var f=i.getElementsByTagName("script")[0];h.type="text/javascript";h.crossorigin=true;h.onload=function(){c[b]||(c[b]=new c.wpkReporter({bid:"dta_1_203933078"}));c[b].installAll()};f.parentNode.insertBefore(h,f);h.src=e})(window,document,"https://g.alicdn.com/woodpeckerx/jssdk/wpkReporter.js","__wpk");
</script>
  • 動態採樣

    • 即通過雲端下發數據採樣率的方式,控制客戶端上報數據的頻率
    • 更好的保護監控下游
  • 自我診斷

    • 除了接口,SDK整體對用戶而言就是一個黑盒,因此用戶在遇到問題時很容易蒙圈 (如:為啥沒有上報數據)
    • SDK可以提供一個自我診斷的接口,快速排除基礎問題

      • 比如,SDK是否已正常初始化、關鍵參數是否正常設置等
  • 增加調試模式,輸出更詳細的過程日誌,方便定位問題
  • 漸進式的指引文檔

    • 圖文並茂,循序漸進
    • 入門,一步步引導用戶初識SDK,領略概貌,學會基本的使用
    • 進階,安利SDK的深度用法,幫助用戶更好的使用SDK

4 結語

實際在SDK的設計和開發過程中,要處理的問題還遠不止本文所述的內容,比如 NPM模塊開發時本地如何引用,構建的bundle大小如何調優等等。不過還是希望閱完此文,對你有所啟發。同時文中若有不對之處,還望不吝賜教。

訪問嶽鷹全景監控平臺

Leave a Reply

Your email address will not be published. Required fields are marked *