用現代 js 開發碼良指令碼

arnan發表於2019-11-25

本文為“碼良系統的使用及設計實現”系列文章的第六篇。

用現代 js 開發碼良指令碼

star history 鎮樓

用ES6+寫指令碼

在前面的文章中,我們已經介紹過碼良編輯器強大而靈活的指令碼功能

不知道你有沒有注意到,在編寫指令碼的時候,我們使用到了一些 js 的新特性(相對於 ES5),比如 rest parameters(rest 引數)、shorthand methods(物件方法簡寫)、shorthand properties(物件屬性簡寫)、template string(模板字串)、destructuring parameters(解構引數)、async(非同步)等。

是的,碼良指令碼完全支援您使用 ES6+ 語法和新的 api。而且這並不意味著您需要使用最新的瀏覽器來編寫指令碼,也不要求終端使用者必須使用最新的 webview 來瀏覽嵌入了 ES6+ 指令碼的頁面。

所以,放心大膽的用吧,用現代 js 特性加速你的指令碼開發。

為什麼可以用ES6+寫指令碼

或者說碼良是如何支援 ES6+ 指令碼的?我們先對這個問題進行拆解。

碼良的指令碼機制允許使用者在頁面編輯階段編寫指令碼來修改/控制元件行為,在編輯器中,這些指令碼編寫完成立即得到執行,當頁面釋出以後,指令碼會附加在終端頁面中,在終端頁面載入時得到執行。

如上所述,指令碼出現的場景有編寫指令碼、在編輯器中執行指令碼、以及在客戶端執行指令碼。

根據上述場景,得到如下需求:

場景 需求
編寫指令碼 執行前後,指令碼內容(文字)不變(轉碼需保留原始碼)
編輯器中執行指令碼 相容性,需要將指令碼轉為ES5;指令碼改變,重新轉碼;轉碼效率、頻率;
客戶端中執行指令碼 相容性,需要將指令碼轉為ES5;轉一次即可;指令碼執行效率;

基於如下事實,

  • 指令碼不是一次性的,可以在編輯器中被修改檢視,因此,必然需要保留原始碼。
  • 因相容性,指令碼原始碼在編輯器和終端頁面中需要被轉碼為 ES5 後才能執行
  • 轉碼操作可以在瀏覽器中進行,也可以在服務端進行。
  • 瀏覽器中進行轉碼需要額外載入 babel 相關 js,會有較大的網路開銷,好處是可以隨時(同步)進行轉碼
  • 服務端轉碼操作佔用較多伺服器資源,且帶來額外網路請求的開銷和延遲,不適合頻繁呼叫

我們容易得出這樣一些方案:

方案一 服務端轉碼

場景 方案
編寫指令碼 從伺服器獲取原始碼;儲存原始碼到伺服器;針對原始碼編輯
編輯器中執行指令碼 開發服務端轉碼介面;每次編輯完成呼叫轉碼介面對需要轉碼的指令碼進行轉碼
客戶端中執行指令碼 請求頁面結構資料時在服務端將其中的指令碼進行轉碼,瀏覽器直接執行轉碼後的指令碼

方案二 執行時轉碼

場景 方案
編寫指令碼 從伺服器獲取原始碼;儲存原始碼到伺服器;針對原始碼編輯
編輯器中執行指令碼 新增 babel 庫到編輯器,每次指令碼編輯完成呼叫 babel 在執行時對需要轉碼的指令碼
客戶端中執行指令碼 新增 babel 庫到頁面,獲取到頁面結構資料後,在瀏覽器中對指令碼進行轉碼

以上兩種方案都存在較大缺陷,方案一會增大服務端資源佔用以及編輯器中轉碼網路延遲帶來的不好體驗;方案二在客戶端中引入 babel 執行轉碼帶來了更多的網路開銷,執行時轉碼也會影響指令碼執行效率,另外也不方便對轉碼結果進行快取(如果快取做在客戶端的話,需要設計一個快取更新機制)

為了解決上述方案的缺陷,我們給出了方案三和方案四

方案三 編輯器本地轉碼,儲存原始碼+轉碼後程式碼

場景 方案
編寫指令碼 從伺服器獲取原始碼;儲存原始碼到伺服器;針對原始碼編輯
編輯器中執行指令碼 新增 babel 庫到編輯器,每次指令碼編輯完成呼叫 babel 在執行時對需要轉碼的指令碼進行轉碼;儲存頁面資料時,不僅儲存指令碼原始碼,也儲存轉碼後的程式碼
客戶端中執行指令碼 請求頁面結構資料,瀏覽器直接執行轉碼後的指令碼

方案四 編輯器本地轉碼+終端頁面服務端轉碼,儲存原始碼

場景 方案
編寫指令碼 從伺服器獲取原始碼;儲存原始碼到伺服器;針對原始碼編輯
編輯器中執行指令碼 新增 babel 庫到編輯器,每次指令碼編輯完成呼叫 babel在執行時對需要轉碼的指令碼進行轉碼
客戶端中執行指令碼 請求頁面結構資料時獲取已在服務端進行指令碼轉碼的資料,瀏覽器直接執行轉碼後的指令碼;增加快取機制,對轉碼後的頁面資料在服務端進行快取,頁面更新(重新發布)後清除快取並重新轉碼存入快取

以上兩個方案,編輯器部分都採用了載入 babel 進行執行時轉碼。在編輯器中,對網路開銷不敏感,但是對轉碼效率和頻率有較高要求,因此執行時轉碼比較合適。

方案三和方案四的差別主要在於終端頁面中的指令碼是否需要進行服務端轉碼,方案三直接使用編輯器轉碼結果,同時儲存指令碼原始碼和轉碼後程式碼供終端頁面使用,方案四使用服務端轉碼+快取機制。這兩種方案在伺服器資源佔用上都得到了優化,只需要少量或不需要進行服務端轉碼;在終端頁面載入效率上也得到了優化,無需在執行時進行轉碼,克服了方案一和方案二的缺陷。

當然,最終碼良採用的是方案四,只儲存指令碼原始碼,在寫入服務端快取時,將指令碼原始碼內容直接換成了轉碼程式碼,保持了頁面資料結構的統一,實現了同一個詳情介面在不同場景下返回包含不同格式指令碼的頁面資料。

最後

文章沒有給出方案的具體實現,實現上也並不複雜,有興趣的可以看看程式碼,這裡只是記錄了做這個方案時經歷的一些思考和權衡,或許能給到您些許啟發。

例行求體驗,例行求 star

相關文章