Skip to content

Support custom JSX package #78

@leonardoraele

Description

@leonardoraele

Description

Right now, the plugin always transforms jsx expressions into React.createElement calls in classic mode, and always imports jsx from react/jsx-runtime in automatic runtime. This makes it impossible to use custom jsx packages.

Suggested solution

In classic runtime, the this object to which createElement() calls are made should be configurable; and in automatic runtime, the package from which jsx is imported should be configurable.

Example: (automatic runtime)

// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react({
    jsxPackage: 'my-jsx-package', // New proposed option
  })],
})
// Input (test.jsx)
export default Test() {
  return <div class="header">Hello World</div>
}
// Output
import { jsx as _jsx } from 'my-jsx-package/jsx-runtime' // imported from custom package instead of 'react'

export default Test() {
  return _jsx('div', { class: 'header' }, 'Hello World')
}

Example (classic runtime)

// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react({
    jsxRuntime: 'classic',
    jsxPragma: 'h', // New proposed option
    jsxPragmaFragment: 'h.fragment', // New proposed option
  })],
})
// Input (test.jsx)
import { h } from 'custom-jsx' // Instead of `import React from 'react'`

export default Test({ message }) {
  return (
    <>
      <div>Hello World</div>
      <div>{ message }</div>
    </>
  )
}
// Output
import { h } from 'custom-jsx'

export default Test({ message }) {
  return h(h.fragment, null, [
    h('div', null, 'Hello World'),
    h('div', null, message)
  ])
}

Alternative

The current alternative is to use classic runtime and manipulate the imports in a way that mimics react API.

Example:

// custom-jsx-wrapper.js
import { h } from 'custom-jsx'

export default { createElement: h, Fragment: h.fragment }
// test.jsx
import React from './custom-jsx-wrapper.js'

export default Test() {
  return <div>Hello World</div>
}

Additional context

This feature is supported by babel-plugin-transform-react-jsx, through importSource, pragma, and pragmaFrag options.

Doc:
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx.html#importsource

Validations

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions