Categories
程式開發

Chameleon跨端框架源碼剖析系列(一):框架概覽


1 前言

近幾年隨著移動互聯網的發展,尤其各個端平台推出了小程序入口,比如微信、支付寶、頭條等,不同端平台之間的語法規範不統一,代碼組織結構複雜,開發者早期應對同樣的業務需求,需要在各端平台上各自維護一套代碼,開發成本高,難以滿足高效快速的日常維護。對於開發效率上的極致追求,使得”一次編寫,到處運行”的跨端融合述求在前端領域裡進一步提高。從本質上講,跨端融合就是統一多端開發模式,增加代碼復用,降低開發成本、保證多端一致性的體驗。

目前前端領域已發展出多種不同的跨端解決方案,比如Chameleon、Taro、Mpvue等,這些跨端解決方案的核心解決思路是一致的,基本上都是編譯+runtime運行時的解決模式。編譯指的是利用Babel的編譯能力和WebPack提供的loader、plugin等構建能力,對源代碼進行一系列分析流程之後,對原始代碼進行優化並根據不同的端平台轉換,最終得到目標代碼。

Chameleon跨端框架源碼剖析系列(一):框架概覽 11

runtime指的是各個解決方案轉換成各目標代碼所需要的運行時依賴。不同跨端解決方案在runtime的實現細節和具體功能上存在一定的差異性,這裡不一一列舉。

在各個跨端解決方案中,Chameleon(簡寫CML )是一款真正專注於讓一套代碼運行多端的跨端框架,始終秉承“一套代碼運行多端,一端所見即多端所見” 的初心,多端高度一致,無需關注各端的文檔。目前CML已經成功擴展支持全平台小程序(微信、支付寶、百度、qq、頭條),未來更會擴展到更多的端平台應用。本系列教程主要介紹Chameleon跨端框架背後的實現機制,針對源碼進行深度剖析,系統分析了整個跨端框架背後的基本原理,包括:CML的命令行註冊運行、WebPack配置、路由實現、模板解析能力、工程化配置方案、核心編譯加載器loader和插件plugin、分包實現等。整個系列教程最好和CML的源碼配合,讀者需要先了解整個的CML的整體架構和斷點開發調試。

2 整體架構

CML基於底層的打包構建工具,配合chamleon-runtime運行時和統一的多端接口chammeleon-api, 將通過統一的語言框架 + 統一的多態協議組合成的多端業務代碼轉換成多端目標代碼。

Chameleon跨端框架源碼剖析系列(一):框架概覽 12

整個CML源碼主要可分為三個部分:打包構建、核心運行時、統一API。

打包構建

倉庫地址:https://github.com/didi/chameleo

打包構建倉庫的packages文件夾中主要包含了構建CML項目時所依賴的npm模塊,比如:chameleon-tool腳手架、webpack構建時所需要的loader和plugin、數據mock服務等。 CML通過webpack構建工具,對統一的語言.cml文件解析,對解析後template、script、style部分分別引入不同的依賴模塊和特殊的端處理模塊,最終將原始的cml代碼轉換成目標各端代碼。

Chameleon跨端框架源碼剖析系列(一):框架概覽 13

每個構架依賴包在CML項目構建環節中都充當不同的作用,這裡先整理了構建倉庫中比較核心的npm模塊包作用,後續的系列教程也會對涉及到的依賴包進行詳細剖析。

Chameleon跨端框架源碼剖析系列(一):框架概覽 14

構建依賴包眾多,每個依賴包可能會互相引用,使用npm link將每個依賴包放到全局node_modules中使用,將會整個倉庫維護起來特別繁瑣。所以構建倉庫使用了基於lerna的基本工作流,解決packages中不同包相互依賴的問題。

