Taro小程序跨端開發入門實戰

語言: CN / TW / HK

背景

一開始我們只做微信小程序隨着我們的業務不斷擴張和各大小程序平台的崛起,針對每個平台都去寫一套代碼是不現實的。而且原生的小程序開發模式有很多弊端。

為了讓小程序開發更簡單,更高效,我們採用 Taro 作為首選框架,我們將使用 Taro 的實踐經驗整理了出來,主要內容圍繞着什麼是 Taro,為什麼用 Taro,以及 Taro 如何使用(正確使用的姿勢),還有 Taro 背後的一些設計思想來進行展開,讓大家能夠對 Taro 有個完整的認識。

Taro 3.0 已經逐漸成熟,我們項目已經進行了Taro 3.0的升級,因此本文代碼示例以 Taro 3.0 作為基礎。

什麼是 Taro

Taro 是一個多端統一的開發框架。使用 taro 它可以支持 React 的開發方式,編寫一次可以運行多端的代碼,就能夠生成可以在各種小程序,H5 甚至 React Native 等多端應用。

Taro 官方介紹:
Taro 是一個開放式跨端跨框架解決方案,支持使用 React/Vue/Nerv 等框架來開發 微信 / 京東 / 百度 / 支付寶 / 字節跳動 / QQ 小程序 / H5/ React Native 等應用。現如今市面上端的形態多種多樣,Web、React Native、微信小程序等各種端大行其道,當業務要求同時在不同的端都要求有所表現的時候,針對不同的端去編寫多套代碼的成本顯然非常高,這時候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。

它的主要特點是:
快:可以快速開發小程序: 解決小程序開發各種痛點;
多:可以實現多終端適配:一套代碼適配小程序、H5、RN 等多終端;

為什麼用 Taro

隨着應用變得龐大之後,複雜度越來越高,原生小程序開發的痛點逐漸暴露出來:
•代碼組織複雜:寫一個頁面的文件結構繁瑣(四個之多)
•規範不統一:組件、方法命名規範不統一、各種書寫方式,語法結構不一致像 React 又像 Vue
•孱弱的字符串模板:邏輯表現力不強,不支持 eslint
•依賴管理混亂:缺少 npm 包依賴管理
•不完全的 ES Next:僅支持部分 ES Next 語法,比較新的 ES2020, ES2021+ 都不支持
•落後的開發方式:前端工程體系不完善,webpack 打包,css 預處理等缺失,對於前端來説比較落後的,對個人成長也不利

可選技術方案可選技術方案

對於以上微信小程序開發模式的痛點,業界也給出了一些可選方案:

對比分析

  • mpvue 是美團研發的框架,多端適配效果不好,很久問題都沒人維護;
  • WePY 是騰訊出的組件化框架,但是無法適配多端;
  • Chameleon 在多端適配方面表現很突出,缺點是不支持京東小程序,無法轉換原生小程序(想用只能重寫項目);
  • Taro 優秀的特性,遵循 React/Vue 語法規範,引入的現代化的開發流程,讓開發更專注核心代碼,提供健全的代碼檢查方式。

多端需求


Taro 支持平台最全面,獨具轉換能力,性能方面優於其它框架,總結特點如下:

  • 可以實現微信小程序原生代碼轉換到微信平台,百度平台等;
  • Taro 框架是唯一一款實現京東小程序適配的框架;
  • 支持 React/Vue 語法,更好的支持組件化和 TypeScript;
  • 行業影響力大,社區活躍,京東內部優秀團隊研發的框架,支持有保障,研發團隊靠譜非常支持我們的工作;
  • 更加完善的UI組件庫,支持多端同步調試能夠適配更多終端;

一處編寫,多端運行

設計思想

主要採用 React 開發方式

用 React 寫多端應用

核心思想

代碼轉換:使代碼可以在不同平台上運行
運行時適配:使代碼在不同平台上有相同表現

以微信小程序為例以微信小程序為例

JSX

WXML

Taro 代碼編譯原理


Taro 的編譯原理:就是對輸入的源代碼進行語法分析,語法樹構建,隨後對語法樹進行轉換操作再解析生成目標代碼的過程。

