最近在进行 Taro项目的升级,由 Taro1升级到 Taro3,但是细想一下一直都是在使用 Taro,却没有进行深入的了解,本篇文章就深入解析下

什么是 Taro? 为什么要用 Taro
在使用任何一种技术之前,都要了解这两个问题:是什么?为什么要用?
Taro是一个开放式跨端跨框架的解决方案,支持使用 React/Vue/Nerv等框架开发微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 小程序 / H5 / RN 等应用。 这么说可能不容易理解,简单来说就是代码一次编写,多端使用。现在市面上的小程序种类特别多,包括最火的微信小程序在内还有支付宝小程序、百度小程序、字节跳动等等,还有一些H5、RN等等应用,如果你的项目要在多端上线就不得不编写多套代码,Taro就是为此而生,使用 Taro编写一套代码就可以在多端使用,大大减少了成本。

第一个问题来了:为什么 Taro要采用 React的语法?
按照 Taro团队的说法,之所以选择 React要从设计 Taro的初衷说起,Taro团队认为 Taro框架应该是这样的:
- 代码多端复用
- 完善且强大的组件机制
- 学习成本低
- 背后生态强大
经过调研后Taro团队认为 React最符合要求,但是对于微信小程序而言,Raact完全没办法进行开发,那么第二个问题来了
如何完成React代码在小程序端的适配?
在讲解这一点之前需要理解几个概念:
- Babel: Babel是一款JS代码编译器,举例来说,一些 JS的高级语法,比如 ES6,有些浏览器是不支持的,但是在开发中我们又想去使用这些语法,这时就可以利用 Babel将ES6代码编译成浏览器可以运行的代码,这个代码转换的过程也就是计算机基础中的编译原理的过程:输入源代码 => 词法分析 => 语法分析 => 语义分析 => 转换 => 新代码生成
- 抽象语法树(AST): 什么是抽象语法树,网络上的解释过于笼统,按照我的理解,抽象语法树就是将编程语言的特定语法从源代码中剥离,仅仅关注源代码的结构和语意,这很重要。可以通过下面的截图感受下什么是 AST

了解上面的概念之后,上面的问题就有了思路:可以将React代码分析成抽象语法树,根据语法树小程序支持的模板代码,再做一个小程序运行时框架处理事件和生命周期与小程序框架兼容,然后把业务代码跑在运行时框架就完成了小程序端的适配
编译时使用babel-parser将react代码转换为抽象语法树,然后通过babel-types对抽象语法树进行修改,最后通过babel-generator将修改后的抽象语法树转换为小程序代码。这样的实现有以下几个缺点:
- 1· jsx支持程度不完美,Taro对jsx的适配是在编译时去实现的,但是jsx非常灵活,因此不能做到 100%的适配,Taro团队采用穷举的方式对jsx可能的写法进行一一适配,工作量巨大
- 2 不支持 source-map,Taro对源代码进行一系列的转换操作之后就不支持 source-map,用户调试很不方便
以上仅仅是设计思路,可以实现,但是还是有问题,仅仅将代码按照对应的语法规则转换,远远不够,因为不同的端会有自己的原生组件,端能力 api等等,代码转换过去可能不能直接执行。例如小程序中的普通容器是而 H5是
怎么弥补不同端的差异?
Taro的做法是定制一个统一的组件库标准,以及统一的 api标准,在不同的端依靠他们的语法和能力去实现这个组件库与api,同时还要为不同的端编写运行时框架。在书写代码的时候,只需要引入标准组件库 @tarojs/components 与运行时框架 @tarojs/taro ,代码经过编译之后,会变成对应端所需要的库。举个例子,在小程序端,Taro实现了 @tarojs/redux 这个库来作为小程序的 Redux 辅助库,并且以他作为基准库,它具有和 react-redux 一致的 API,在书写代码的时候,引用的都是 @tarojs/redux ,经过编译后,在 H5 端会替换成 nerv-redux(Nerv的 Redux 辅助库),在 RN 端会替换成 react-redux。这样就实现了 Redux 在 Taro 中的多端支持。

Taro1 与 Taro3
看完上面的内容相信你已经对 Taro有了一个初步的认知,从 Taro1 到 Taro3中间的数次迭代和更新此处不细说了,接下来着重解析这两个版本进行对比。
Taro1 与 Taro3的架构区别
Taro 1/2 属于编译型架构,主要通过对类 React 代码进行语法编译转换地方式,得到各个端可以运行的代码,再配合非常轻量的运行时适配,以及根据标准组件库、API 进行差异抹平,从而实现多端适配的目的,整体架构如下。

这样做的最直观的好处就是前面说到的,不再受限制与框架本身了,理论上来说,Taro不仅可以支持Vue和React,也能用jquery、Angular等等的库进行跨端开发。站在React的使用者角度:通过taro2和taro3两个项目开发经验来说还有一点最直观的感受,taro3中写JSX更加舒服了!其实就更加友好的支持JSX这一点,应该是顺理成章的,因为taro的架构其实就是无限接近于React的开发体验,适配的工作是通过运行时的BOM/DOM去完成的,而不是像之前版本一样,通过穷举 的方式对 JSX 的写法进行适配。