學習lerna可以查閱如下資料:lerna管理前端packages的最佳實踐(https://juejin.im/post/5a989fb451882555731b88c2)

核心運行時

倉庫地址:https://github.com/chameleon-team/chameleon-runtime

核心運行時倉庫是CML轉換後目標各端代碼在各端運行時所需要相關代碼,獨立於打包構建倉庫。開發者在使用如下命令初始化項目時,整個業務項目會依賴chameleon-runtime提供的運行時的能力

cml init

chameleon-runtime對外導出以外方法,供構建倉庫中的chameleon-tool使用:

  • bootstrap啟動應用
  • createApp創建App
  • createPage創建頁面
  • createComponent創建組件

後續的系列教程也會涉及到整個運行時進行詳細剖析。

統一API

倉庫地址:https://github.com/chameleon-team/chameleon-api

本倉庫為chameleon的api的相關代碼,chameleon 支持大量基礎API,對外提供統一的接口,以模塊的方式引入chameleon-api進行使用。查閱接口及擴展文檔:https://cmljs.org/doc/api/api.html

3 斷點開發調試

閱讀源碼無法避免進行斷點開發調試。斷點調試方案主要使用如下兩種方案:利用v8自帶的檢查器連接chrome進行調試和利用IDE(VsCode)工具進行調試

利用v8自帶的檢查器連接chrome進行調試

整體腳手架調試都是基於Node層面進行調試,Node的V8 檢查器集成允許將 Chrome 開發者工具附加到 Node.js 實例以進行調試和性能分析。如果開發者已經在全局安裝了chameleon-tool構建工具,開發者即可在終端輸入cml -v命令查看CML在全局環境的安裝路由:

current running chameleon(/Users/didi/.nvm/versions/node/v10.16.3/lib/node_modules/chameleon-tool/)

在當前項目下找到chameleon.js入口文件,將入口文件的如下內容取消註釋,即可開始調試:

#! /usr/bin/env node
// --inspect-brk

更多的有關於v8自帶的檢查器連接chrome進行調試方案見debugger Nodejs API文檔:http://nodejs.cn/api/debugger.html

優點: 便於基於已有的項目快速進行調試chameleon-tool

缺點: 對於chameleon-tool所依賴的模塊包無法快速切換調試;容易對已有正確的chameleon-tool構建工具造成污染

利用IDE(VsCode)自帶的工具進行調試

1. 從遠程倉庫克隆到本地

git clone https://github.com/didi/chameleon.git

2. 使用VsCode項目打開此項目,然後按照下圖的步驟創建launch.json

Chameleon跨端框架源碼剖析系列(一):框架概覽 15

launch.json的內容如下:

{
  // 使用 IntelliSense 了解相关属性。
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "CML测试",
      "program": "${workspaceFolder}/packages/chameleon-tool/chameleon.js",
      "args": ["wx", "dev"],
      "cwd": "/Users/didi/WorkSpace/hummer-dsl-cml-test"
    }
  ]
}

上面的launch.json中配置解析如下:

  • program表示當前構建倉庫的chameleon-tool的入口文件
  • args表示要運行命令,讀者可以改成其他運行命令
  • cwd表示構建好的項目倉庫地址,讀者可以改成自己構建好的項目倉庫地址

launch.json配置好後,讀者可以在克隆下來的本地構建倉庫項目中隨意增加斷點,然後點擊運行和調試按鈕,即可進入調試。更多有關通過VsCode進行調試見Debugging in Visual Studio Code(https://code.visualstudio.com/Docs/editor/debugging)

參考文獻

github地址

https://github.com/didi/chameleon

官網

https://cml.js.org/

作者介紹

阮榕城,滴滴高級軟件開發工程師

我是阮榕城,熱愛前端,熱愛技術,不搞花里胡哨,踏踏實實敲代碼。平時喜歡看看漫畫,到處走走,吃不了辣的吃貨。

本文轉載自公眾號普惠出行產品技術(ID:pzcxtech)。

原文鏈接

https://mp.weixin.qq.com/s/BJl54Hn2H2AoRyHH-jafmg