SoFunction
Updated on 2025-04-05

Implementation of Vue3 JSX interpreter

In Vue 3, we can use JSX to write template code, which makes it easier for us to create components and put them together. In this article, we will discuss how to develop a Vue 3 JSX interpreter with native JavaScript so that we can write and use JSX code.

Step 1: What is JSX?

JSX is a JavaScript extension syntax used to declare the structure of UI components. JSX was originally introduced by React, but has now become part of many JavaScript frameworks, including Vue 3.

In Vue 3, we can use JSX instead of template syntax. For example, here is a Vue 3 component that uses template syntax:

<template>
  <div class="container">
    <h1>{{ title }}</h1>
    <p>{{ content }}</p>
  </div>
</template>

We can replace it with JSX:

import { defineComponent } from 'vue';

export default defineComponent({
  render() {
    return (
      <div class="container">
        <h1>{}</h1>
        <p>{}</p>
      </div>
    );
  },
  props: {
    title: String,
    content: String,
  },
});

As you can see in these two examples, JSX looks more like HTML code, but in fact it is JavaScript code. So we need an interpreter to convert JSX to JavaScript code so that we can run it in the browser.

Step 2: Parsing JSX

To parse JSX, we need to convert it into JavaScript code with the same structure. We will use a tool called Babel to help us accomplish this task. However, in this article, we will discuss how to manually parse JSX.

To manually parse JSX, we need to do the following:

  • Convert JSX to AST (Abstract Syntax Tree).
  • Iterate over the AST and convert it into equivalent JavaScript code.

Here is a simple JSX code example:

const element = <h1>Hello, world!</h1>;

We will convert it to the following AST:

{
  type: 'element',
  tagName: 'h1',
  attributes: {},
  children: [{
    type: 'text',
    value: 'Hello, world!'
  }]
}

To convert AST into equivalent JavaScript code, we can use a recursive function to iterate over AST. Here is an example implementation:

function generateCode(node) {
  if ( === 'element') {
    const props = ()
      .map(key => `${key}="${[key]}"`)
      .join(' ');

    const children = (generateCode).join('');

    return `createElement("${}", { ${props} }, ${children})`;
  }

  if ( === 'text') {
    return `"${}"`;
  }
}

In this example, we define a function called generateCode that takes a node as a parameter and converts it into equivalent JavaScript code. If the node type is an element, we use the createElement function to create the element and pass its child nodes to it. If the node type is text, we wrap it in quotes so that it can be passed as a string.

Here is how to use the generateCode function to convert our sample JSX code:

const element = &lt;h1&gt;Hello, world!&lt;/h1&gt;;
const code = generateCode(element);
(code); // Output:createElement("h1", {}, "Hello, world!")

Now we can convert JSX into equivalent JavaScript code.

Step 3: Create a Vue 3 JSX interpreter

Now that we have learned how to parse and convert JSX, let's start creating our own Vue 3 JSX interpreter.

First, we need to create a createElement function that takes tag names, attributes, and child elements and converts them into a Vue 3 VNode object. This is easy to implement, as follows:

function createElement(tagName, props, children) {
  return {
    type: 2,
    tag: tagName,
    props: props,
    children: (children) ? children : [children],
    shapeFlag: 4
  };
}

In this example, we define a function called generateCode that takes a node as a parameter and converts it into equivalent JavaScript code. If the node type is an element, we use the createElement function to create the element and pass its child nodes to it. If the node type is text, we wrap it in quotes so that it can be passed as a string.

Here is how to use the generateCode function to convert our sample JSX code:

const element = &lt;h1&gt;Hello, world!&lt;/h1&gt;;
const code = generateCode(element);
(code); // Output:createElement("h1", {}, "Hello, world!")

Now we can convert JSX into equivalent JavaScript code.

Next, we need to write a function that parses JSX code. The function should accept a JSX code string and return a JavaScript code string. This function should do the following:

  • Convert JSX code to AST.
  • Convert AST to JavaScript code string.
  • Wrap the code string in a function and return it.

Here is a possible implementation:

function parseJSX(code) {
  const ast = parse(code, {
    plugins: ['jsx']
  });

  const codeStr = generateCode([0].expression);

  return `function render() { return ${codeStr} }`;
}

In this implementation, we use @babel/parser to convert JSX code to AST. Then, we use the generatedCode function we defined earlier to convert AST to JavaScript code string. Finally, we wrap the code string in a function and return it.

Now that we have written a Vue 3 JSX interpreter, we can use it to write our Vue 3 components. Here is a simple example:

import { defineComponent } from 'vue';

const MyComponent = defineComponent({
  render() {
    const message = 'Hello, world!';

    return parseJSX(
      <div>
        <h1>{message}</h1>
        <p>This is a Vue 3 component written in JSX!</p>
      </div>
    );
  }
});

export default MyComponent;

In this example, we use the defineComponent function to define our components. In the render function, we define a variable called message and use the parseJSX function to render our JSX code. Note that we use message variables in our JSX code.

Summarize

In this article, we learned how to write a Vue 3 JSX interpreter using native JavaScript so that we can write Vue 3 components using JSX syntax. We learned how to parse and convert JSX code and created a function that generates equivalent JavaScript code. We then created a Vue 3 JSX interpreter using this function and showed how to use it to write Vue 3 components.

The Vue 3 JSX interpreter enables us to write Vue 3 components using more intuitive and readable syntax. At the same time, it can also improve our development efficiency and reduce the time to write a lot of duplicate code. It is worth noting that when using JSX, we need to keep the code readable and consistent and follow best practices.

This article covers implementation details and usage of the Vue 3 JSX interpreter and provides a complete example. If you are interested in Vue 3 and JSX, this article will provide you with a lot of useful information and inspiration.

Sample code for the complete Vue 3 JSX interpreter:

import { parse } from '@babel/parser';
import { generate } from '@babel/generator';

function generateCode(node) {
  if ( === 'JSXElement') {
    const tagName = ;
    const props = (attr => {
      const propName = ;
      const propValue = generate().code;
      return `${propName}: ${propValue}`;
    }).join(', ');
    const children = (child => generateCode(child)).join(', ');

    return `createElement("${tagName}", { ${props} }, ${children})`;
  } else if ( === 'JSXText') {
    return `"${}"`;
  }
}

function createElement(tagName, props, children) {
  return {
    type: 2,
    tag: tagName,
    props: props,
    children: (children) ? children : [children],
    shapeFlag: 4
  };
}

function parseJSX(code) {
  const ast = parse(code, {
    plugins: ['jsx']
  });

  const codeStr = generateCode([0].expression);

  return `function render() { return ${codeStr} }`;
}

export { createElement, parseJSX };

Example of usage:

import { defineComponent } from 'vue';
import { createElement, parseJSX } from './jsx';

const MyComponent = defineComponent({
  render() {
    const message = 'Hello, world!';

    return parseJSX(
      <div>
        <h1>{message}</h1>
        <p>This is a Vue 3 component written in JSX!</p>
      </div>
    );
  }
});

export default MyComponent;

In this example, we define a Vue 3 component called MyComponent and use the Vue 3 JSX interpreter in its render function. We define a variable called message and use it in our JSX code. Finally, we use the defineComponent function to export the component as the default module.

Using the Vue 3 JSX interpreter allows us to write Vue 3 components using more intuitive and readable syntax, while also improving our development efficiency.

This is the end of this article about the implementation of Vue3 JSX interpreter. For more related contents of Vue3 JSX interpreter, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!