首先是 Parse,將代碼解析(Parse)成抽象語法樹(Abstract Syntex Tree),然後對 AST 進行遍歷(traverse)和替換(replace)(這對於前端來説其實並不陌生,可以類比 DOM 樹的操作),最後是生成(generate),根據新的 AST 生成編譯後的代碼。

開發時遵循 React 語法標準,結合編譯原理的思想,對代碼文件進行一系列轉換操作,最終獲得可以在小程序運行的代碼。而 React 最開始就是為了解決 Web 開發而生的,所以對代碼稍加改動,也可以直接生成在 Web 端運行的代碼,而同屬 React 語法體系下的 React Native,也能夠很便捷地提供支持。同理其他平台,如快應用、百度小程序等,將源碼進行編譯轉換操作,也能獲得該平台下的對應語法代碼。

可以看出小程序和 Web 端上組件標準與 API 標準有很大差異,這些差異僅僅通過代碼編譯手段是無法抹平的,例如你不能直接在編譯時將小程序的 直接編譯成

 

,因為他們雖然看上去有些類似,但是他們的組件屬性有很大不同的,僅僅依靠代碼編譯,無法做到一致,同理,眾多 API 也面臨一樣的情況。針對這樣的情況,Taro 採用了定製一套運行時標準來抹平不同平台之間的差異。

 

這一套標準主要以三個部分組成,包括標準運行時框架、標準基礎組件庫、標準端能力 API,其中運行時框架和 API 對應 @taro/taro,組件庫對應 @tarojs/components,通過在不同端實現這些標準,從而達到去差異化的目的。

多端適配基礎標準

  • 基礎框架(生命週期、組件API):以React的生命週期、組件api為基礎,小程序的特性作為補充
  • 標準組件庫(View、Button): 以微信小程序組件為標準,各端模擬實現
  • 標準Api (request、setState):擴展的小程序標準Api,各端模擬實現

多端適配基礎架構圖如下:

快速上手

初始化項目

環境準備:需要有個 node 環境,運行 npm 命令:

 


 

開始使用 Taro 編寫頁面:

運行項目

多平台啟動命令示例:

如果同時看三端效果:分別運行以上命令即可;

微信原生小程序轉換 Taro 小程序

Taro 項目的組成

Taro項目目錄結構

基本的目錄結構:

比較完整的多端項目結構:

完整的文檔請訪問:https://taro-docs.jd.com/

多端適配

多終端配置文件編寫

•微信的配置文件 project.config.json,文件內容可以自定義微信小程序的選項,運行的目錄和 appid 等;
•百度小程序的配置文件 project.swan.json 內容和微信類似;
•京東小程序的配置文件 project.jd.json 內容和微信類似;
•其它平台的小程序都有獨立的配置文件便於運行的調試;

多終端入口文件

每個平台有不同的頁面配置信息:
•微信小程序頁面是全量的,有微信登錄頁面(其它平台不需要);
•百度小程序有專門的登錄頁面有些頁面百度不支持需隱藏比如:圖片裁剪,達達同城,打印等;
•京東小程序:不支持批量寄,不需要登錄頁面,不支持分包,都要寫入主包中;

 

 

差異化配置

  • 不同平台加載對應的文件:
  • 每個平台差異化配置信息:
  • 地圖類型;
  • 渠道信息;
  • 請求頭信息;
  • 。。。

    代碼差異化處理

平台特定 js 代碼塊兒實現,在任意 js 代碼中加入如下語法

平台特定 css 代碼塊兒實現, 在任意 css 代碼中加入如下語法

提示:代碼在打包時不會增加包體積,針對不同平台提取相應代碼。

多端適配案例

