Vue3 + Vite 使用 JSX 的推荐方式

Recommended way to use JSX with Vue3 + Vite

我无法让 JSX 在官方 Vue3/Vite/JSX 脚手架中工作。 JSX 上的官方 Vue3 文档零提及如何让它工作 https://vuejs.org/guide/extras/render-function.html

这些是我采取的步骤

  1. npm init vue@latest
    搭建项目
    • 回答 YESAdd JSX Support?
    • 回答 NO 其他问题。
  2. 更改 App.vue 以便它使用 JSX render() 函数而不是 <template>
// App.vue

<script>
export default {
  render() {
    return (
      <div>
        Hello world.
      </div>
    );
  }
}
</script>
  1. 运行 npm run dev, 给我以下错误
X [ERROR] The JSX syntax extension is not currently enabled

    html:.../src/App.vue:8:6:
      8 │       <div>
        ╵       ^

  The esbuild loader for this file is currently set to "js" but it must be set to "jsx" to be able
  to parse JSX syntax. You can use "loader: { '.js': 'jsx' }" to do that.
  1. esbuild: { loader: { '.js': '.jsx' } } 添加到 vite.config.js
// vite.config.js

import { fileURLToPath, URL } from 'url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.declsv/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  esbuild: { loader: { '.js': '.jsx' } } // <--- Added this line
})
    再次
  1. 运行 npm run dev。与步骤 3 中的错误完全相同。

我认为问题出在您的组件格式上。检查 plugin-vue-jsxgithub page 为 Vite 中的 Vue 提供 JSX 支持

支持的模式:

import { defineComponent } from 'vue'

// named exports w/ variable declaration: ok
export const Foo = defineComponent({})

// named exports referencing variable declaration: ok
const Bar = defineComponent({ render() { return <div>Test</div> }})
export { Bar }

// default export call: ok
export default defineComponent({ render() { return <div>Test</div> }})

// default export referencing variable declaration: ok
const Baz = defineComponent({ render() { return <div>Test</div> }})
export default Baz

Non-supported 模式:

// not using `defineComponent` call
export const Bar = { ... }

// not exported
const Foo = defineComponent(...)

defineComponent 不仅对于 Vue 3 中的 JSX 是必需的(对于 TS 和智能感知也是必需的)所以请使用它。并删除 vite.config.js 的更改 - 它们不需要

另外不要忘记在 .vue 文件中指定正确的 lang 属性:

  • <script lang="jsx"> 用于纯 JS + JSX
  • <script lang="tsx"> TS + TSX

Working demo

我是这样做的:

vite.config.ts:

import { defineConfig } from 'vite'
import tsConfigPaths from 'vite-tsconfig-paths'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  plugins: [
    tsConfigPaths(),
    vueJsx()
  ]
})

App.tsx:

function render() {
  return <div>hello</div>
}

export default render

main.ts:

import { createApp } from 'vue'
import App from './App'

createApp(App).mount('#app')