1. 程式人生 > >Mpvue小程式的最新規範

Mpvue小程式的最新規範

mpvue 是一款使用 Vue.js 開發微信小程式的前端框架。使用此框架,開發者將得到完整的 Vue.js 開發體驗,同時為 H5 和小程式提供了程式碼複用的能力。如果想將 H5 專案改造為小程式,或開發小程式後希望將其轉換為 H5,mpvue 將是十分契合的一種解決方案。

目前, mpvue 已經在美團點評多個實際業務專案中得到了驗證,因此我們決定將其開源,希望更多技術同行一起開發,應用到更廣泛的場景裡去。專案的地址在:

github.com/Meituan-Dia…

為了幫助大家更好的理解 mpvue 的架構,接下來我們來解析框架的設計和實現思路。文中主要內容已經發表在《程式設計師》雜誌2017年第9期小程式專題封面報道,內容略有修改。

小程式開發特點

微信小程式推薦簡潔的開發方式,通過多頁面聚合完成輕量的產品功能。小程式以離線包方式下載到本地,通過微信客戶端載入和啟動,開發規範簡潔,技術封裝徹底,自成開發體系,有 Native 和 H5 的影子,但又絕不雷同。

小程式本身定位為一個簡單的邏輯檢視層框架,官方並不推薦用來開發複雜應用,但業務需求卻難以做到精簡。複雜的應用對開發方式有較高的要求,如元件和模組化、自動構建和整合、程式碼複用和開發效率等,但小程式開發規範較大的限制了這部分能力。為了解決上述問題,提供更好的開發體驗,我們創造了 mpvue,通過使用 Vue.js 來開發微信小程式。

mpvue是什麼?

mpvue 是一套定位於開發小程式的前端開發框架,其核心目標是提高開發效率,增強開發體驗。使用該框架,開發者只需初步瞭解小程式開發規範、熟悉 Vue.js 基本語法即可上手。框架提供了完整的 Vue.js 開發體驗,開發者編寫 Vue.js 程式碼,mpvue 將其解析轉換為小程式並確保其正確執行。此外,框架還通過 vue-cli 工具向開發者提供 quick start 示例程式碼,開發者只需執行一條簡單命令,即可獲得可執行的專案。

為什麼做mpvue?

在小程式內測之初,我們計劃快速迭代出一款對標 H5 的產品實現,核心訴求是:快速實現、程式碼複用、低成本和高效率… 隨後經歷了多個小程式建設,結合業務場景、技術選型和小程式開發方式,我們整理彙總出了開發階段面臨的主要問題:

元件化機制不夠完善

程式碼多端複用能力欠缺

小程式框架和團隊技術棧無法有機結合

小程式學習成本不夠低

元件機制:小程式邏輯和檢視層程式碼彼此分離,公共元件提取後無法聚合為單檔案入口,元件需分別在檢視層和邏輯層引入,維護性差;元件無名稱空間機制,事件回撥必須設定為全域性函式,元件設計有命名衝突的風險,資料封裝不強。開發者需要友好的程式碼組織方式,通過 ES 模組一次性匯入;元件資料有良好的封裝。成熟的元件機制,對工程化開發至關重要。

多端複用:常見的業務場景有兩類,通過已有 H5 產品改造為小程式應用或反之。從效率角度出發,開發者希望通過複用程式碼完成開發,但小程式開發框架卻無法做到。我們嘗試過通過靜態程式碼分析將 H5 程式碼轉換為小程式,但只做了檢視層轉換,無法帶來更多收益。多端程式碼複用需要更成熟的解決方案。

引入 Vue.js:小程式開發方式與 H5 近似,因此我們考慮和 H5 做程式碼複用。沿襲團隊技術棧選型,我們將 Vue.js 確定為小程式開發規範。使用 Vue.js 開發小程式,將直接帶來如下開發效率提升:

H5 程式碼可以通過最小修改複用到小程式

使用 Vue.js 元件機制開發小程式,可實現小程式和 H5 元件複用

技術棧統一後小程式學習成本降低,開發者從 H5 轉換到小程式不需要更多學習

Vue.js 程式碼可以讓所有前端直接參與開發維護

為什麼是 Vue.js?這取決於團隊技術棧選型,引入新的選型與統一技術棧和提高開發效率相悖,有違開發工具服務業務的初衷。

mpvue的演進

mpvue的形成,來源於業務場景和需求,最終方案的確定,經歷了三個階段。

