龔澄,經常使用ID: Gcaufy,小程序開源框架 WePY 做者,熱愛技術,熱愛開源。於2015年加入騰訊,負責騰訊手機充值相關業務的開發。2018年加入微信支付,負責微信支付商戶側業務小程序的開發。前端
本主題雖然在其它地方講了不少次,但仍是有很是多新內容。由於不少東西正在作或者想要作。本次分享主要分爲如下幾個部分: vue
上面展現的 WePY 用戶不是所有的數據。由於沒有辦法讓 WePY 用戶主動上報本身在使用 WePY,因此我只列了我知道的在使用 WePY 的公司,數據比較有限。webpack
就我所知道的,最近有一個刷爆朋友圈的小程序 —— 騰訊疫苗,前端採用的 WePY,後端用了騰訊開源的 TARS 項目。微信支付內部也有大量小程序在使用 WePY 框架。web
右邊貼的聊天記錄是我在 WePY 交流羣收集到的用戶反饋,就反饋的內容來看,有不少感謝的話,說明 WePY 這個框架確實能幫助開發者提升本身的開發效率。嘿嘿,我沒有貼 WePY 的負面反饋,由於我擔憂一頁 PPT 不夠貼 👀。vue-cli
WePY 項目在 Github 上如今有13900多個 Star。拿其它前端框架對比,Vue、React 等 Star 數可能達到了 10W+,可是它們都是國際的項目。WePY 這個項目因爲微信小程序的緣由,算是一個國內項目,能有13000多個 Star 仍是至關不錯的。Star 數多不必定表明 WePY 這個框架好,可是能代表小程序這塊流量很大,開發小程序也很是有前景。 開發者們須要 WePY 這樣的框架來提供幫助。這也是爲何後來出現了 Taro、mpvue 等相似的很是優秀的框架。npm
issues 目前有1300多個。這意味着我天天起牀都有超過10條 to-do list 須要處理。加上天天還有公司的其它事情須要處理,比較頭大。小程序
pull requests 目前有320多條。相比其它開源項目,這個 PR 數量至關不錯,很是感謝爲 WePY 做貢獻的開發者們。後端
用戶數有4000多。這個數據的來源我是統計的我創建的 WePY 交流羣,目前這個交流羣裏有 4000 多人。微信小程序
將 Web App 和小程序進行對比。Web App 和小程序在功能上相似, Web App 在開發的時候,可能使用 Vue.js 做爲其核心庫,用 Webpack 進行打包。在微信小程序中,你們能夠簡單的將 WePY 理解爲 Web App 裏的 Vue.js + Webpack 的合體。前端工程化
WePY 在開發中到底幫助開發者作了什麼事情呢?WePY 又有哪些特色呢?
16年8月參加小程序內測,10月份開始着手代碼轉換相關的工做。在不停的迭代中,我發現還有不少事情能夠作。好比能夠將相關的工做抽象出來提供給其它開發者。因而在11月我對代碼進行了重構,將 Gulp 編譯部分拋棄重寫並於 Github 開源1.1版本。
開源以後有不少人關注到這個項目,說明仍是有很多人遇到了相應的問題。所以我作了更加具體的優化,在1.1版本上又一次重構,把編譯流程抽象,提出了編譯器和插件兩個概念,方便用戶進行擴展。
17年1月份發佈1.4版本,對整個開發流程和開發者使用框架時的體驗進行了更多優化,包括性能優化等。
1.6 版本開始考慮多端問題:小程序一套代碼多端複用。
17年11月左右,小程序推出了原生組件。WePY 自己就是爲了解決小程序組件的問題,原生組件發佈以後,WePY 的使用場景就沒有之前那麼強了,因此我開始思考, WePY 須要作一個徹底重構的版本。
18年2月份啓動了該重構版本,這個版本主要是爲了解決小程序原生組件相關的問題,是一個全新的重構版本。但因爲各類緣由,這個版本尚未正式公佈。敬請期待!
接下來我會講一下 WePY 在技術上的實現原理。
總的來講,WePY 解決的問題就是開發中遇到的痛點問題。
上面是我寫的兩個核心的部分:CLI 以及 Core。Core 經過 CLI 編譯,生成小程序端運行的代碼。CLI 部分又分爲 wepy、wepy-web ,分別負責 wepy 的編譯和 wepy-web 的編譯。其上又分爲編譯器和插件兩部分,編譯器涉及到目前主流的預處理器,相似 Webpack 的 loader 。插件是在編譯以後要作的事情,相似於 Webpack 的 plugin。Core 部分分爲 wepy 核心庫、小程序核心庫和 wepy-web 核心庫。wepy-web 核心庫比小程序多了 wepy components 和 wepy API 。小程序自己的一些內置組件,好比彈窗組件,想要多端運行都須要封裝起來放在 wepy components 。小程序原生 API 須要經過 wepy API 封裝。
web 自己還分不少平臺種類,好比 browser、微信 h五、QQ h5,這些都須要分別適配,因此 wepy-web 之上是一個適配層。
整個 Core 之上,是用戶封裝的一些組件,好比上報、異步。還有一些功能組件,好比用戶作的彈窗、toast、imageloader 等。
縱觀整個 WePY,個人代碼會經過 CLI 基於 Core 輸出小程序端運行的代碼。
以上就是 WePY 的整個編譯過程。
在實現多端方面,面臨着如下問題:
開發模式
小程序開發模式自成一派,與現有開發模式都不相同。好在使用 WePY 開發時,WePY 使用的是類 Vue 的開發語法,跟 Vue 開發模式很貼近,因此開發模式問題藉助 WePY 很是好解決。
標籤與樣式
小程序與 H5 的標籤不同,可是能夠直接作一些簡單的轉換處理。好比 <view>
轉換爲<div>
。樣式上小程序有一個 rpx 單位,在 750 px 的狀況下直接 /2 將 rpx 轉爲 px。
模版語法
小程序有本身的模版語法,好比 <wx-if>
等,解析時能夠作簡單的轉換。
模塊化
小程序原生可使用 require
,可是H5不能夠。好在有不少工具值得借鑑,好比 webpack,browserify。
內置組件及內置 API
WePY 自己使用的是類 Vue 的語法,要轉換爲 Vue 運行在 Web 端的話,內置組件直接使用 Vue 的形式編寫,使用時直接引入這個 Vue 組件。內置 API 使用 WePY 提供的 JSSDK 去模擬微信端、H5等提供的 API。
所以,多端實現徹底可行。咱們的一些項目徹底利用 WePY 實現多端。
左邊是在 Github 上看到的一些 UI 庫,你們在使用 WePY 開發的時候能夠直接利用這些 UI 庫進行二次開發。右邊是網上收集到的開發資源,包括開發組件、第三方模塊等。Github 上 WePY 關鍵字搜索結果有900多頁。從用戶反饋來看,用戶選擇 WePY 的一個緣由也是 WePY 誕生的時間長,生態比較完善。
WePY 目前存在的核心問題是
靜態組件編譯
WePY 項目作的比較倉促,花了大概一個多月就上線了。最開始只是爲了解決組件化的問題。所以它採用了靜態組件編譯這套方案,在編譯組件時,直接將我寫的組件進行靜態替換,將我寫的組件注入到頁面中,作了一些隔離相關的事情。這致使動態 repeat 時會出現比較嚴重的 BUG。這是設計上的缺陷,也是急需解決的問題。
語法解析
xml 的解析用了一個存在問題的庫,致使 xml 解析時常常出錯。js 的解析設計之初沒有考慮用語法樹解析,而是使用正則進行解析。由於目前僅涉及解析和語法注入,實現起來都比較簡單,因此沒有考慮用 AST 語法樹進行解析,致使用戶沒有按照規範寫的一些代碼在解析時會出現錯誤。
類 Vue 語法
從用戶的反饋來看,你們更但願用 Vue 的語法而不是類 Vue 語法。這兩個之間仍是有一些差別的。
數據綁定性能優化
數據綁定時作了一些優化和處理。但這些優化和處理是經過髒數據進行的,幫助用戶減小 setDate 的次數。可是後來再看,這塊仍是有能夠優化的空間。
錯誤處理機制
目前 WePY 的錯誤處理還比較簡單,沒有一個通用的錯誤處理機制。用戶在使用和編譯時的報錯很難追溯和定位。後面但願能作到在報錯時能夠定位到報錯的文件和代碼。
測試用例覆蓋度
WePY 目前只有核心庫被測試用例覆蓋。CLI 部分很複雜沒有作測試用例覆蓋。這致使目前大部分問題都和 CLI 相關。在下一個版本要所有被測試用例覆蓋。
上圖是2.0版本編譯部分的對比。左邊是 1.0 的編譯,右邊是2.0正在作的事。前面有講到1.0的編譯是把.wpy 文件放到 CLI 中進行編譯。CLI 自己涉及編譯器和插件。在2.0中,將文件編譯修改成了入口編譯,從 App 入口,經過 CLI 自動解析依賴,CLI 中也只有插件,全部的核心功能都將經過插件實現。最後生成的除了小程序文件,還有 Vendor 文件(Vendor 文件是指全部的 npm 包都會打包到這個文件內)、資源文件以及本身引用的模塊的文件。
編譯的核心部分是參考 Webpack 作的插件化編譯。插件化的概念參考我上面作的圖:固定一塊板子,板子上有固定數量的掛鉤,每一個掛鉤均可以掛不一樣的東西。每一個掛鉤放什麼不清楚,可是每一個掛鉤均可以實現不一樣的功能。我只須要規定編譯的流程,經過在掛鉤中寫不一樣的內容實現整個編譯流程。因此整個編譯過程變爲:配置初始化➡️核心編譯➡️輸出文件。
插件化能夠提供更高的擴展性和可複用性。全部的核心功能都依賴插件進行。用戶以爲某個功能不合適的時候,徹底能夠本身寫一個插件替換掉核心功能。用戶能夠對編譯的任何一個環節進行修改。
v1 的數據綁定:在初始化的時候對數據進行深拷貝作數據備份。每一個流程都會預置 apply 動做,好比有一個點擊事件,點擊事件對數據進行修改後進入到 apply 流程,在 apply 流程中進行深比較獲得髒數據,髒數據最終進入到 setDate 中。
右邊是比較簡單易懂的圖:小明對文件 B 進行修改獲得 B+,老師將 B+ 和 B 進行對比,獲得修改的數據。這是一個同步流程。當小明叫小紅修改 C 文件時,若是老師再也不,須要小紅主動叫老師對 C 文件進行對比。即手動調用 apply 流程。
2.0 使用了 Vue 的數據綁定機制。在初始化時生成 Render Watcher,每一個數據初始化時都會添加 observer。修改數據時記錄修改的 key-path 並加入隊列中,全部的修改動做都會觸發 Watcher。在一個 nextTick 時間內會清空隊列,並在 Render Watcher 中進行 setDate。setDate 環節根據記錄的 key-path 進行 setDate。
相比小明和老師的故事:小明在修改文件時會主動記錄修改的內容併發起通知,小紅的操做方式與小明一致。當老師收到通知時,根據小明、小紅的修改記錄對修改的內容進行 setDate 的處理。
這種優化方式不須要手動調用 apply,也不須要關心異步流程。
第二個版本會先在內部項目運用,內部實踐以後沒有問題再開源。另外2.0版本測試用例覆蓋度要徹底覆蓋。
如何保證開源項目的質量?
第一是文檔規範。Readme 部分要言簡意賅的講明這個項目能作什麼,一個簡單的示例說明如何啓動項目。Readme 要簡潔,你們一眼能看到他想要的東西。
第二是 CI。將對應的狀態放在 Readme,讓開發者能夠更安心的使用這個項目。
第三是 license。
還有 contributer 文檔,代碼規範、Git 規範等。
測試使用了 Mocha 和 Istanbul,集成使用了 TravisCI,部署使用了 npm 和 lerna。
推廣運營方面主要靠本身發文章,作外鏈。另外我在公衆號和微信羣推了本身的文章。微信羣作了一個機器人放入羣碼。
還作了文檔監控,官方文檔修改以後,我能夠第一時間知道官方文檔都修改了什麼。以及監控報告,天天都會給個人微信推送今天項目有多少 star 、多少 issue 。
後期維護主要是文檔、issue、pr 和新的計劃維護。右邊的圖,灰色部分是我沒打標籤的 issue。下面閉合的是我在相應時間點處理完的 issue,沒有閉合代表這個 issue 還在處理中。
WePY 2.0 目前處於內測階段,10月底會發布公測版本。