5

随便写写 Taro 解析

 2 years ago
source link: https://zwkang.com/?p=914
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

由于工作原因,需要定制化 Taro 功能实现某些自定义功能。
所以对 Taro 原理以及源码有一点了解。

但经过我 2021 年的面试经历来看,大家并不在意类似 Taro 类型框架的原理。

但 Taro 框架,我理清源码后发现,其在国内开源的作品里,应该算是较好的一小撮了。

由于工作原因,我们的应用只有设计 H5 / 小程序 双端兼容。
在这个前提下我来讲讲 Taro 的事情。


为什么我会觉得 Taro 是那么一小撮呢?

  1. 打磨时间较久,社区有一定响应速度。
  2. 完善的 startup project 方式以及 contribute 方式,方便社区人员参与。
  3. 完善的单元测试覆盖。(很少见,很良心)
  4. 开放的生态,Taro native 在 3.x 后甚至不是由 凹凸 团队负责实现开发的。本文二次编辑时,还仍然在积极接入适配 鸿蒙 生态。
  5. 良好的开发心态,及时汲取社区新的优秀实现,反馈到社区内。

但是可能我仍然觉得有一点不太好的地方。

  1. 没有杀手级的组件库配套。
  2. 社区 roadmap 没有提供,更多的参与者在 bug fix 而不是 feature contribute。
  3. 物料市场多少有点名存实亡。

本文并无全面细致的解析,源码级的代码阅读笔记并不打算开放。


Taro 1.x

原有的 Taro 版本是基于 Nerv JS 去做的适配。

是 React 代码 到 微信小程序代码的点对点转换。

(Nerv 特性使得编译后代码甚至可以兼容 ie8)

Taro3.x

分为 web端 / 小程序,适配兼容都是在 react-reconciler 里面,做 hostConfig ,然后不同的端使用不同的 document object 调度

web 端上的话,reconciler 还是调用的 document 。在小程序上的话 reconciler 调用的是自己抽象的 Taro Document

export const document = (isBrowser ? doc : createDocument()) as TaroDocumentInstance

web端 不同的东西其实相对较少

  1. 会根据小程序配置文件,梳理路由打包,这块是使用的webpack loader 来做的这块事情(在主 APP 文件入口增加个个路由文件的 require,从而使得打包文件将其识别为chunk进行打包)
  2. 自建路由,为了与小程序路由栈行为一致。(只是增加了个个页面的显示隐藏的调度)(所以一个应用可能在一个h5上有多个页面实例)
  3. __taroAppConfig 全局变量可以获得当前的所有配置信息
  4. eventCenter可以监听到每个routerChange的事件
  5. 多端的一些模版适配是依赖 ionic/stencil 来做适配的(web-components的方案)。所以如果我们要动态使用组件的时候需要使用 applyPlugin 一下,不然动态组件无法使用。(这块loader帮我们做好了)

小程序端的打包内容很繁琐很多,但是完全可以跳过,因为只是生成目标的运行模式而已!核心只要管setData的调度。

Taro的enqueueUpdate

Taro解决了一部分setData频率的问题,在你每次setState的时候实际上会去做一个简单的调度,再统一setData处理!

在小程序上的调度完全来自于enqueueUpdate

截图的 Taro 小程序 Data

这是一个我们在小程序的page Data

我们可以看到里面完全没有我们应用的数据,例如没有我们应用实际的state

这里记载的大多数是一个个vnode的data(也就是一个节点应该长啥样子)

这里的字段含义解释一下
(我想这里缩写是可能尽可能让每一次setData的内容更小。)

Container = 'container',
Childnodes = 'cn',
Text = 'v',
NodeType = 'nt',
NodeName = 'nn',

// Attrtibutes
Style = 'st',
Class = 'cl',
Src = 'src'

其中这里uid还有一些别的功能

例如 在Taro document上实现eventTarget,包括getElementById也是通过uid来查找的。

每一次创建的时候会将一个uid 传入一个eventSource的set中保管(每一次会将当前的一个node节点set进去)。

调用getElementById则是通过去eventSource里面get一个id出来

每个页面路由的pageID是指向路由路径的。

数据的消费场景
这块数据的消费主要有两种场景

  1. 可递归组件
  2. 不可递归组件
    1. 有限制迭代

这块的模版在小程序会预先生成。在bundle中的 base.wxml 内。

小程序所有的setData都是在一个page Ctx下做的。
除非你单独处理,用customView来做。(可以做到局部刷新)
否则的话这块全是交由page Context统一setData

各端小程序其实大同小异,核心可能仅仅在一些tag 或者是attribute名有区别而已。

Taro在这方面也做了一层bundle小程序的抽象

https://taro-docs.jd.com/taro/docs/platform-plugin-template

让你可以做到 你仅仅只需要改变一个Adapter 上的属性就可以做到平台的扩展,核心是因为小程序的模式大同小异。

而Taro把这层code-generator 抽象了。(在后面添加更多平台时,基本上构建层模版是固定的,分发到各自平台的细节实现上。)

说多一嘴reconciler

Taro在原有的模式下扩展了hide 和 show方法

在不同端的reconciler 调用方法有所差异。

在web端可能就是调用真实dom上的一个insertBefore

在小程序端上可能就是调整整个data的一些属性,例如 当前为 x.[2] 调整为x.[3], 调用一个enqueueUpdate Path来setData到小程序上更新。(不过这里批量化调整的话会使用hydrate去做)

Taro在工程化上做的东西

  1. 样式适配的策略

    Taro 是使用postcss去做样式适配的,可以根据实际个人情况定义designWidth去设置

  2. Taro cli 底层其实自建了一个类似 yeoman-template 的模式去做用户自定义模版这块的东西

  3. Taro cli 每一个打包模式/命令 都抽象成为可插拔的plugin了,这块的调度则是使用Tapable去做的。

  4. 推荐的同构适配,依赖文件后缀名。这块则是通过enhance-resolve来自定义了resolve的一些方案,会根据你当前打包的flag 判断platform来优先resolve文件。

  5. 一些开箱即用的配置 cssnano terser uglify

etc...

小程序优化方案

小程序代码包下载的时候,尽可能让代码包要小一些。

(分包,图片cdn,代码打压缩,公共模块提取,避免无用依赖,静态资源尽可能缓存)

代码运行时候

避免节点过多,避免脚本阻塞过久。

setData的频率与数据量大小。

  1. 本文只是列举了大概阅读的一些心得,方便日后根据关键字于代码中得到锚点。
  2. Taro 是一个很不错的框架,大家有兴趣完全可以阅读,完全不亏。

Contact Me

all encode by base64

  • Email: a2FuZzk1NjMwQGdtYWlsLmNvbQ==
  • QQ: OTA3NzQ3ODc0QHFxLmNvbQo=

转载需注明出处与作者

否则将被视为侵权

Reprinting must indicate the source and author

Otherwise it will be regarded as infringement

Comments

发表评论 取消回复

邮箱地址不会被公开。 必填项已用*标注

评论

名称 *

电子邮件 *

站点

在此浏览器中保存我的姓名、电子邮件和站点地址。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK