Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
9ab8e4c
chore: update lockfile
edison1105 Apr 1, 2025
e5dd701
feat(vapor/hydration): handle component with anchor insertion
edison1105 Apr 21, 2025
9c30fd4
wip: save
edison1105 Apr 22, 2025
d8443d3
wip: refactor
edison1105 Apr 22, 2025
3108d91
refactor: skip dynamic anchors and empty text nodes
edison1105 Apr 23, 2025
1248172
wip: save
edison1105 Apr 23, 2025
25b8fbe
refactor: add enableHydrationNodeLookup and disableHydrationNodeLooku…
edison1105 Apr 23, 2025
3e7f093
chore: dont process text/comment node as dynamic
edison1105 Apr 23, 2025
04eadd8
wip: refactor
edison1105 Apr 23, 2025
b5762b5
wip: add tests + skip fragment end anchor
edison1105 Apr 24, 2025
38d4889
wip: hydrate v-if
edison1105 Apr 24, 2025
e9c9e49
wip: refactor hydration for v-if
edison1105 Apr 24, 2025
612cde7
wip: test hydrate v-if in PROD
edison1105 Apr 25, 2025
4d8284b
test: update
edison1105 Apr 25, 2025
34b9a4b
wip: hydation for dynamic component
edison1105 Apr 25, 2025
aad75fd
wip: refactor
edison1105 Apr 25, 2025
e6e0160
wip: v-for hydration
edison1105 Apr 25, 2025
7a842ab
wip: refactor
edison1105 Apr 26, 2025
ca34d4a
wip: add more tests
edison1105 Apr 26, 2025
42a421a
wip: hydration for slots
edison1105 Apr 26, 2025
2f00264
fix(compiler-vapor): move `next`, `child` and `nthChild` before setI…
zhiyuanzmj Apr 27, 2025
700f49e
wip: hydration for slots
edison1105 Apr 27, 2025
e5399c3
wip: vdom interop
edison1105 Apr 28, 2025
4253b0c
wip: update
edison1105 Apr 28, 2025
d281d62
wip: vdom hydration interop
edison1105 Apr 29, 2025
ea34f2f
wip: vdom interop
edison1105 Apr 29, 2025
3e69504
fix(compiler-vapor): properly handle static ref in inline mode
edison1105 Apr 29, 2025
a9496de
test: more tests
edison1105 Apr 29, 2025
d776a26
chore: tweaks
edison1105 Apr 30, 2025
7dd7d82
chore: Merge branch 'vapor' into edison/feat/vaporHydration
edison1105 Jun 20, 2025
552ac6d
chore: update
edison1105 Jun 25, 2025
ea1c60b
wip: handle more case
edison1105 Jun 28, 2025
bac2bc2
Merge branch 'vapor' into edison/feat/vaporHydration
edison1105 Jun 28, 2025
a776fc4
chore: update
edison1105 Jun 30, 2025
bb606f3
wip: handle $root during hydration
edison1105 Jul 1, 2025
f2a5abe
chore: update
edison1105 Jul 1, 2025
0ca32f4
fix(hydration): skip dynamic children in __child
edison1105 Jul 4, 2025
cb7779b
chore: Merge branch 'minor' into edison/feat/vaporHydration
edison1105 Jul 18, 2025
5ee1628
fix(hydration): handle v-if on insertion parent
edison1105 Jul 29, 2025
85693f0
feat(hydration): handle consecutive if node
edison1105 Jul 30, 2025
541ba07
Merge branch 'minor' into edison/feat/vaporHydration
edison1105 Aug 16, 2025
e52d2ab
refactor: hydration
edison1105 Aug 16, 2025
ee8c5be
refactor: block anchors
edison1105 Aug 18, 2025
4db35b1
chore: tweaks
edison1105 Aug 19, 2025
c252e91
test: add more tests
edison1105 Aug 19, 2025
6c8471b
wip: hydration mismatch handling
edison1105 Aug 19, 2025
ec28c43
wip: text node mismatch
edison1105 Aug 19, 2025
e8a8117
fix(hydration): properly handle empty text node
edison1105 Aug 19, 2025
ab2c308
wip: prop mismatch handling
edison1105 Aug 19, 2025
474cb7f
wip: add tests for class mismatch
edison1105 Aug 20, 2025
8f23b4e
wip: style mismatch
edison1105 Aug 20, 2025
aec4002
wip: style mismatch with v-show
edison1105 Aug 20, 2025
e496228
refactor: style / class mismatch handling
edison1105 Aug 20, 2025
e4fcb9d
wip: attr mismatch
edison1105 Aug 20, 2025
690f256
wip: test attr mismatch
edison1105 Aug 20, 2025
be95736
test: add more tests
edison1105 Aug 21, 2025
29692d9
chore: Merge branch 'minor' into edison/feat/vaporHydration
edison1105 Aug 21, 2025
8b77465
chore: pin rollup
edison1105 Aug 21, 2025
c52f8d8
chore: update block anchor labels
edison1105 Aug 26, 2025
00266de
fix: ensure self anchor is inserted during hydration
edison1105 Aug 29, 2025
41d322e
refactor: vapor hydration
edison1105 Sep 9, 2025
df9131d
chore: Merge branch 'minor' into edison/feat/vaporHydration
edison1105 Sep 9, 2025
63111cb
chore: use empty text node as anchor in PROD
edison1105 Sep 9, 2025
df2c42a
chore: small tweaks
edison1105 Sep 10, 2025
dbe1bd8
perf: don't initialize hydration state if no anchor
edison1105 Sep 16, 2025
576e93a
perf: replace spread operator with apply
edison1105 Sep 16, 2025
2ef3caa
fix: handling v-for on component with non-hydration node
edison1105 Sep 22, 2025
0359298
refactor: reuse hydration state
edison1105 Sep 22, 2025
2a4ce48
fix: don't warn mismatch if value is empty
edison1105 Sep 22, 2025
df9f8f2
fix: don't warn mismatch in setHtml
edison1105 Sep 22, 2025
1df1597
fix: skip blank text nodes during hydration
edison1105 Sep 24, 2025
ac11bd0
test: remove redundant test
edison1105 Sep 24, 2025
f270791
refactor: sync from test vapor branch
edison1105 Oct 20, 2025
be48dc6
chore: Merge branch 'minor' into edison/feat/vaporHydration
edison1105 Oct 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"pug": "^3.0.3",
"puppeteer": "~24.16.2",
"rimraf": "^6.0.1",
"rollup": "4.50.1",
"rollup": "^4.52.5",
"rollup-plugin-dts": "^6.2.3",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-polyfill-node": "^0.13.0",
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,11 @@ export function compileScript(
: ''
// wrap setup code with function.
if (ctx.isTS) {
// in SSR, always use defineComponent, so __vapor flag is required
if (ssr && vapor) {
runtimeOptions += `\n __vapor: true,`
}

// for TS, make sure the exported type is still valid type with
// correct props information
// we have to use object spread for types to be merged properly
Expand Down
18 changes: 9 additions & 9 deletions packages/compiler-ssr/__tests__/ssrVIf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ describe('ssr: v-if', () => {
test('<template v-if> (text)', () => {
expect(compile(`<template v-if="foo">hello</template>`).code)
.toMatchInlineSnapshot(`
"
return function ssrRender(_ctx, _push, _parent, _attrs) {
if (_ctx.foo) {
_push(\`<!--[-->hello<!--]-->\`)
} else {
_push(\`<!---->\`)
}
}"
`)
"
return function ssrRender(_ctx, _push, _parent, _attrs) {
if (_ctx.foo) {
_push(\`<!--[-->hello<!--]-->\`)
} else {
_push(\`<!---->\`)
}
}"
`)
})

test('<template v-if> (single element)', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`compile > bindings 1`] = `
"import { child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div> </div>", true)

export function render(_ctx, $props, $emit, $attrs, $slots) {
const n0 = t0()
const x0 = _child(n0)
const x0 = _txt(n0)
_renderEffect(() => _setText(x0, "count is " + _toDisplayString(_ctx.count) + "."))
return n0
}"
Expand Down Expand Up @@ -38,7 +38,7 @@ export function render(_ctx) {
"default": () => {
const n0 = _createIf(() => (true), () => {
const n3 = t0()
_setInsertionState(n3)
_setInsertionState(n3, null, true)
const n2 = _createComponentWithFallback(_component_Bar)
_withVaporDirectives(n2, [[_directive_hello, void 0, void 0, { world: true }]])
return n3
Expand Down Expand Up @@ -157,8 +157,8 @@ export function render(_ctx, $props, $emit, $attrs, $slots) {
const _component_Comp = _resolveComponent("Comp")
const n0 = t0()
const n3 = t1()
const n2 = _child(n3)
_setInsertionState(n3, 0)
const n2 = _child(n3, 1)
_setInsertionState(n3, 0, true)
const n1 = _createComponentWithFallback(_component_Comp)
_renderEffect(() => {
_setProp(n3, "id", _ctx.foo)
Expand All @@ -180,13 +180,13 @@ export function render(_ctx) {
`;

exports[`compile > dynamic root nodes and interpolation 1`] = `
"import { child as _child, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, delegateEvents as _delegateEvents, template as _template } from 'vue';
"import { txt as _txt, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, delegateEvents as _delegateEvents, template as _template } from 'vue';
const t0 = _template("<button> </button>", true)
_delegateEvents("click")

export function render(_ctx) {
const n0 = t0()
const x0 = _child(n0)
const x0 = _txt(n0)
n0.$evtclick = e => _ctx.handleClick(e)
_renderEffect(() => {
const _count = _ctx.count
Expand All @@ -198,12 +198,12 @@ export function render(_ctx) {
`;

exports[`compile > execution order > basic 1`] = `
"import { child as _child, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { txt as _txt, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div> </div>", true)

export function render(_ctx) {
const n0 = t0()
const x0 = _child(n0)
const x0 = _txt(n0)
_renderEffect(() => {
_setProp(n0, "id", _ctx.foo)
_setText(x0, _toDisplayString(_ctx.bar))
Expand All @@ -212,32 +212,56 @@ export function render(_ctx) {
}"
`;

exports[`compile > execution order > setInsertionState > next, child and nthChild should be above the setInsertionState 1`] = `
"import { resolveComponent as _resolveComponent, child as _child, next as _next, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, nthChild as _nthChild, createIf as _createIf, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div></div>")
const t1 = _template("<div><div></div><!><div></div><!><div><button></button></div></div>", true)

export function render(_ctx) {
const _component_Comp = _resolveComponent("Comp")
const n6 = t1()
const n5 = _next(_child(n6), 1)
const n7 = _nthChild(n6, 3, 3)
const p0 = _next(n7, 4)
const n4 = _child(p0, 0)
_setInsertionState(n6, n5)
const n0 = _createComponentWithFallback(_component_Comp)
_setInsertionState(n6, n7, true)
const n1 = _createIf(() => (true), () => {
const n3 = t0()
return n3
})
_renderEffect(() => _setProp(n4, "disabled", _ctx.foo))
return n6
}"
`;

exports[`compile > execution order > with insertionState 1`] = `
"import { resolveComponent as _resolveComponent, child as _child, setInsertionState as _setInsertionState, createSlot as _createSlot, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue';
const t0 = _template("<div><div></div></div>", true)

export function render(_ctx) {
const _component_Comp = _resolveComponent("Comp")
const n3 = t0()
const n1 = _child(n3)
_setInsertionState(n1)
const n1 = _child(n3, 0)
_setInsertionState(n1, null, true)
const n0 = _createSlot("default", null)
_setInsertionState(n3)
_setInsertionState(n3, 1, true)
const n2 = _createComponentWithFallback(_component_Comp)
return n3
}"
`;

exports[`compile > execution order > with v-once 1`] = `
"import { child as _child, next as _next, nthChild as _nthChild, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, next as _next, nthChild as _nthChild, txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div><span> </span> <br> </div>", true)

export function render(_ctx) {
const n3 = t0()
const n0 = _child(n3)
const n1 = _next(n0)
const n2 = _nthChild(n3, 3)
const x0 = _child(n0)
const n0 = _child(n3, 0)
const n1 = _next(n0, 1)
const n2 = _nthChild(n3, 3, 3)
const x0 = _txt(n0)
_setText(x0, _toDisplayString(_ctx.foo))
_renderEffect(() => {
_setText(n1, " " + _toDisplayString(_ctx.bar))
Expand Down Expand Up @@ -280,30 +304,6 @@ export function render(_ctx) {
}"
`;

exports[`compile > setInsertionState > next, child and nthChild should be above the setInsertionState 1`] = `
"import { resolveComponent as _resolveComponent, child as _child, next as _next, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, nthChild as _nthChild, createIf as _createIf, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div></div>")
const t1 = _template("<div><div></div><!><div></div><!><div><button></button></div></div>", true)

export function render(_ctx) {
const _component_Comp = _resolveComponent("Comp")
const n6 = t1()
const n5 = _next(_child(n6))
const n7 = _nthChild(n6, 3)
const p0 = _next(n7)
const n4 = _child(p0)
_setInsertionState(n6, n5)
const n0 = _createComponentWithFallback(_component_Comp)
_setInsertionState(n6, n7)
const n1 = _createIf(() => (true), () => {
const n3 = t0()
return n3
})
_renderEffect(() => _setProp(n4, "disabled", _ctx.foo))
return n6
}"
`;

exports[`compile > static + dynamic root 1`] = `
"import { toDisplayString as _toDisplayString, setText as _setText, template as _template } from 'vue';
const t0 = _template(" ")
Expand Down
30 changes: 15 additions & 15 deletions packages/compiler-vapor/__tests__/compile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,19 @@ describe('compile', () => {
})
})

describe('setInsertionState', () => {
test('next, child and nthChild should be above the setInsertionState', () => {
const code = compile(`
describe('execution order', () => {
test('basic', () => {
const code = compile(`<div :id="foo">{{ bar }}</div>`)
expect(code).matchSnapshot()
expect(code).contains(
`_setProp(n0, "id", _ctx.foo)
_setText(x0, _toDisplayString(_ctx.bar))`,
)
})

describe('setInsertionState', () => {
test('next, child and nthChild should be above the setInsertionState', () => {
const code = compile(`
<div>
<div />
<Comp />
Expand All @@ -234,18 +244,8 @@ describe('compile', () => {
</div>
</div>
`)
expect(code).toMatchSnapshot()
})
})

describe('execution order', () => {
test('basic', () => {
const code = compile(`<div :id="foo">{{ bar }}</div>`)
expect(code).matchSnapshot()
expect(code).contains(
`_setProp(n0, "id", _ctx.foo)
_setText(x0, _toDisplayString(_ctx.bar))`,
)
expect(code).toMatchSnapshot()
})
})

test('with v-once', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function render(_ctx) {
return n5
}, () => {
const n14 = t2()
_setInsertionState(n14, 0)
_setInsertionState(n14, 0, true)
const n9 = _createIf(() => (_ctx.c), () => {
const n11 = t1()
return n11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ export function render(_ctx) {
`;

exports[`compiler: expression > empty interpolation 4`] = `
"import { child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div> </div>", true)

export function render(_ctx) {
const n1 = t0()
const n0 = _child(n1)
const x1 = _child(n1)
const n0 = _child(n1, 0)
const x1 = _txt(n1)
_renderEffect(() => {
const _foo = _ctx.foo
_setText(n0, _toDisplayString(_foo))
Expand Down Expand Up @@ -81,13 +81,13 @@ export function render(_ctx, $props, $emit, $attrs, $slots) {
`;

exports[`compiler: expression > update expression 1`] = `
"import { child as _child, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, txt as _txt, setProp as _setProp, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div> </div>", true)

export function render(_ctx) {
const n1 = t0()
const n0 = _child(n1)
const x1 = _child(n1)
const n0 = _child(n1, 0)
const x1 = _txt(n1)
_renderEffect(() => {
const _String = String
const _foo = _ctx.foo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const t1 = _template("<div><div></div><!><div></div></div>", true)

export function render(_ctx) {
const n4 = t1()
const n3 = _next(_child(n4))
_setInsertionState(n4, n3)
const n3 = _next(_child(n4), 1)
_setInsertionState(n4, n3, true)
const n0 = _createIf(() => (1), () => {
const n2 = t0()
return n2
Expand All @@ -18,16 +18,16 @@ export function render(_ctx) {
`;

exports[`compiler: children transform > children & sibling references 1`] = `
"import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, next as _next, txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div><p> </p> <p> </p></div>", true)

export function render(_ctx) {
const n3 = t0()
const n0 = _child(n3)
const n1 = _next(n0)
const n2 = _next(n1)
const x0 = _child(n0)
const x2 = _child(n2)
const n0 = _child(n3, 0)
const n1 = _next(n0, 1)
const n2 = _next(n1, 2)
const x0 = _txt(n0)
const x2 = _txt(n2)
_renderEffect(() => {
_setText(x0, _toDisplayString(_ctx.first))
_setText(n1, " " + _toDisplayString(_ctx.second) + " " + _toDisplayString(_ctx.third) + " ")
Expand All @@ -38,33 +38,33 @@ export function render(_ctx) {
`;

exports[`compiler: children transform > efficient find 1`] = `
"import { child as _child, nthChild as _nthChild, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, nthChild as _nthChild, txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div><div>x</div><div>x</div><div> </div></div>", true)

export function render(_ctx) {
const n1 = t0()
const n0 = _nthChild(n1, 2)
const x0 = _child(n0)
const n0 = _nthChild(n1, 2, 2)
const x0 = _txt(n0)
_renderEffect(() => _setText(x0, _toDisplayString(_ctx.msg)))
return n1
}"
`;

exports[`compiler: children transform > efficient traversal 1`] = `
"import { child as _child, next as _next, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
"import { child as _child, next as _next, txt as _txt, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div><div>x</div><div><span> </span></div><div><span> </span></div><div><span> </span></div></div>", true)

export function render(_ctx) {
const n3 = t0()
const p0 = _next(_child(n3))
const n0 = _child(p0)
const p1 = _next(p0)
const n1 = _child(p1)
const p2 = _next(p1)
const n2 = _child(p2)
const x0 = _child(n0)
const x1 = _child(n1)
const x2 = _child(n2)
const p0 = _next(_child(n3), 1)
const n0 = _child(p0, 0)
const p1 = _next(p0, 2)
const n1 = _child(p1, 0)
const p2 = _next(p1, 3)
const n2 = _child(p2, 0)
const x0 = _txt(n0)
const x1 = _txt(n1)
const x2 = _txt(n2)
_renderEffect(() => {
const _msg = _ctx.msg
_setText(x0, _toDisplayString(_msg))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`compiler: element transform > checkbox with static indeterminate 1`] = `
"import { setProp as _setProp, template as _template } from 'vue';
const t0 = _template("<input type=\\"checkbox\\">", true)

export function render(_ctx) {
const n0 = t0()
_setProp(n0, "indeterminate", "")
return n0
}"
`;

exports[`compiler: element transform > component > cache v-on expression with unique handler name 1`] = `
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback } from 'vue';

Expand Down
Loading
Loading