Skip to content
目录

04 — 框架层:React / Solid 等与 Reconciler

1. React:taro-react = react-reconciler + 类 DOM

@tarojs/taro-react 使用官方 react-reconciler,在 hostConfig.createInstance 里调用 document.createElement(来自 @tarojs/runtime,非浏览器 document):

49:56:packages/taro-react/src/reconciler.ts
createInstance (type, props: Props, _rootContainerInstance: any, _hostContext: any, internalInstanceHandle: Fiber) {
    const element = document.createElement(type)

    precacheFiberNode(internalInstanceHandle, element)
    updateFiberProps(element, props)

    return element
  },

设计原因

  • 复用 React 的 Fiber 调度、并发特性、Hooks 等完整语义;宿主侧只需实现 类 DOM 接口(createElement、appendChild、commitUpdate…)。
  • precacheFiberNode / updateFiberProps 维护 Fiber ↔ TaroElement 映射与 props 缓存,便于事件与更新对齐。

finalizeInitialChildren 里对表单控件 defaultValue / defaultChecked 的处理,注释写明是为了 在 Page 初始化后立刻从 dom 读取 时行为正确:

60:71:packages/taro-react/src/reconciler.ts
finalizeInitialChildren (dom, type: string, props: any) {
    let newProps = props
    if (dom instanceof FormElement) {
      const [defaultName, defaultKey] = ['switch', 'checkbox', 'radio'].includes(type) ? ['checked', 'defaultChecked'] : ['value', 'defaultValue']
      if (props.hasOwnProperty(defaultKey)) {
        newProps = { ...newProps, [defaultName]: props[defaultKey] }
        delete newProps[defaultKey]
      }
    }

    updateProps(dom, {}, newProps) // 提前执行更新属性操作,Taro 在 Page 初始化后会立即从 dom 读取必要信息

2. Reconciler 实例化

文件末尾:

185:204:packages/taro-react/src/reconciler.ts
const TaroReconciler = Reconciler(hostConfig)

if (process.env.NODE_ENV !== 'production') {
  const foundDevTools = TaroReconciler.injectIntoDevTools({
    bundleType: 1,
    version: '18.0.0',
    rendererPackageName: 'taro-react'
  })

要点:DevTools 注入说明 Taro 在 dev 下尽量对齐 React 18 调试体验(版本号随上游升级可能变化,以源码为准)。

3. Solid:solid-js/universal + 独立 reconciler 包

Solid 在 非 Web 时走 babel-plugin-transform-solid-jsxgenerate: 'universal',并把 moduleName 指到 @tarojs/plugin-framework-solid/dist/reconciler

63:75:packages/babel-preset-taro/index.js
} else if (isSolid) {
    const solidOptions = {}
    if (process.env.TARO_PLATFORM !== 'web') {
      Object.assign(solidOptions, {
        moduleName: '@tarojs/plugin-framework-solid/dist/reconciler',
        generate: 'universal',
        uniqueTransform: true,
      })
    }
    presets.push([
      require('babel-plugin-transform-solid-jsx'),
      solidOptions,
    ])
  }

@tarojs/taro-framework-solid 内用 createRenderer 对接 TaroNode(与 React 路线不同:Solid 是细粒度响应式 + universal renderer)。

4. Vue3

Vue3 在 Webpack 路径下使用 @vue/babel-plugin-jsx + @babel/preset-typescript 的 overrides 处理 .vue(见 babel-preset-taro/index.js)。运行时侧依赖 @vue/runtime-dom 的抽象与 Taro 提供的 DOM 层(具体在 taro-runtime 与 framework 包中协作)。

5. 平台对 Reconciler 的「合并」

各小程序 platform-*runtime.ts 中通常:

ts
import { mergeReconciler } from '...'
mergeReconciler(hostConfig)

生命周期补丁、混合开发数据传输 等注入(见 03 文档 hostConfig 示例)。插件 @tarojs/plugin-inject 同样提供 hostConfig,用于业务侧扩展宿主行为。

6. 小结

框架接入方式关键点
Reactreact-reconcilerdocument.createElement 实为 Taro DOM
Solidsolid-js/universal + babel jsxmoduleName 指向 Taro reconciler 构建产物
Vue3compiler-dom + runtimeBabel/Vite 分支处理 TS/SFC

参考资料

MIT License.