Running React Code in Mini Programs with Taro: Compilation vs Runtime Approaches
Unlike Taro 1/2, which compiles React code into native mini‑program files through a complex Babel‑based pipeline, Taro 3 runs the original React source at runtime by injecting a lightweight simulated DOM/BOM layer, simplifying development but adding a performance‑overhead that is mitigated with pre‑rendering and virtual lists.
In this article we explore the problem of how React code can run on mini‑program platforms. Two main strategies are discussed:
Compile React (or Vue) source code into the native mini‑program files (WXML, WXSS, JSON, etc.). This is the approach taken by Taro 1/2, but it requires a heavy compilation step and separate handling for each framework.
Execute the original React code directly in the mini‑program environment by providing a simulated DOM/BOM layer. This is the core idea of Taro 3.
We first look at the Taro 1/2 architecture, which consists of a compile‑time phase and a runtime phase.
Compile‑time
The Taro source is parsed with babel‑parser , transformed into an abstract syntax tree (AST), modified via babel‑types , and finally generated into target code with babel‑generate . The most complex part is JSX compilation, which Taro handles by exhaustive pattern matching.
// before compilation
import Taro, { Component } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import './index.scss'
export default class Index extends Component {
config = { navigationBarTitleText: '首页' }
componentDidMount () {}
render () {
return (
Hello world!
)
}
}
// after compilation
import { BaseComponent, createComponent } from '@tarojs/taro-weapp'
class Index extends BaseComponent {
// ...
_createDate(){ /* process state and props */ }
}
export default createComponent(Index)After compilation the React render method disappears; the runtime uses BaseComponent and createComponent to bridge to the mini‑program.
The drawbacks of this approach are:
Incomplete JSX support – exhaustive matching cannot cover every possible syntax.
No source‑map support, making debugging difficult.
High maintenance cost due to the complex, fragmented compilation code.
Taro 3 Runtime
Taro 3 adopts an interpretive architecture. It injects a lightweight DOM/BOM implementation into the mini‑program and lets the original React (or Vue) code run unchanged.
Key components of the simulated environment:
TaroEventTarget – implements addEventListener / removeEventListener .
TaroNode – provides appendChild , insertBefore , etc.
TaroElement – handles attributes, styles, and event dispatch.
TaroRootElement – converts the virtual DOM tree into the mini‑program data structure via enqueueUpdate .
Webpack’s ProvidePlugin is used to inject the simulated globals into the mini‑program logic layer:
plugin.providerPlugin = getProviderPlugin({
window: ['@tarojs/runtime', 'window'],
document: ['@tarojs/runtime', 'document'],
navigator: ['@tarojs/runtime', 'navigator'],
requestAnimationFrame: ['@tarojs/runtime', 'requestAnimationFrame'],
cancelAnimationFrame: ['@tarojs/runtime', 'cancelAnimationFrame'],
Element: ['@tarojs/runtime', 'TaroElement'],
SVGElement: ['@tarojs/runtime', 'SVGElement'],
MutationObserver: ['@tarojs/runtime', 'MutationObserver'],
history: ['@tarojs/runtime', 'history'],
location: ['@tarojs/runtime', 'location'],
URLSearchParams: ['@tarojs/runtime', 'URLSearchParams'],
URL: ['@tarojs/runtime', 'URL']
})The host configuration required by react‑reconciler is implemented in taro‑react . Important callbacks include:
createInstance – creates a simulated element via document.createElement .
createTextInstance – creates a text node.
appendInitialChild / appendChild – delegate to the simulated DOM.
finalizeInitialChildren – registers event listeners by calling updateProps .
commitUpdate – updates properties and events using updatePropsByPayload .
Event handling works by converting React event names to the mini‑program equivalents, registering them on the simulated TaroEventTarget , and finally dispatching through dom.dispatchEvent during runtime.
Template Generation
Because mini‑programs cannot create nodes dynamically, Taro generates static WXML templates that are recursively invoked to render the virtual DOM tree. The build process produces a base.wxml file containing a hierarchy of <template> blocks, and each page imports this base template.
// base.wxml (excerpt)
// page index.wxmlSummary
Taro 3 moves from a heavy compile‑time transformation to a lightweight runtime simulation, allowing developers to write mini‑programs with familiar front‑end frameworks such as React, Vue, or even jQuery. While this brings flexibility, it also introduces performance overhead due to the extra abstraction layer. Taro mitigates this with features like pre‑rendering and virtual lists.
HelloTech
Official Hello technology account, sharing tech insights and developments.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.