Frontend Development 12 min read

Vue to React Component Conversion Using Babel AST

The article describes a pipeline that converts a Vue component into a React component by parsing the template, script and style with vue‑template‑compiler and Babel, traversing the AST to map Vue data, props, computed, methods and lifecycle hooks to React state, defaultProps and lifecycle methods, and generating JSX from directives such as v‑if, v‑for and event bindings, thereby reducing rewrite effort and supporting targets.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Vue to React Component Conversion Using Babel AST

The front‑end ecosystem evolves quickly, and teams often need to reuse components across different DSLs such as Taobao's React/Rax and Xianyu's Vue/Weex. Converting an existing Vue component into a React component can be achieved by a compiler‑based approach.

Babel’s three‑step workflow – parse (source to AST), transform (AST manipulation), and generate (AST back to code) – provides the core mechanism for this conversion.

The process starts by separating a Vue single‑file component into template , script and style using vue-template-compiler . The template is compiled to a Vue AST, while the script is parsed with @babel/parser . Traversal of the script AST via @babel/traverse identifies Vue‑specific options (data, props, computed, methods, lifecycle hooks) and rewrites them into their React equivalents using @babel/types . Finally, @babel/generator emits the transformed JavaScript.

Key mappings include:

Vue data → React state (class property state = { … } )

Vue props → React defaultProps and propTypes

Vue methods → class methods

Vue computed → getter functions or derived state

Lifecycle hooks: created → componentWillMount , mounted → componentDidMount , updated → componentDidUpdate , beforeDestroy → componentWillUnmount

Template directives are also translated to JSX:

v‑if becomes a conditional expression {condition && }

v‑else becomes a ternary expression {condition ? : }

v‑for is mapped to Array.map in JSX

Event binding @click → onClick , attribute style → className , and dynamic bindings are wrapped in curly braces.

An example of the generated React component:

import { createElement, Component, PropTypes } from 'react';
import './index.css';

export default class Mod extends Component {
  static defaultProps = { title: 'title' };
  static propTypes = { title: PropTypes.string };
  state = { show: true, name: 'name' };

  componentDidMount() {
    const { name } = this.state;
    console.log(name);
  }

  handleClick() {}

  render() {
    const { title } = this.props;
    const { show, name } = this.state;
    const { handleClick } = this;
    return (
{title}
{show &&
{name}
}
);
  }
}

The approach has been applied to dozens of Vue components in production, dramatically reducing manual rewrite effort. Future work aims to extend the pipeline to other cross‑platform scenarios such as mini‑programs, where platform‑specific APIs and components must be considered.

ASTReactBabelVueComponent Conversion
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.