Taro – 多端開發框架
Taro 是什麼?
Taro 是由京東 – 凹凸實驗室打造的一套遵循 React 語法規範的多端統一開發框架。
現如今市面上端的形態多種多樣,Web、App 端(React Native)、微信小程式等各種端大行其道,當業務要求同時在不同的端都要求有所表現的時候,針對不同的端去編寫多套程式碼的成本顯然非常高,這時候只編寫一套程式碼就能夠適配到多端的能力就顯得極為需要。
使用 Taro,我們可以只書寫一套程式碼,再通過 Taro 的編譯工具,將原始碼分別編譯出可以在不同端(微信小程式、H5、App 端等)執行的程式碼。同時 Taro 還提供開箱即用的語法檢測和自動補全等功能,有效地提升了開發體驗和開發效率。
Taro 能提供什麼?
一次編寫,多端執行
既然是一個多端解決方案,Taro 最重要的能力當然是寫一套程式碼輸出多端皆可執行的程式碼。目前 Taro 已經支援一套程式碼同時生成 H5 和小程式,App端(React Native)端也即將支援,同時諸如快應用等端也將得到支援。
同時 Taro 也已經投入到了生產環境使用,目前已經支撐了一個 3 萬行程式碼小程式 TOPLIFE 的開發和部分京東購物小程式,未來也將會支撐更多的京東核心業務小程式。
現代前端開發流程
和微信自帶的小程式框架不一樣,Taro 積極擁抱社群現有的現代開發流程,包括但不限於:
- NPM 包管理系統
- ES6+ 語法
- 自由的資源引用
- CSS 前處理器和後處理器(SCSS、Less、PostCSS)
對於微信小程式的編譯流程,我們從 Parcel 得到靈感,自研了一套打包機制將 AST 不斷傳遞,因此程式碼分析的速度得到了很大的提高。一臺 2015 年 的 15寸 RMBP 在編譯上百個元件時僅需要大約 15 秒左右。
和 React 完全一致的 API 和元件化系統
在 Taro 中,你不用像小程式一樣區分什麼是 App
元件,什麼是 Page
元件,什麼是 Component
元件,Taro 全都是 Component
元件,並且和 React 的生命週期完全一致。可以說,一旦你掌握了 React,那就幾乎掌握了 Taro。而學習 React 的資源也幾乎是汗牛充棟,完全不用擔心學不會。
Taro 和 React 一樣,同樣使用宣告式的 JSX 語法。相比起字串的模板語法,JSX 在處理精細複雜需求的時候會更得心應手。
// 一個典型的 Taro 元件
import Taro, { Component } from `@tarojs/taro`
import { View, Button } from `@tarojs/components`
export default class Home extends Component {
constructor (props) {
super(props)
this.state = {
title: `首頁`,
list: [1, 2, 3]
}
}
componentWillMount () {}
componentDidMount () {}
componentWillUpdate (nextProps, nextState) {}
componentDidUpdate (prevProps, prevState) {}
shouldComponentUpdate (nextProps, nextState) {
return true
}
add = (e) => {
// dosth
}
render () {
const { list, title } = this.state
return (
<View className=`index`>
<View className=`title`>{title}</View>
<View className=`content`>
{list.map(item => {
return (
<View className=`item`>{item}</View>
)
})}
<Button className=`add` onClick={this.add}>新增</Button>
</View>
</View>
)
}
}
良好的開發效率和體驗
鑑於 Taro 的語法和 React 完全一樣,因此編輯器/IDE 能夠對 Taro 的支援和 React 是幾乎一樣的。現代的編輯器預設都對 JSX 進行了支援,如果沒有,找一個外掛也是非常容易的事情。但畢竟我們做 Taro 就是為了提升開發效率和開發體驗,而真正使用 Taro 的人就是我們自己或正坐在我們旁邊的同事。因此在此基礎上,我們又對 Taro 開發體驗進行了進一步加強。
自定義 ESLint 規則
我們之前提到過,當學會了 React,其實也差不多會 Taro 了。其中很重要的一個原因就是我們對 Taro 不支援的語法和特性單獨寫了 ESLint 規則:開發者只管寫程式碼,寫到不支援的語法/特性編輯器會報錯,並給出報錯資訊和一個文件地址描述。
型別安全和執行時檢測
JSX 的本質就是 JavaScript 的語法增強,所以例如沒有 import
元件等語法錯誤在編譯期就能發現。開發者也可以使用 TypeScript
或 Flow
來對程式碼的可靠性進一步增強,或使用 PropsType
在執行時進一步保障程式碼的魯棒性。
高效的自動補全和 ES6+ 語法
Taro 的所有 API(包括微信小程式等端能力介面)都有智慧的提醒和自動補全,包括介面的引數和返回值。
Taro 的設計思路
我們的初心就是做一款能夠適配多端的解決方案,結合業務場景、技術選型和前端歷史發展程式,我們的解決方案必須滿足下述要求:
- 程式碼多端複用,不僅能執行在時下最熱門的 H5、微信小程式、React Native,對其他可能會流行的端也留有餘地和可能性。
- 完善和強大的元件化機制,這是開發複雜應用的基石。
- 與目前團隊技術棧有機結合,有效提高效率。
- 學習成本足夠低
- 背後的生態強大
同時滿足這幾個需求並不容易,在我們經過充分地調研和思考之後發現只有 React 體系能夠滿足我們的需求。而對於微信小程式而言,使用 React 完全沒有辦法進行開發——直到我們從 codemod得到靈感:
在一個優秀且嚴格的規範限制下,從更高抽象的視角(語法樹)來看,每個人寫的程式碼都差不多。
也就是說,對於微信小程式這樣不開放不開源的端,我們可以先把 React 程式碼分析成一顆抽象語法樹,根據這顆樹生成小程式支援的模板程式碼,再做一個小程式執行時框架處理事件和生命週期與小程式框架相容,然後把業務程式碼跑在執行時框架就完成了小程式端的適配。
對於 React 已經支援的端,例如 Web、React Native 甚至未來的 React VR,我們只要包一層元件庫再做些許樣式支援即可。鑑於時下小程式的熱度和我們團隊本身的業務側重程度,元件庫的 API 是以小程式為標準,其他端的元件庫的 API 都會和小程式端的元件保持一致。
技術選型與權衡
在我們前面社群已經有多個優秀的框架以小程式為核心對多端適配進行了探索,我們將各個開發框架的主要特點和特性進行了對比並製成圖表。大家可以結合團隊技術棧、技術需求以及框架特點、特性進行選型和權衡。
結語
經過數個月的開發,Taro 從第一次 commit 到發展成包括 16 個包,十多位同學共同參與的大型專案。與此同時,Taro 也在生產環境支撐了數個複雜業務線上專案的開發,將來也會支撐更多的京東業務。
Taro 的技術方案和實現也根植於社群,我們也希望為技術社群的發展壯大貢獻一份自己的力量。秉持著京東凹凸實驗室長久以來開源、開放、共享的優良傳統,我們今天將 Taro 全部程式碼開源,為廣大開發者快速開發多端專案提供一整套技術解決方案。未來,我們也將繼續擴充 Taro 現有能力,支援更多端能力,繼續完善開發者體驗,提高開發者效率,幫助更多開發者,同時也從社群中汲取養分,讓 Taro 變得更加強大。
GitHub: github.com/nervjs/taro
如果你還沒聽過 Nerv,可以來這裡看看:nerv.aotu.io/
感謝您的閱讀,本文由 凹凸實驗室 版權所有。如若轉載,請註明出處:凹凸實驗室(aotu.io/notes/2018/…)