第一階段:我們實現了一個檢視層程式碼轉換工具,旨在提高程式碼首次開發效率。通過將H5檢視層程式碼轉換為小程式程式碼,包括 HTML 標籤對映、Vue.js 模板和樣式轉換,在此目的碼上進行二次開發。我們做到了有限的程式碼複用,但元件化開發和小程式學習成本並未得到有效改善。

第二階段:我們著眼於完善程式碼元件化機制。參照 Vue.js 元件規範設計了程式碼組織形式,通過程式碼轉換工具將程式碼解析為小程式。轉換工具主要解決元件間資料同步、生命週期關聯和名稱空間問題。最終我們實現了一個 Vue.js 語法子集,但想要實現更多特性或跟隨 Vue.js 版本迭代,工作量變得難以估計,有永無止境之感。

第三階段:我們的目標是實現對 Vue.js 語法全集的支援,達到使用 Vue.js 開發小程式的目的。並通過引入 Vue.js runtime 實現了對 Vue.js 語法的支援,從而避免了人肉語法適配。至此,我們完成了使用 Vue.js 開發小程式的目的。較好地實現了技術棧統一、元件化開發、多端程式碼複用、降低學習成本和提高開發效率的目標。

mpvue設計思路

Vue.js 和小程式都是典型的邏輯檢視層框架,邏輯層和檢視層之間的工作方式為:資料變更驅動檢視更新;檢視互動觸發事件,事件響應函式修改資料再次觸發檢視更新,如圖1所示。

圖1: 小程式實現原理

圖1: 小程式實現原理

鑑於 Vue.js 和小程式一致的工作原理,我們思考將小程式的功能託管給 Vue.js,在正確的時機將資料變更同步到小程式,從而達到開發小程式的目的。這樣,我們可以將精力聚焦在 Vue.js 上,參照 Vue.js 編寫與之對應的小程式程式碼,小程式負責檢視層展示,所有業務邏輯收斂到 Vue.js 中,Vue.js 資料變更後同步到小程式,如圖2所示。如此一來,我們就獲得了以 Vue.js 的方式開發小程式的能力。為此,我們設計的方案如下:

圖2:mpvue 實現原理

圖2:mpvue 實現原理

Vue程式碼

將小程式頁面編寫為 Vue.js 實現

以 Vue.js 開發規範實現父子元件關聯

小程式程式碼

以小程式開發規範編寫檢視層模板

配置生命週期函式,關聯資料更新呼叫

將 Vue.js 資料對映為小程式資料模型

並在此基礎上,附加如下機制

Vue.js 例項與小程式 Page 例項建立關聯

小程式和 Vue.js 生命週期建立對映關係,能在小程式生命週期中觸發 Vue.js 生命週期

小程式事件建立代理機制,在事件代理函式中觸發與之對應的 Vue.js 元件事件響應

這套機制總結起來非常簡單,但實現卻相當複雜。在揭祕具體實現之前,讀者可能會有這樣一些疑問:

要同時維護 Vue.js 和小程式,是否需要寫兩個版本的程式碼實現?

小程式負責檢視層展現,Vue.js的檢視層是否還需要,如果不需要應該如何處理?

生命週期如何打通,資料同步更新如何實現?

上述問題包含了 mpvue 框架的核心內容,下文將仔細為你道來。首先,mpvue 為提高效率而生,本身提供了自動生成小程式程式碼的能力,小程式程式碼根據 Vue.js 程式碼構建得到,並不需要同時開發兩套程式碼。

Vue.js 檢視層渲染由 render 方法完成,同時在記憶體中維護著一份虛擬 DOM,mpvue 無需使用 Vue.js 完成檢視層渲染,因此我們改造了 render 方法,禁止檢視層渲染。熟悉原始碼的讀者,都知道 Vue runtime 有多個平臺的實現,除了我們常見的 Web 平臺,還有 Weex。從現在開始,我們增加了新的平臺 mpvue。

生命週期關聯:生命週期和資料同步是 mpvue 框架的靈魂,Vue.js 和小程式的資料彼此隔離,各自有不同的更新機制。mpvue 從生命週期和事件回撥函式切入,在 Vue.js 觸發資料更新時實現資料同步。小程式通過檢視層呈現給使用者、通過事件響應使用者互動,Vue.js 在後臺維護著資料變更和邏輯。

可以看到,資料更新發端於小程式,處理自 Vue.js,Vue.js 資料變更後再同步到小程式。為實現資料同步,mpvue 修改了 Vue.js runtime 實現,在 Vue.js 的生命週期中增加了更新小程式資料的邏輯。

