diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap index b469ea52d..da9a78950 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap @@ -5,11 +5,12 @@ exports[`comile > bindings 1`] = ` import { template, setText } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setText(n0, undefined, count.value) }) -return root +return n0 + }" `; @@ -18,11 +19,12 @@ exports[`comile > directives > v-bind > simple expression 1`] = ` import { template, setAttr } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setAttr(n0, \\"id\\", undefined, id.value) }) -return root +return n0 + }" `; @@ -31,11 +33,12 @@ exports[`comile > directives > v-html > no expression 1`] = ` import { template, setHtml } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setHtml(n0, undefined, \\"\\") }) -return root +return n0 + }" `; @@ -44,11 +47,12 @@ exports[`comile > directives > v-html > simple expression 1`] = ` import { template, setHtml } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setHtml(n0, undefined, code.value) }) -return root +return n0 + }" `; @@ -57,11 +61,12 @@ exports[`comile > directives > v-on > simple expression 1`] = ` import { template, on } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { on(n0, \\"click\\", handleClick) }) -return root +return n0 + }" `; @@ -69,13 +74,14 @@ exports[`comile > directives > v-once 1`] = ` "import { template, children, insert, setText, setAttr } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() -const { 1: [n2],} = children(root) +const n0 = t0() +const { 1: [n2],} = children(n0) const n1 = document.createTextNode(msg.value) insert(n1, n0, 0 /* InsertPosition.FIRST */) setText(n1, undefined, msg.value) setAttr(n2, \\"class\\", undefined, clz.value) -return root +return n0 + }" `; @@ -84,11 +90,12 @@ exports[`comile > directives > v-text > no expression 1`] = ` import { template, setText } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setText(n0, undefined, \\"\\") }) -return root +return n0 + }" `; @@ -97,11 +104,12 @@ exports[`comile > directives > v-text > simple expression 1`] = ` import { template, setText } from 'vue/vapor' const t0 = template(\`
\`) export function render() { -const root = t0() +const n0 = t0() watchEffect(() => { setText(n0, undefined, str.value) }) -return root +return n0 + }" `; @@ -109,7 +117,8 @@ exports[`comile > static template 1`] = ` "import { template } from 'vue/vapor' const t0 = template(\`

hello

\`) export function render() { -const root = t0() -return root +const n0 = t0() +return n0 + }" `; diff --git a/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap index 4a4d7c6ce..fdf4d1cd9 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap @@ -3,8 +3,8 @@ exports[`fixtures 1`] = ` "import { defineComponent as _defineComponent } from 'vue' import { watchEffect } from 'vue' -import { template, insert, setText, on, setHtml } from 'vue/vapor' -const t0 = template(\`

Counter

Count:

Double:

once:

{{ count }}

\`) +import { template, children, insert, setText, on, setHtml } from 'vue/vapor' +const t0 = template(\`

Counter

Count:

Double:

once:

{{ count }}

\`) import { ref, computed } from 'vue' const html = 'HTML' @@ -19,7 +19,8 @@ const increment = () => count.value++ return (() => { -const root = t0() +const n8 = t0() +const { 1: [n0], 2: [n2], 3: [n4], 4: [n5], 6: [n6],} = children(n8) const n1 = document.createTextNode(count.value) insert(n1, n0) const n3 = document.createTextNode(double.value) @@ -39,7 +40,8 @@ on(n4, \\"click\\", increment) watchEffect(() => { setHtml(n5, undefined, html) }) -return root +return n8 + })(); } diff --git a/packages/compiler-vapor/__tests__/fixtures/counter.vue b/packages/compiler-vapor/__tests__/fixtures/counter.vue index c780b459d..d09cfd2e0 100644 --- a/packages/compiler-vapor/__tests__/fixtures/counter.vue +++ b/packages/compiler-vapor/__tests__/fixtures/counter.vue @@ -10,12 +10,14 @@ const html = 'HTML' diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index e2ed01b73..ff4c497ff 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -27,29 +27,32 @@ export function generate( vaporHelpers.add('template') } - // TODO multiple-template - code += `const root = t0()\n` - if (ir.children[0] && Object.keys(ir.children[0].children).length) { - code += `const {${genChildren(ir.children[0].children)}} = children(root)\n` - vaporHelpers.add('children') - } + for (const [, { id, children }] of Object.entries(ir.children)) { + code += `const n${id} = t0()\n` - for (const operation of ir.operation) { - code += genOperation(operation) - } + if (Object.keys(children).length) { + code += `const {${genChildren(children)}} = children(n${id})\n` + vaporHelpers.add('children') + } - for (const [_expr, operations] of Object.entries(ir.effect)) { - // TODO don't use watchEffect from vue/core, implement `effect` function in runtime-vapor package - let scope = `watchEffect(() => {\n` - helpers.add('watchEffect') - for (const operation of operations) { - scope += genOperation(operation) + for (const operation of ir.operation) { + code += genOperation(operation) } - scope += '})\n' - code += scope - } - code += 'return root' + for (const [_expr, operations] of Object.entries(ir.effect)) { + // TODO don't use watchEffect from vue/core, implement `effect` function in runtime-vapor package + let scope = `watchEffect(() => {\n` + helpers.add('watchEffect') + for (const operation of operations) { + scope += genOperation(operation) + } + scope += '})\n' + code += scope + } + + // TODO multiple-template + code += `return n${id}\n` + } if (vaporHelpers.size) preamble = diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 3ce7ff375..28a6eac70 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -121,7 +121,7 @@ function createContext( if (ctx.once) { return ctx.registerOpration(operation) } - parent.registerEffect(expr, operation) + return parent.registerEffect(expr, operation) }, } return ctx @@ -168,6 +168,9 @@ function transformChildren( const isFirst = i === 0 const isLast = i === children.length - 1 + // TODO: multiple root elements + if (root) child.store = true + switch (node.type) { case 1 satisfies NodeTypes.ELEMENT: { transformElement(child as TransformContext) diff --git a/playground/src/App-root.vue b/playground/src/App-root.vue new file mode 100644 index 000000000..74531c510 --- /dev/null +++ b/playground/src/App-root.vue @@ -0,0 +1,20 @@ + + + diff --git a/playground/src/main.ts b/playground/src/main.ts index c458e0959..261042c33 100644 --- a/playground/src/main.ts +++ b/playground/src/main.ts @@ -1,9 +1,11 @@ import { render } from 'vue/vapor' -import App from './App.vue' -render(() => { - // @ts-expect-error - const returned = App.setup({}, { expose() {} }) - // @ts-expect-error - return App.render(returned) -}, '#app') +const modules = import.meta.glob('./*.vue') +const mod = (modules['.' + location.pathname] || modules['./App.vue'])() + +mod.then(({ default: m }) => { + render(() => { + const returned = m.setup({}, { expose() {} }) + return m.render(returned) + }, '#app') +})