Skip to content

Commit f46592c

Browse files
committed
feat: add interop mode
1 parent ac494d1 commit f46592c

File tree

9 files changed

+129
-31
lines changed

9 files changed

+129
-31
lines changed

packages/babel/src/index.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@ export type Options = {
1414
delegateEventSet: Set<string>
1515
preambleMap: Map<string, string>
1616
preambleIndex: number
17-
roots: { node: JSXElement | JSXFragment; source: string }[]
18-
compile?: CompilerOptions
17+
roots: {
18+
node: JSXElement | JSXFragment
19+
source: string
20+
inVaporComponent: boolean
21+
}[]
22+
opts: {
23+
interop?: boolean
24+
compile?: CompilerOptions
25+
}
1926
}
2027

2128
export default (): {
@@ -47,6 +54,18 @@ export default (): {
4754
state.roots.push({
4855
node: path.node,
4956
source: path.getSource(),
57+
inVaporComponent: !state.opts.interop
58+
? true
59+
: (
60+
path.findParent(
61+
({ node }) =>
62+
node.type === 'CallExpression' &&
63+
node.callee.type === 'Identifier' &&
64+
['defineVaporComponent', 'defineComponent'].includes(
65+
node.callee.name,
66+
),
67+
) as any
68+
)?.node.callee.name === 'defineVaporComponent',
5069
})
5170
}
5271
}

packages/babel/src/transform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ export const transformJSX: VisitNodeFunction<
1313
if (isJSXElement(path.parent)) return
1414

1515
const root = state.roots.shift()
16-
if (!root) return
16+
if (!root || !root.inVaporComponent) return
1717

1818
const isTS = state.filename?.endsWith('tsx')
1919
let { code, helpers, preamble, map } = compile(root.node, {
2020
isTS,
2121
filename: state.filename,
2222
sourceMap: true,
2323
source: ' '.repeat(root.node.start || 0) + root.source,
24-
...state?.compile,
24+
...state.opts.compile,
2525
})
2626

2727
helpers.forEach((helper) => state.importSet.add(helper))

packages/babel/test/interop.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { transformSync } from '@babel/core'
3+
import jsx from '../src/index'
4+
5+
describe('transform', () => {
6+
test('transform multiple components', () => {
7+
const { code } = transformSync(
8+
`const A = defineComponent(() => {
9+
defineVaporComponent(() => <div />)
10+
return () => <div />
11+
})
12+
const B = defineVaporComponent(() => {
13+
const C = defineComponent(() => <div />)
14+
const D = <div />
15+
return <div />
16+
})`,
17+
{
18+
filename: 'test.tsx',
19+
plugins: [[jsx, { interop: true }]],
20+
},
21+
)!
22+
expect(code).toMatchInlineSnapshot(`
23+
"import { template as _template } from 'vue';
24+
const _t00 = _template("<div></div>", true);
25+
const A = defineComponent(() => {
26+
defineVaporComponent(() => (() => {
27+
const n0 = _t00();
28+
return n0;
29+
})());
30+
return () => <div />;
31+
});
32+
const B = defineVaporComponent(() => {
33+
const C = defineComponent(() => <div />);
34+
const D = (() => {
35+
const n0 = _t00();
36+
return n0;
37+
})();
38+
return (() => {
39+
const n0 = _t00();
40+
return n0;
41+
})();
42+
});"
43+
`)
44+
})
45+
})

packages/unplugin/src/core/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function transformVueJsxVapor(
1717
) {
1818
const result = transformSync(code, {
1919
plugins: [
20-
[jsx, { compile: options?.compile }],
20+
[jsx, { compile: options?.compile, interop: options?.interop }],
2121
id.endsWith('.tsx')
2222
? [babelTypescript, { isTSX: true, allowExtensions: true }]
2323
: null,

packages/unplugin/src/index.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,31 @@ export const unpluginFactory: UnpluginFactory<Options | undefined> = (
99
) => {
1010
return [
1111
plugin(options, meta),
12-
{
13-
name: 'unplugin-esbuild',
14-
transformInclude: createFilter(
15-
options?.include || /\.[jt]sx$/,
16-
options?.exclude,
17-
),
18-
transform(code, id) {
19-
return transformWithEsbuild(code, id, {
20-
target: 'esnext',
21-
charset: 'utf8',
22-
minify: false,
23-
minifyIdentifiers: false,
24-
minifySyntax: false,
25-
minifyWhitespace: false,
26-
treeShaking: false,
27-
keepNames: false,
28-
supported: {
29-
'dynamic-import': true,
30-
'import-meta': true,
12+
options.interop
13+
? { name: 'interop' }
14+
: {
15+
name: 'unplugin-esbuild',
16+
transformInclude: createFilter(
17+
options?.include || /\.[jt]sx$/,
18+
options?.exclude,
19+
),
20+
transform(code, id) {
21+
return transformWithEsbuild(code, id, {
22+
target: 'esnext',
23+
charset: 'utf8',
24+
minify: false,
25+
minifyIdentifiers: false,
26+
minifySyntax: false,
27+
minifyWhitespace: false,
28+
treeShaking: false,
29+
keepNames: false,
30+
supported: {
31+
'dynamic-import': true,
32+
'import-meta': true,
33+
},
34+
})
3135
},
32-
})
33-
},
34-
},
36+
},
3537
]
3638
}
3739

packages/unplugin/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export interface Options {
55
// define your plugin options here
66
include?: FilterPattern
77
exclude?: FilterPattern
8+
interop?: boolean
89
compile?: CompilerOptions
910
}

playground/main.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { createVaporApp } from 'vue'
1+
import { createApp, vaporInteropPlugin } from 'vue'
22

33
const modules = import.meta.glob<any>('./src/*.tsx')
44
const mod = (
55
modules[`./src${location.pathname}.tsx`] || modules['./src/App.tsx']
66
)()
77

88
mod.then(({ default: mod }) => {
9-
const app = createVaporApp(mod)
10-
app.mount('#app')
9+
const app = createApp(mod)
10+
app.use(vaporInteropPlugin).mount('#app')
1111

1212
// @ts-expect-error
1313
globalThis.unmount = () => {

playground/src/interop.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { defineComponent, defineVaporComponent, ref } from 'vue'
2+
3+
const VaporComp = defineVaporComponent(
4+
(props) => {
5+
return (
6+
<div>
7+
Vapor Component:
8+
{props.model}
9+
</div>
10+
)
11+
},
12+
{ props: ['model'] },
13+
)
14+
15+
const Comp = (props) => <div>Virtual Dom Component:{props.model}</div>
16+
17+
export default defineComponent(() => {
18+
const model = ref('')
19+
return () => [
20+
<input v-model={model.value}></input>,
21+
<Comp model={model.value}></Comp>,
22+
<VaporComp model={model.value} />,
23+
]
24+
})

playground/vite.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { defineConfig } from 'vite'
22
import Inspect from 'vite-plugin-inspect'
33
import VueJsxVapor from 'unplugin-vue-jsx-vapor/vite'
4+
import VueJsx from '@vitejs/plugin-vue-jsx'
45

56
export default defineConfig({
6-
plugins: [VueJsxVapor(), Inspect()],
7+
plugins: [
8+
VueJsxVapor({
9+
interop: true,
10+
}),
11+
VueJsx(),
12+
Inspect(),
13+
],
714
})

0 commit comments

Comments
 (0)