事件代理機制:使用者互動觸發的資料更新通過事件代理機制完成。在 Vue.js 程式碼中,事件響應函式對應到元件的 method, Vue.js 自動維護了上下文環境。然而在小程式中並沒有類似的機制,又因為 Vue.js 執行環境中維護著一份實時的虛擬 DOM,這與小程式的檢視層完全對應,我們思考,在小程式元件節點上觸發事件後,只要找到虛擬 DOM 上對應的節點,觸發對應的事件不就完成了麼;另一方面,Vue.js 事件響應如果觸發了資料更新,其生命週期函式更新將自動觸發,在此函式上同步更新小程式資料,資料同步也就實現了。

mpvue如何使用?

mpvue框架本身由多個npm模組構成,入口模組已經處理好依賴關係,開發者只需要執行如下程式碼即可完成本地專案建立。

# 安裝 vue-cli$ npm install --global vue-cli# 根據模板專案建立本地專案,目前為內網地址$ vue init ‘bitbucket:xxx.meituan.  com:hfe/mpvue-quickstart’ --clone my- project# 安裝依賴和啟動自動構建$ cd my-project$ npm install$ npm run dev

執行完上述命令,在當前專案的 dist 子目錄將構建出小程式目的碼,使用小程式開發者工具載入 dist 目錄即可啟動本地除錯和預覽。示例專案遵循 Vue.js 模板專案規範,通過Vue.js 命令列工具vue-cli建立。程式碼組織形式與 Vue.js 官方例項保持一致,我們為小程式定製了 Vue.js runtime 和 webpack 載入器,此部分依賴也已經內建到專案中。

針對小程式開發中常見的兩類程式碼複用場景,mpvue 框架為開發者提供瞭解決思路和技術支援,開發者只需要在此指導下進行專案配置和改造。我們內部實踐了一個將 H5 轉換為小程式的專案,下圖為使用 mpvue 框架的轉換效果:

圖3: H5 和小程式轉換效果

將小程式轉換為H5:直接使用 Vue.js 規範開發小程式,程式碼本身與H5並無不同,具體程式碼差異會集中在平臺 Api 部分。此外並不需明顯改動,改造主要分如下幾部分:

將H5轉換為小程式:已經使用 Vue.js 開發完 H5,我們需要做的事情如下:

根據小程式開發平臺提供的能力,我們最大程度的支援了 Vue.js 語法特性,但部分功能現階段暫時尚未實現。

表1: mpvue 暫不支援的語法特性

表1: mpvue 暫不支援的語法特性

專案轉換注意事項:框架的目標是將小程式和 H5 的開發方式通過 Vue.js 建立關聯,達到最大程度的程式碼複用。但由於平臺差異的客觀存在(主要集中在實現機制、底層Api 能力差異),我們無法做到程式碼 100% 複用,平臺差異部分的改造成本無法避免。對於程式碼複用的場景,開發者需要重點思考如下問題並做好準備:

儘量使用平臺無的語法特性,這部分特性無需轉換和適配成本

避免使用不支援的語法特性,譬如 slot, filter 等,降低改造成本

如果使用特定平臺 Api ,考慮抽象好適配層介面,通過切換底層實現完成平臺轉換

mpvue最佳實踐

在表2中,我們對微信小程式、mpvue、WePY 這三個開發框架的主要能力和特點做了橫向對比,幫助大家瞭解不同框架的側重點,結合業務場景和開發習慣,確定技術方案。對於如何更好地使用 mpvue 進行小程式開發,我們總結了一些最佳實踐。

使用 vue-cli 命令列工具建立專案,使用Vue 2.x 的語法規範進行開發

避免使用框架不支援的語法特性,部分 Vue.js語法在小程式中無法使用,儘量使用 mpvue 和 Vue.js 共有特性

合理設計資料模型,對資料的更新和操作做到細粒度控制,避免效能問題

合理使用元件化開發小程式,提高程式碼複用率

表2: 框架使用特點對比

表2: 框架使用特點對比

結語

mpvue 框架已經在業務專案中得到實踐和驗證,目前正在美團點評內部大範圍使用。mpvue 來源於開源社群,飲水思源,我們也希望為開源社群貢獻一份力量,為廣大小程式開發者提供一套技術方案。mpvue 的初衷是讓 Vue.js 的開發者以低成本接入小程式開發,做到程式碼的低成本遷移和複用,我們未來會繼續擴充套件現有能力、解決開發者的訴求、優化使用體驗、完善周邊生態建設,幫助到更多的開發者。

最後,mpvue 基於 Vue.js 原始碼進行二次開發,新增加了小程式平臺的實現,我們保留了跟隨 Vue.js 版本升級的能力,由衷的感謝 Vue.js 框架和微信小程式給業界帶來的便利。