前端: 如何快速將應用封裝成js-sdk?

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文將介紹","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"前端","attrs":{}},{"type":"text","text":"如何封裝一款 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 以及如何快速將你的應用變成 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" , 我們將總結一些封裝 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 的原則和案例, 來幫大家更快的上手 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 開發. 其中筆者還會以","attrs":{}},{"type":"link","attrs":{"href":"https://link.zhihu.com/?target=https%3A//github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"H5-Dooring","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 爲例子, 介紹如何將 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"H5 頁面編輯器","attrs":{}},{"type":"text","text":"封裝成一個 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 供他人使用.","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3c/3cf6db5b9732ff7d09650e48fa9ff5c5.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"正文","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在開始文章之前, 筆者先來介紹一下什麼是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 而言, 我們能舉出很多例子, 如下:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UI組件庫","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"性能監控工具, 如阿里 arms","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"統計分析工具","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"阿里雲智能驗證sdk","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"極驗驗證sdk","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 的目的是提高我們開發項目的效能, 安全性和便捷性等問題, 所以我們在設計 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 時一定要遵循一些原則, 如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f0/f0e4744c91231a7960e1717559fa242c.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"最小可用性原則","attrs":{}},{"type":"text","text":": 也就是沒有必要的功能/代碼儘量不額外添加, 使代碼達到最簡","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"最少依賴原則","attrs":{}},{"type":"text","text":": 也就是沒有必要的依賴堅決不添加, 以達到最低限度的外部依賴","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"易擴展","attrs":{}},{"type":"text","text":": 插件化,最大限度支持擴展和自定義","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"穩定性","attrs":{}},{"type":"text","text":": 絕不能導致宿主應用崩潰,向後兼容, 可測試","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在熟悉以上的背景和原則之後, 我們來看看如何實現一個 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 的案例.","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"將 H5-Dooring 封裝成一個 js-sdk","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者在這拿 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"開源頁面製作工具","attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"link","attrs":{"href":"https://link.zhihu.com/?target=https%3A//github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"H5-Dooring","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":" 來作爲案例(當然將其封裝成 sdk 也是我們迭代中的一部分, 甚至後期會做成npm包), 介紹如何封裝js-sdk, 我們先看一張抽象圖:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7e/7e11161f6722937b70fc03df44a9c9b0.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們的 sdk 就好像一個完整系統的一個零件, 可以和系統中的其他模塊通信, 互相交換數據. 總體而言 sdk 是爲宿主系統服務的, 在 dooring-sdk 中 我們一方面要提供對外的接口支持, 另一方面需要支持宿主能控制 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"H5 編輯器","attrs":{}},{"type":"text","text":"的界面, 所以綜合分析下來我們有如下的初步規劃圖:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/85/856e8bac16c840ef858b444edf49926d.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先我們 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 採用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js","attrs":{}}],"attrs":{}},{"type":"text","text":" 動態加載 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iframe","attrs":{}}],"attrs":{}},{"type":"text","text":" 的模式來實現, 並通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iframe","attrs":{}}],"attrs":{}},{"type":"text","text":" 通信來實現","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"props","attrs":{}}],"attrs":{}},{"type":"text","text":" 傳遞, 此時可以有兩種比較靠譜的通信方案:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"postmessage","attrs":{}}],"attrs":{}},{"type":"text","text":" 實現跨域跨系統通信","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"url","attrs":{}}],"attrs":{}},{"type":"text","text":" 參數通信","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"postmessage","attrs":{}}],"attrs":{}},{"type":"text","text":" 對宿主系統要求比較高, 需要宿主手動配置 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"origin","attrs":{}}],"attrs":{}},{"type":"text","text":" 白名單, 對可插拔式體驗不夠友好, 所以筆者這裏採用了比較常用的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"url","attrs":{}}],"attrs":{}},{"type":"text","text":" 通行方式, 這裏需要對參數做解析, 最後達到一個比較簡單的接入方式, 如下:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var dooringOpts = {\n container: '', // 掛載到哪個dom節點上\n iframeStyle: { // iframe自定義樣式\n width: '',\n height: '',\n border: ''\n },\n controls: {\n gallery: false, // 是否啓動圖片庫\n template: false, // 是否啓用模版庫\n saveTemplate: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n save: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n downCode: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n isPhoneTest: false,\n helpPage: true, // false/true表示隱藏/顯示幫助頁面\n uploadApi: '', // 自定義上傳api\n formApi: '', // 自定義表單提交api\n screenshotsApi: '' // 自定義截圖提交api\n }\n};\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶只需要在全局定義好配置的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"props","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"callback","attrs":{}}],"attrs":{}},{"type":"text","text":" , 即可自由定製 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"H5-Dooring","attrs":{}}],"attrs":{}},{"type":"text","text":". 接下來我們只需要再引入 dooring-sdk即可(注意先定義全局變量, 再引入sdk):","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上只是確定了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"js-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方案和最終調用效果, 接下來我們來看看如何去實現它. 也就是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dooring-sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 內部到底做了那些工作. 我們先看一張實現機制圖:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/48/4800cda3c9a8c6b3eb05108563bba5c1.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由上圖分析可知我們需要提前把用戶定義的全局配置解析成 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"url","attrs":{}}],"attrs":{}},{"type":"text","text":" 參數, 然後將動態創建的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iframe","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"src","attrs":{}}],"attrs":{}},{"type":"text","text":" 屬性設置爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dooring url","attrs":{}}],"attrs":{}},{"type":"text","text":" + ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"parmas","attrs":{}}],"attrs":{}},{"type":"text","text":"的結構, 具體實現如下:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"(function(){\n let iframe = document.createElement('iframe');\n let tid = Date.now();\n let sdk_domain_path = 'http://xxxx/xxxx';\n iframe.src = sdk_domain_path + '/h5_plus/editor?tid=' + tid + '&' + getDooringApiStr(dooringOpts) + '&isOpen=1';\n\n iframe.style.border = 'none';\n iframe.style.width = '100vw';\n iframe.style.height = '100vh';\n if(dooringOpts && dooringOpts.iframeStyle) {\n iframe.style.border = dooringOpts.iframeStyle.border || 'none';\n iframe.style.width = dooringOpts.iframeStyle.width || '100vw';\n iframe.style.height = dooringOpts.iframeStyle.height || '100vh';\n }\n\n document.querySelector(dooringOpts.container || 'body').appendChild(iframe);\n\n function getDooringApiStr(opt) {\n let controls = Object.assign({\n gallery: false,\n template: false,\n saveTemplate: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n save: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n downCode: true, // 參數可以是true/false,表示是否啓動下載代碼, 也可以是函數, 用來自定義下載代碼邏輯\n isPhoneTest: false,\n helpPage: true, // false/true表示隱藏/顯示幫助頁面\n uploadApi: '',\n formApi: '',\n screenshotsApi: ''\n }, opt.controls || {})\n\n let params = '';\n for(let key in controls) {\n params += key + '=' + encodeURI(controls[key]) + '&'\n }\n return params.slice(0, params.length -1)\n }\n})()\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上只是個簡單的實現實現思路, 是不是有點傳統的寫jquery插件的感覺? 同時我們還需要配合 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"h5-dooring","attrs":{}}],"attrs":{}},{"type":"text","text":" 內部去支持解析 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"parmas","attrs":{}}],"attrs":{}},{"type":"text","text":" 等操作, 這裏感興趣的可以自行研究. 當然 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"sdk","attrs":{}}],"attrs":{}},{"type":"text","text":" 的實現方式還有很多, 期待大家的探索.","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最後","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上方案筆者已經集成到 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"H5-Dooring","attrs":{}},{"type":"text","text":" 中,大家可以以 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"sdk","attrs":{}},{"type":"text","text":" 的方式體驗一下。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"github 地址:","attrs":{}},{"type":"link","attrs":{"href":"https://link.zhihu.com/?target=https%3A//github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"所見即所得的H5頁面編輯器H5-Dooring","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章