使用Vue.js開發小程式開源架構mpvue解析,vue.jsmpvue
前言
mpvue是一款使用Vue.js開發小程式的前端架構。使用此架構,開發人員將得到完整的 Vue.js 開發體驗,同時為H5和小程式提供了代碼複用的能力。如果想將 H5 項目改造為小程式,或開發小程式後希望將其轉換為H5,mpvue將是十分契合的一種解決方案。
目前,mpvue已經在美團點評多個實際商務專案中得到了驗證,因此我們決定將其開源,希望更多技術同行一起開發,應用到更廣泛的情境裡去。github項目地址請參見mpvue 。使用文檔請參見 http://mpvue.com/。
為了協助大家更好的理解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: 小程式實現原理
鑒於 Vue.js 和小程式一致的工作原理,我們思考將小程式的功能託管給 Vue.js,在正確的時機將資料變更同步到小程式,從而達到開發小程式的目的。這樣,我們可以將精力聚焦在 Vue.js 上,參照 Vue.js 編寫與之對應的小程式代碼,小程式負責視圖層展示,所有商務邏輯收斂到 Vue.js 中,Vue.js 資料變更後同步到小程式,2所示。如此一來,我們就獲得了以 Vue.js 的方式開發小程式的能力。
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 部分。此外並不需明顯改動,改造主要分如下幾部分:
- 將小程式平台的 Vue.js 架構替換為標準 Vue.js
- 將小程式平台的 vue-loader 載入器替換為標準 vue-loader
- 適配和改造小程式與 H5 的底層 Api 差異
將H5轉換為小程式:已經使用 Vue.js 開發完 H5,我們需要做的事情如下:
- 將標準 Vue.js 替換為小程式平台的 Vue.js 架構
- 將標準 vue-loader 載入器替換為小程式平台的 vue-loader
- 適配和改造小程式與 H5 的底層 Api 差異
根據小程式開發平台提供的能力,我們最大程度的支援了 Vue.js 文法特性,但部分功能現階段暫時尚未實現。
表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: 架構使用特點對比
結語
mpvue 架構已經在商務專案中得到實踐和驗證,目前正在美團點評內部大範圍使用。mpvue 來源於開源社區,飲水思源,我們也希望為開源社區貢獻一份力量,為廣大小程式開發人員提供一套技術方案。mpvue 的初衷是讓 Vue.js 的開發人員以低成本接入小程式開發,做到代碼的低成本遷移和複用,我們未來會繼續擴充現有能力、解決開發人員的訴求、最佳化使用體驗、完善周邊生態建設,協助到更多的開發人員。
最後,mpvue 基於 Vue.js 源碼進行二次開發,新增加了小程式平台的實現,我們保留了跟隨 Vue.js 版本升級的能力,由衷的感謝 Vue.js 架構和小程式給業界帶來的便利。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。