]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: root id
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 24 Nov 2023 12:38:59 +0000 (20:38 +0800)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 24 Nov 2023 12:41:46 +0000 (20:41 +0800)
packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
packages/compiler-vapor/__tests__/__snapshots__/fixtures.test.ts.snap
packages/compiler-vapor/__tests__/compile.test.ts
packages/compiler-vapor/src/generate.ts
packages/compiler-vapor/src/transform.ts

index da9a78950b5c69f70cde7bcae8183ae359ae085b..bba5cbb222bb9c79c57e135b3ec4760fc98c6e69 100644 (file)
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
 exports[`comile > bindings 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setText } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, children, insert, setText } from 'vue/vapor';
+const t0 = template(\`<div>count is <!>.</div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setText(n0, undefined, count.value)
-})
-return n0
-
-}"
+  const n0 = t0();
+  const {
+    1: [n2],
+  } = children(n0);
+  const n1 = document.createTextNode(count.value);
+  insert(n1, n0, n2);
+  watchEffect(() => {
+    setText(n1, undefined, count.value);
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-bind > simple expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setAttr } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, setAttr } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setAttr(n0, \\"id\\", undefined, id.value)
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    setAttr(n0, 'id', undefined, id.value);
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-html > no expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setHtml } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, setHtml } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setHtml(n0, undefined, \\"\\")
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    setHtml(n0, undefined, '');
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-html > simple expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setHtml } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, setHtml } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setHtml(n0, undefined, code.value)
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    setHtml(n0, undefined, code.value);
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-on > simple expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, on } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, on } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-on(n0, \\"click\\", handleClick)
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    on(n0, 'click', handleClick);
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-once 1`] = `
-"import { template, children, insert, setText, setAttr } from 'vue/vapor'
-const t0 = template(\`<div> <span></span></div>\`)
+"import { template, children, insert, setText, setAttr } from 'vue/vapor';
+const t0 = template(\`<div> <span></span></div>\`);
 export function render() {
-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 n0
-
-}"
+  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 n0;
+}
+"
 `;
 
 exports[`comile > directives > v-text > no expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setText } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, setText } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setText(n0, undefined, \\"\\")
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    setText(n0, undefined, '');
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > directives > v-text > simple expression 1`] = `
-"import { watchEffect } from 'vue'
-import { template, setText } from 'vue/vapor'
-const t0 = template(\`<div></div>\`)
+"import { watchEffect } from 'vue';
+import { template, setText } from 'vue/vapor';
+const t0 = template(\`<div></div>\`);
 export function render() {
-const n0 = t0()
-watchEffect(() => {
-setText(n0, undefined, str.value)
-})
-return n0
-
-}"
+  const n0 = t0();
+  watchEffect(() => {
+    setText(n0, undefined, str.value);
+  });
+  return n0;
+}
+"
 `;
 
 exports[`comile > static template 1`] = `
-"import { template } from 'vue/vapor'
-const t0 = template(\`<div><p>hello</p><input><span></span></div>\`)
+"import { template } from 'vue/vapor';
+const t0 = template(\`<div><p>hello</p><input><span></span></div>\`);
 export function render() {
-const n0 = t0()
-return n0
-
-}"
+  const n0 = t0();
+  return n0;
+}
+"
 `;
index fdf4d1cd9c628d301c4c427ee40e9c8bc108f0d7..6ade34c03ca0667d854cc3f7367039e474f5bef2 100644 (file)
@@ -19,28 +19,28 @@ const increment = () => count.value++
 
 
 return (() => {
-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)
-insert(n3, n2)
-const n7 = document.createTextNode(count.value)
-insert(n7, n6)
-setText(n7, undefined, count.value)
+const n0 = t0()
+const { 1: [n1], 2: [n3], 3: [n5], 4: [n6], 6: [n7],} = children(n0)
+const n2 = document.createTextNode(count.value)
+insert(n2, n1)
+const n4 = document.createTextNode(double.value)
+insert(n4, n3)
+const n8 = document.createTextNode(count.value)
+insert(n8, n7)
+setText(n8, undefined, count.value)
 watchEffect(() => {
-setText(n1, undefined, count.value)
+setText(n2, undefined, count.value)
 })
 watchEffect(() => {
-setText(n3, undefined, double.value)
+setText(n4, undefined, double.value)
 })
 watchEffect(() => {
-on(n4, \\"click\\", increment)
+on(n5, \\"click\\", increment)
 })
 watchEffect(() => {
-setHtml(n5, undefined, html)
+setHtml(n6, undefined, html)
 })
-return n8
+return n0
 
 })();
 }
