最近在開(kāi)發(fā)一款一鍵登錄的號(hào)碼認(rèn)證js-sdk
,所以就做了一些調(diào)研,記錄下開(kāi)發(fā)過(guò)程。
前端SDK是什么?前端SDK是為了幫助前端實(shí)現(xiàn)特定需求,而向開(kāi)發(fā)者暴露的一些JS-API的集合,規(guī)范的SDK包括若干API實(shí)現(xiàn)、說(shuō)明文檔等
前端SDK其實(shí)很常見(jiàn)了,比如:
UI組件庫(kù):通過(guò)封裝一系列組件,通過(guò)配置幫助開(kāi)發(fā)者調(diào)用
Antd
ElementUI
JS類庫(kù):通過(guò)實(shí)現(xiàn)一類常用的方法,便于開(kāi)發(fā)處理數(shù)據(jù),也不用再考慮兼容性
lodash
moment
監(jiān)控統(tǒng)計(jì)工具:通過(guò)API,來(lái)監(jiān)聽(tīng)前端系統(tǒng)的報(bào)錯(cuò)、統(tǒng)計(jì)數(shù)據(jù)
Sentry
百度統(tǒng)計(jì)等
SDK開(kāi)發(fā)其實(shí)很簡(jiǎn)單,簡(jiǎn)單到寫(xiě)一個(gè)函數(shù)導(dǎo)出就行,但在實(shí)際應(yīng)用的過(guò)程中,我們要考慮很多實(shí)際情況。
SDK一般都是為了滿足一類業(yè)務(wù)的需要,所以設(shè)計(jì)之初要明確業(yè)務(wù)范圍
即能用確定的方法實(shí)現(xiàn),就不要再去搞復(fù)雜的內(nèi)容。我理解,比如獲取DOM,如果GetElementById
可以實(shí)現(xiàn),就不要再設(shè)計(jì)一下GetElementsByTagName
、 document.querySelector
等方法封裝,除非有其他的開(kāi)發(fā)需要無(wú)法滿足。
SDK減少依賴,要避免Lodash、JQuery、Moment、Dayjs等庫(kù),盡可能自行實(shí)現(xiàn)必要的方法,或者引入盡量小的庫(kù)。否則會(huì)導(dǎo)致SDK打包后過(guò)大,或者更新版本帶來(lái)的兼容問(wèn)題
當(dāng)然一切都要根據(jù)實(shí)際情況,有些SDK是時(shí)間的各種處理,自己處理時(shí)間的成本太高,不妨引入小型的Dayjs時(shí)間庫(kù)
減少BreakChange,絕不能導(dǎo)致載體應(yīng)用崩潰,同時(shí)做好文檔說(shuō)明
模塊化實(shí)現(xiàn)方法,盡量小的封裝函數(shù),保持函數(shù)功能的單一性原則,這樣就可以更好的增加SDK的能力。
根據(jù)這些原則,下面是我們做的對(duì)應(yīng)操作:
首先要明確我們寫(xiě)的SDK是用來(lái)做什么的?
比如我本次實(shí)現(xiàn)的是用戶H5頁(yè)面的一鍵登錄和號(hào)碼檢測(cè)。
那么我們需要暴露兩個(gè)實(shí)例,供其他開(kāi)發(fā)者使用,為了滿足易擴(kuò)展的原則,我們將聲明兩個(gè)類,來(lái)實(shí)現(xiàn)(如果每個(gè)實(shí)例都很多能力,可以拆分成兩個(gè)SDK也是可以的)
提供的SDK一般都要提供壓縮和未壓縮版本,未壓縮可以用來(lái)幫助開(kāi)發(fā)調(diào)用,查找問(wèn)題。壓縮版本可以使用在生產(chǎn)環(huán)境,減少http損耗。所以我們要借助構(gòu)建工具來(lái)集成這部分的能力。
可供選擇的壓縮工具有很多:webpack、Rollup、Gulp
如果是純類庫(kù)的壓縮,當(dāng)然是Rollup更好,壓縮更徹底
如果是有DOM和樣式,那么使用webpack功能更強(qiáng)大
這里由于我們可能涉及到頁(yè)面SDK,而且對(duì)Webpack更熟悉,所以選擇Webpack
SDK的設(shè)計(jì)原則有一條:足夠穩(wěn)定、向后兼容,最少依賴原則。
這就意味著我們要少寫(xiě)B(tài)ug,所以一定要引入單元測(cè)試,這里我們選擇Jest,使用起來(lái)也很簡(jiǎn)單。
describe('common test', () => { test('osIsPc', () => { expect(osIsPc()).toBeBoolean(true, false); }) test("isWifi", () => { expect(isWifi()).toBeBoolean(true, false); }) }) 復(fù)制代碼
瀏覽器js模塊化常見(jiàn)的幾種方式包括:amd\cmd\es6 modules\umd
1、靜態(tài)資源引入
<script src="/sdk/v1/phoneserver"></script> 復(fù)制代碼
2、支持amd引入
define([jquery.js, lodash.js], function($, _){ console.log("jquery and lodash", $, _) }) 復(fù)制代碼
3、支持cmd引入
define(function(require){ const lodash = require('./a.js') console.log("lodash", lodash) }) 復(fù)制代碼
4、支持es6引入
import { PhoneServer } from 'phone-server-sdk' 復(fù)制代碼
我們直接在webpack中配置umd方式打包,然后就可以支持上面的多種引入方式
output: { path: path.resolve(__dirname, '../dist'), filename: '[name].js', library: 'Phone-JS-SDK', libraryTarget: 'umd' } 復(fù)制代碼
打包的庫(kù)命名:Phone-JS-SDK
管理好版本號(hào)
記錄好更新日志
SDK版本更新,每個(gè)版本都會(huì)存在差異,而用戶使用的版本肯定也太一樣,所以記錄好版本更新日志可以減少非技術(shù)問(wèn)題。
通過(guò)靜態(tài)文件導(dǎo)出的SDK要同時(shí)部署多個(gè)版本,不能隨時(shí)下線老版本。
代碼混淆
開(kāi)發(fā)環(huán)境配置和代碼格式
上傳NPM
CDN部署
依賴的三方庫(kù)如何打包進(jìn)SDK
僅支持靜態(tài)引入的庫(kù)如何處理
如何全局共享庫(kù)方法
針對(duì)有后端API交互的SDK,需要考慮
API要限流、限制次數(shù)、防止盜刷
日志監(jiān)控和數(shù)據(jù)上報(bào)
針對(duì)提交代碼的檢測(cè)和格式化,這里直接配置好了,如果需要了解,可以查看我之前的一篇文章前端工程化:Prettier+ESLint+lint-staged+commitlint+Hooks+CI 自動(dòng)化配置處理
構(gòu)建工具構(gòu)建,配置開(kāi)發(fā)環(huán)境、ts配置
實(shí)現(xiàn)類庫(kù)的相關(guān)方法(版本記錄、幫助命令等)
實(shí)現(xiàn)一鍵登錄的方法(預(yù)期的功能方法)
實(shí)現(xiàn)號(hào)碼檢測(cè)的方法
單元測(cè)試
上傳npm,支持導(dǎo)入
我們選擇了ts,首先配置下tsconfig.json,然后配置webpack,引入ts-lodader,通過(guò)webpack-merge自行配置生產(chǎn)環(huán)境和開(kāi)發(fā)環(huán)境,比較簡(jiǎn)單就不重復(fù)了
module.exports = { entry: { sdk: [path.resolve(__dirname, '../src/index.ts')] }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, output: { path: path.resolve(__dirname, '../dist'), filename: '[name].js', library: 'SDK', libraryTarget: 'umd' }, module: { rules: [ { test: /\.ts?$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, { loader: 'ts-loader', options: { compilerOptions: { noEmit: false, }, }, }, ], }, ] } 復(fù)制代碼
下面是項(xiàng)目的主要目錄結(jié)構(gòu)
src源代碼
scripts 是webpack的相關(guān)配置
public 是用來(lái)調(diào)試和打包的目錄
tests 單元測(cè)試
LibInfo.ts 用來(lái)實(shí)現(xiàn)庫(kù)的一些方法,比如獲取版本號(hào),幫助文檔,展示依賴版本等
PhoneNumberLogin.ts 一鍵登錄類
PhoneNumberAuth.ts 號(hào)碼認(rèn)證類
ajax.ts 簡(jiǎn)單封裝的ajax請(qǐng)求
index.ts 作為入口文件
js-sdk ├─ __tests__ │ └─ utils │ ├─ ajax.test.js │ └─ commont.test.js ├─ public │ ├─ index.html │ └─ sdk.js ├─ scripts │ ├─ webpack.base.config.js │ ├─ webpack.dev.config.js │ └─ webpack.prod.config.js ├─ src │ ├─ lib │ │ ├─ LibInfo.ts │ │ ├─ PhoneNumberAuth.ts │ │ ├─ PhoneNumberLogin.ts │ │ └─ Init.ts │ ├─ utils │ │ ├─ ajax.ts │ │ ├─ common.ts │ │ └─ interface.ts │ └─ index.ts ├─ Readme.md ├─ index.d.ts ├─ jest.config.js ├─ package.json ├─ tsconfig.json └─ yarn.lock 復(fù)制代碼
1、在調(diào)用之前,我們需要引用第三方庫(kù),而且是md5加密的(如下),無(wú)法直接下載本地使用,所以考慮直接插入head中
export const scriptInit = (src: string, callback?: Function) => { const script:any = document.createElement('script'), fn = callback || function(){}; script.type = 'text/javascript'; //IE if(script.readyState){ script.onreadystatechange = function(){ if( script.readyState == 'loaded' || script.readyState == 'complete' ){ script.onreadystatechange = null; fn(); } }; }else{ //其他瀏覽器 script.onload = function(){ fn(); }; } script.src = src; document.getElementsByTagName('head')[0].appendChild(script); } 復(fù)制代碼
2、我們以實(shí)現(xiàn)意見(jiàn)登錄號(hào)碼為例,新建PhoneNumberLogin.ts
const loginPhoneUrl = `http://test.com` export class PhoneNumberLogin { constructor(options:AppInfo){ this.Init() } private Init(){ // 引入第三方依賴的script scriptInit(loginPhoneUrl) } // 處理一鍵登錄的接口邏輯 public LoginApp(options){ return options } } 復(fù)制代碼
這樣我們每一個(gè)小的功能點(diǎn)都放在一個(gè)類中,不對(duì)外的設(shè)置為私有方法,對(duì)外的可以設(shè)置為公共方法,其他的通過(guò)引用就可以讓SDK保持良好的可擴(kuò)展性。
3、在index.ts中拋出方法
export * from './lib/PhoneNumberLogin.ts' 復(fù)制代碼
4、在項(xiàng)目中使用
script
導(dǎo)入,一般都需要申請(qǐng)域名,那么就需要考慮容災(zāi),防止一臺(tái)機(jī)器掛掉,服務(wù)不可用,一般考慮CDN部署
const { PhoneNumberLogin } = Phone-JS-SDK const PhoneServer = new PhoneNumberLogin() 復(fù)制代碼
ES6 Modules導(dǎo)入
const { PhoneNumberLogin } from "Phone-JS-SDK" const PhoneServer = new PhoneNumberLogin() 復(fù)制代碼
接著我們發(fā)布下npm,一個(gè)JS-SDK就完成了。
登陸npm倉(cāng)庫(kù),沒(méi)有的話去注冊(cè)一個(gè),地址
npm login 復(fù)制代碼
選擇一個(gè)中意的SDK名字,查一下是否存在,這里我們起個(gè)名字Phone-JS-SDK
執(zhí)行
npm version patch && npm publish --registry=https://registry.npmjs.org
,然后就發(fā)布成功了。
作者:前端中后臺(tái)
鏈接:https://juejin.cn/post/7111880557914488846
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/127966.html
摘要:未使用微信如果網(wǎng)頁(yè)中未使用微信用戶在微信中打開(kāi)網(wǎng)站可能會(huì)觸發(fā)這個(gè)錯(cuò)誤,目前看來(lái)只有忽略。關(guān)于微信支付方法監(jiān)聽(tīng)事件之后再進(jìn)行下一步操作方法直接使用文檔中的支付代碼,不要使用公眾號(hào)支付文檔里面的代碼。 Fundebug并沒(méi)有使用微信JS-SDK,然而卻收到了WeixinJSBridge is not defined的報(bào)錯(cuò): showImg(https://segmentfault.com...
摘要:進(jìn)過(guò)下面的步驟,一步一步的配置,就可以讓你正確的在項(xiàng)目中引入微信的。在進(jìn)行了正確的微信文件引入后看上面在頁(yè)面中調(diào)用如下代碼就可以注入權(quán)限驗(yàn)證配置??梢酝ㄟ^(guò)微信提供的兩個(gè)接口來(lái)進(jìn)行事件回調(diào)。到這為止,微信的接入就完成了。 微信JS-SDK的功能 如果你點(diǎn)進(jìn)來(lái),那么我相信你應(yīng)該知道微信的JS-SDK可以用來(lái)做什么了。微信的官方文檔描述如下。 微信JS-SDK是微信公眾平臺(tái)面向網(wǎng)頁(yè)開(kāi)發(fā)者提供...
摘要:安裝并引入依賴包這里是說(shuō)明文檔下載依賴包在需要用到的模塊引入檢查是否引入成功可以在引入的模塊中執(zhí)行控制臺(tái)顯示以上代碼表示引入成功配置微信所有需要使用的頁(yè)面必須先注入配置信息,否則將無(wú)法調(diào)用開(kāi)啟調(diào)試模式調(diào)用的所有的返回值會(huì) 1.安裝并引入JS-SDK依賴包 這里是JS-SDK說(shuō)明文檔 1.1 npm 下載依賴包 npm install weixin-js-sdk --save 1.2.在...
摘要:注冊(cè)測(cè)試號(hào)注冊(cè)的地址在這里要進(jìn)行微信公眾號(hào)的開(kāi)發(fā),那就需要一個(gè)本地的開(kāi)發(fā)環(huán)境來(lái)進(jìn)行開(kāi)發(fā)。而微信測(cè)試號(hào)就正好提供了這樣的一個(gè)環(huán)境。通俗一點(diǎn)理解微信要知道訪問(wèn)它資源是不是這個(gè)當(dāng)前測(cè)試號(hào)。 注冊(cè)測(cè)試號(hào) 注冊(cè)的地址在 這里 要進(jìn)行微信公眾號(hào)的開(kāi)發(fā),那就需要一個(gè)本地的開(kāi)發(fā)環(huán)境來(lái)進(jìn)行開(kāi)發(fā)。而微信測(cè)試號(hào)就正好提供了這樣的一個(gè)development環(huán)境。每個(gè)微信號(hào)只能對(duì)應(yīng)一個(gè)測(cè)試號(hào),但是每個(gè)測(cè)試號(hào)可以...
摘要:前端配置微信微信是微信公眾平臺(tái)面向網(wǎng)頁(yè)開(kāi)發(fā)者提供的基于微信的網(wǎng)頁(yè)開(kāi)發(fā)工具包,通過(guò)使用微信,網(wǎng)頁(yè)開(kāi)發(fā)者,可借助微信高效的使用拍照掃碼錄音定位等原生應(yīng)用愛(ài)具有的能力。 前端配置微信 js-sdk 微信js-sdk 是微信公眾平臺(tái)面向網(wǎng)頁(yè)開(kāi)發(fā)者提供的基于微信的網(wǎng)頁(yè)開(kāi)發(fā)工具包,通過(guò)使用微信 js-sdk,網(wǎng)頁(yè)開(kāi)發(fā)者,可借助微信高效的使用 拍照、掃碼、錄音、定位等原生應(yīng)用愛(ài)具有的能力。 前端開(kāi)發(fā)...
摘要:這段時(shí)間做了一個(gè)微信服務(wù)號(hào)的開(kāi)發(fā)初版設(shè)計(jì)圖如下這個(gè)方式前面幾個(gè)步驟都沒(méi)有問(wèn)題關(guān)鍵在于后面第六步重定向到頁(yè)面之所以這么做是考慮到了我們前端的框架需要對(duì)入口作統(tǒng)一的處理操作這樣在機(jī)子上沒(méi)有任何問(wèn)題但是在上面經(jīng)常出現(xiàn)的認(rèn)證失敗而且不是必現(xiàn)是偶爾 這段時(shí)間做了一個(gè)微信服務(wù)號(hào)的開(kāi)發(fā)初版設(shè)計(jì)圖如下:showImg(https://segmentfault.com/img/bV7EHR?w=690&...
閱讀 1573·2025-02-07 13:29
閱讀 1003·2024-11-07 18:25
閱讀 131496·2024-02-01 10:43
閱讀 1336·2024-01-31 14:58
閱讀 1144·2024-01-31 14:54
閱讀 83571·2024-01-29 17:11
閱讀 3870·2024-01-25 14:55
閱讀 2390·2023-06-02 13:36