Skip to content

Commit e756c48

Browse files
committed
feat: vue-jsx support
1 parent 1a90b4e commit e756c48

File tree

16 files changed

+554
-13
lines changed

16 files changed

+554
-13
lines changed

packages/playground/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"outDir": "dist",
66
"allowJs": true,
77
"esModuleInterop": true,
8-
"baseUrl": "."
8+
"baseUrl": ".",
9+
"jsx": "preserve"
910
}
1011
}

packages/playground/vue-jsx/Comp.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineComponent, ref } from 'vue'
2+
3+
const Default = defineComponent(() => {
4+
const count = ref(3)
5+
const inc = () => count.value++
6+
7+
return () => (
8+
<button class="default-tsx" onClick={inc}>
9+
default tsx {count.value}
10+
</button>
11+
)
12+
})
13+
14+
export default Default

packages/playground/vue-jsx/Comps.jsx

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { defineComponent, ref } from 'vue'
2+
3+
export const Named = defineComponent(() => {
4+
const count = ref(0)
5+
const inc = () => count.value++
6+
7+
return () => (
8+
<button class="named" onClick={inc}>
9+
named {count.value}
10+
</button>
11+
)
12+
})
13+
14+
const NamedSpec = defineComponent(() => {
15+
const count = ref(1)
16+
const inc = () => count.value++
17+
18+
return () => (
19+
<button class="named-specifier" onClick={inc}>
20+
named specifier {count.value}
21+
</button>
22+
)
23+
})
24+
export { NamedSpec }
25+
26+
export default defineComponent(() => {
27+
const count = ref(2)
28+
const inc = () => count.value++
29+
30+
return () => (
31+
<button class="default" onClick={inc}>
32+
default {count.value}
33+
</button>
34+
)
35+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { editFile, isBuild, untilUpdated } from '../../testUtils'
2+
3+
test('should render', async () => {
4+
expect(await page.textContent('.named')).toMatch('0')
5+
expect(await page.textContent('.named-specifier')).toMatch('1')
6+
expect(await page.textContent('.default')).toMatch('2')
7+
expect(await page.textContent('.default-tsx')).toMatch('3')
8+
})
9+
10+
test('should update', async () => {
11+
await page.click('.named')
12+
expect(await page.textContent('.named')).toMatch('1')
13+
await page.click('.named-specifier')
14+
expect(await page.textContent('.named-specifier')).toMatch('2')
15+
await page.click('.default')
16+
expect(await page.textContent('.default')).toMatch('3')
17+
await page.click('.default-tsx')
18+
expect(await page.textContent('.default-tsx')).toMatch('4')
19+
})
20+
21+
if (!isBuild) {
22+
test('hmr: named export', async () => {
23+
editFile('Comps.jsx', (code) =>
24+
code.replace('named {count', 'named updated {count')
25+
)
26+
await untilUpdated(() => page.textContent('.named'), 'named updated 0')
27+
28+
// should not affect other components on the page
29+
expect(await page.textContent('.named-specifier')).toMatch('2')
30+
expect(await page.textContent('.default')).toMatch('3')
31+
expect(await page.textContent('.default-tsx')).toMatch('4')
32+
})
33+
34+
test('hmr: named export via specifier', async () => {
35+
editFile('Comps.jsx', (code) =>
36+
code.replace('named specifier {count', 'named specifier updated {count')
37+
)
38+
await untilUpdated(
39+
() => page.textContent('.named-specifier'),
40+
'named specifier updated 1'
41+
)
42+
43+
// should not affect other components on the page
44+
expect(await page.textContent('.default')).toMatch('3')
45+
expect(await page.textContent('.default-tsx')).toMatch('4')
46+
})
47+
48+
test('hmr: default export', async () => {
49+
editFile('Comps.jsx', (code) =>
50+
code.replace('default {count', 'default updated {count')
51+
)
52+
await untilUpdated(() => page.textContent('.default'), 'default updated 2')
53+
54+
// should not affect other components on the page
55+
expect(await page.textContent('.default-tsx')).toMatch('4')
56+
})
57+
58+
test('hmr: named export via specifier', async () => {
59+
// update another component
60+
await page.click('.named')
61+
expect(await page.textContent('.named')).toMatch('1')
62+
63+
editFile('Comp.tsx', (code) =>
64+
code.replace('default tsx {count', 'default tsx updated {count')
65+
)
66+
await untilUpdated(
67+
() => page.textContent('.default-tsx'),
68+
'default tsx updated 3'
69+
)
70+
71+
// should not affect other components on the page
72+
expect(await page.textContent('.named')).toMatch('1')
73+
})
74+
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<div id="app"></div>
2+
<script type="module" src="./main.jsx"></script>

packages/playground/vue-jsx/main.jsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createApp } from 'vue'
2+
import { Named, NamedSpec, default as Default } from './Comps'
3+
import { default as TsxDefault } from './Comp'
4+
5+
function App() {
6+
return (
7+
<>
8+
<Named />
9+
<NamedSpec />
10+
<Default />
11+
<TsxDefault />
12+
</>
13+
)
14+
}
15+
16+
createApp(App).mount('#app')
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "test-vue-jsx",
3+
"private": true,
4+
"version": "0.0.0",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"debug": "node --inspect-brk ../../vite/bin/vite"
9+
},
10+
"devDependencies": {
11+
"@vitejs/plugin-vue-jsx": "^1.0.0"
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const vueJsxPlugin = require('@vitejs/plugin-vue-jsx')
2+
3+
/**
4+
* @type {import('vite').UserConfig}
5+
*/
6+
module.exports = {
7+
plugins: [vueJsxPlugin()]
8+
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Plugin } from 'vite'
22

3-
declare function reactRefresh(): Plugin
3+
declare function createPlugin(): Plugin
44

5-
export = reactRefresh
5+
export = createPlugin

packages/plugin-react-refresh/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default exports
2424
/**
2525
* Transform plugin for transforming and injecting per-file refresh code.
2626
*
27-
* @type { () => import('vite').Plugin }
27+
* @returns {import('vite').Plugin}
2828
*/
2929
module.exports = function reactRefreshPlugin() {
3030
let shouldSkip = false

packages/plugin-vue-jsx/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/plugin-vue-jsx/README.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# @vitejs/plugin-vue-jsx
2+
3+
Provides optimized Vue 3 JSX support via [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next).
4+
5+
```js
6+
// vite.config.js
7+
import vueJsx from '@vitejs/plugin-vue-jsx'
8+
9+
export default {
10+
plugins: [vueJsx({
11+
// options are passed on to @vue/babel-plugin-jsx
12+
})]
13+
}
14+
```

packages/plugin-vue-jsx/index.d.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Plugin } from 'vite'
2+
3+
// https://github.com/vuejs/jsx-next/tree/dev/packages/babel-plugin-jsx#options
4+
export interface Options {
5+
transformOn?: boolean
6+
optimize?: boolean
7+
isCustomElement?: (tag: string) => boolean
8+
mergeProps?: boolean
9+
}
10+
11+
declare function createPlugin(options?: Options): Plugin
12+
13+
export default createPlugin

0 commit comments

Comments
 (0)