index 3092f731be762fb665b2f0cf6a4057f821389f69..80079114657c5a517f60f1c12aa7f21ef426e2f0 100644 (file)
@@ -1,9 +1,24 @@
-import { BindingTypes } from '@vue/compiler-dom'
-import { compile } from '../src'
+import { BindingTypes, CompilerOptions, RootNode } from '@vue/compiler-dom'
+// TODO remove it
+import { format } from 'prettier'
+import { compile as _compile } from '../src'
+
+async function compile(
+  template: string | RootNode,
+  options: CompilerOptions = {},
+) {
+  let { code } = _compile(template, options)
+  code = await format(code, {
+    parser: 'babel',
+    printWidth: 999999,
+    singleQuote: true,
+  })
+  return code
+}
 
 describe('comile', () => {
-  test('static template', () => {
-    const { code } = compile(
+  test('static template', async () => {
+    const code = await compile(
       `<div>
         <p>hello</p>
         <input />
@@ -13,8 +28,8 @@ describe('comile', () => {
     expect(code).matchSnapshot()
   })
 
-  test('bindings', () => {
-    const { code } = compile(`<div>{{ count }}</div>`, {
+  test('bindings', async () => {
+    const code = await compile(`<div>count is {{ count }}.</div>`, {
       bindingMetadata: {
         count: BindingTypes.SETUP_REF,
       },
@@ -24,8 +39,8 @@ describe('comile', () => {
 
   describe('directives', () => {
     describe('v-bind', () => {
-      test('simple expression', () => {
-        const { code } = compile(`<div :id="id"></div>`, {
+      test('simple expression', async () => {
+        const code = await compile(`<div :id="id"></div>`, {
           bindingMetadata: {
             id: BindingTypes.SETUP_REF,
           },
@@ -35,8 +50,8 @@ describe('comile', () => {
     })
 
     describe('v-on', () => {
-      test('simple expression', () => {
-        const { code } = compile(`<div @click="handleClick"></div>`, {
+      test('simple expression', async () => {
+        const code = await compile(`<div @click="handleClick"></div>`, {
           bindingMetadata: {
             handleClick: BindingTypes.SETUP_CONST,
           },
@@ -46,8 +61,8 @@ describe('comile', () => {
     })
 
     describe('v-html', () => {
-      test('simple expression', () => {
-        const { code } = compile(`<div v-html="code"></div>`, {
+      test('simple expression', async () => {
+        const code = await compile(`<div v-html="code"></div>`, {
           bindingMetadata: {
             code: BindingTypes.SETUP_REF,
           },
@@ -55,15 +70,15 @@ describe('comile', () => {
         expect(code).matchSnapshot()
       })
 
-      test('no expression', () => {
-        const { code } = compile(`<div v-html></div>`)
+      test('no expression', async () => {
+        const code = await compile(`<div v-html></div>`)
         expect(code).matchSnapshot()
       })
     })
 
     describe('v-text', () => {
-      test('simple expression', () => {
-        const { code } = compile(`<div v-text="str"></div>`, {
+      test('simple expression', async () => {
+        const code = await compile(`<div v-text="str"></div>`, {
           bindingMetadata: {
             str: BindingTypes.SETUP_REF,
           },
@@ -71,14 +86,14 @@ describe('comile', () => {
         expect(code).matchSnapshot()
       })
 
-      test('no expression', () => {
-        const { code } = compile(`<div v-text></div>`)
+      test('no expression', async () => {
+        const code = await compile(`<div v-text></div>`)
         expect(code).matchSnapshot()
       })
     })
 
-    test('v-once', () => {
-      const { code } = compile(
+    test('v-once', async () => {
+      const code = await compile(
         `<div v-once>
           {{ msg }}
           <span :class="clz" />
index ff4c497fff529d95914b8aa888e7c1529564b616..b14c98407b0201203350f62493b51244cf29f631 100644 (file)
@@ -77,6 +77,7 @@ export function generate(
   function genOperation(operation: OperationNode) {
     let code = ''
 
+    // TODO: cache old value
     switch (operation.type) {
       case IRNodeTypes.SET_PROP: {
         code = `setAttr(n${operation.element}, ${JSON.stringify(
index 28a6eac7096dd30f393000b3fe7f37f9c6210b7d..29bfa6e5ec00c25a5c746cc43f568cf7435dcbfa 100644 (file)
@@ -169,7 +169,11 @@ function transformChildren(
     const isLast = i === children.length - 1
 
     // TODO: multiple root elements
-    if (root) child.store = true
+    if (root) {
+      child.store = true
+      // generate id for root element early
+      child.getElementId()
+    }
 
     switch (node.type) {
       case 1 satisfies NodeTypes.ELEMENT: {