一些典型的多端通用解決方案:

  • 樣式解析:

    • 微信是 rpx,百度小程序 vw,京東小程序 px;
    • Taro 統一使用 px 通過框架處理轉換成對應平台的像素,因此 px 值不要使用單數;
    • 1px(像素)的邊框通常會轉換成平台對應單位會導致無法顯示, 可以使用大寫的PX單位,例如: 1PX ;
    • 百度小程序和京東小程序不支持 externalClasses,其它小程序也可能不支持避免使用;
  • 模塊導入和導出:

    • 導入模塊需要使用ES6 的 import, 不要使用 require 到 JS 文件(有些平台不支持);
    • 內聯本地圖片資源可以使用 require 動態導入;
    • 導入外部資源的 url 必須使用 https,有些平台或機型不支持 http ;
    • 小程序插件導入可以使用 require 但是要做多平台適配和兼容性處理;
  • 組件開發細節:

    • 組件 key 取值,不要使用 index ,對象的 id 屬性要先解構出來;
    • 組件渲染條件取 length 屬性頁面不更新;
    • dataset 問題:百度和微信獲取的不一樣,都要用小寫來保持代碼一致: 這種駝峯的:data-goodsIndex={index} ,微信會轉成全小寫 goodsindex, 百度會保留駝峯 ,正確地寫法:data-goodsindex={index} ;

百度小程序開發注意事項:

  • 層次較深的狀態不會更新時,需要解構變量;
  • 轉換成 vw 樣式有偏差,確保樣式的通用性;
  • 個別組件 height: auto 有bug,不寫沒事;
  • line-height 居中有偏差,用 flex 比較穩妥;
  • fixed 佈局居底要設置 left: 0, bottom: 0 ,不寫默認會有問題(默認在中間渲染);
  • mask 組件層級較深時,可能不會更新狀態,可以使用 tt-modal 代替;
  • 圖片裁剪,語音識別,打印功能等依賴原生 API 不支持;
  • 狀態更新從有到無需要顯性設置 null ,例如將列表組件隱藏:this.setState({list: null}) {list && <組件實例>};

京東小程序開發注意事項:

  • 不支持全局覆蓋組件樣式,如果想兼容需要單寫加上拼接樣式名;
  • 不支持小程序分包,需要單獨配置頁面路由信息;
  • showModal 彈窗不能定製 confirmColor 屬性;
  • storagesync 不支持存儲 json 數據,讀取需要自己手動JSON.parse;
  • 不支持 canvas繪畫API:微信自定義分享功能,圖片裁剪,訂單條形碼等功能都做不了;
  • 不支持同層渲染,原生組件上只能使用 Cover 組件;
  • ios 內嵌H5,如果url帶參數,需要手動做一下urlencode編碼;
  • H5頁面使用小程序 webview 不具備全部京東 app webview 功能,有些功能不支持;
  • 京東小程序分享 URL 和 其它小程序分享的 URL 不一樣,要注意路徑的差異區分:
    • 例如:shareURL: 京東小程序: page/index/index 微信小程序:/pages/index/index

多端同步調試

在 config/index.js 配置:outputRoot: dist/${process.env.TARO_ENV}

生態與規劃

物流風格的 Taro UI組件庫—Tarot(已適配Taro3.0)

定製化 Taro 模板工程定製化 Taro 模板工程

模板工程主要特性:
•自帶按需引入的 Tarot 組件庫及組件使用示例。
•自帶 pandora-tools 中的工具,如網關調用插件等。
•登陸適配多端,小程序端自動引入京東無線登陸插件,h5端自動跳轉無線統一登陸M頁d等。
•網關調用適配多端,自帶 Demo 示例;
•包含 TypeScript 和 Redux等更多高級API及用法示例;
•其它功能持續更新……

小程序 Mini Debug 工具

MiniDebug 是一款多端小程序調試工具,旨在提高小程序開發、測試效率的工具庫
功能介紹:
主要功能包括環境切換、身份Mock、應用信息獲取、位置模擬、緩存管理、掃一掃、H5跳轉、更新版本等。工具部分頁面如下圖所示:
目前已經在 GitHub 上開源(歡迎 issue):https://github.com/jdlfe/minidebug

物流風格的小程序可視化拖拽平台(規劃中)

京東商城已經實現了小程序可視化拖拽平台:https://ling.jd.com/atom/cms/pc/06599

結語:

Taro V3.0.0 目前支持 React、Nerv、Vue 三類框架,在未來 Taro 將開放拓展能力,使得開發者可以通過 Taro 拓展更多的框架支持,(比如:適配 Flutter 將成為可能 )。目前Taro框架完善社區活躍,即使沒有多端需求,僅用 Taro 開發 H5 也是個不錯的選擇(未來可以 0 成本接入小程序平台),想了解更多 Taro 3.0 實踐經驗歡迎線下交流。