Skip to content

Commit

Permalink
feat(compile-core): support element and interpolation
Browse files Browse the repository at this point in the history
  • Loading branch information
cuixiaorui committed Jan 12, 2022
1 parent 89938a3 commit a0d791d
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 10 deletions.
16 changes: 15 additions & 1 deletion example/compiler-base/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
// 最简单的情况
// template 只有一个 interpolation
// export default {
// template: `{{msg}}`,
// setup() {
// return {
// msg: "vue3 - compiler",
// };
// },
// };


// 复杂一点
// template 包含 element 和 interpolation
export default {
template: `{{msg}}`,
template: `<p>{{msg}}</p>`,
setup() {
return {
msg: "vue3 - compiler",
Expand Down
2 changes: 2 additions & 0 deletions example/compiler-base/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

const rootContainer = document.querySelector("#app");
createApp(App).mount(rootContainer);


</script>
</body>
</html>
30 changes: 29 additions & 1 deletion lib/mini-vue.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/mini-vue.cjs.js.map

Large diffs are not rendered by default.

31 changes: 29 additions & 2 deletions lib/mini-vue.esm.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/mini-vue.esm.js.map

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion src/compiler-core/__tests__/codegen.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import { generate } from "../src/codegen";
import { baseParse } from "../src/parse";
import { transform } from "../src/transform";
import { transformElement } from "../src/transforms/transformElement";
import { transformExpression } from "../src/transforms/transformExpression";

test("interpolation module", () => {
const ast = baseParse("{{hello}}");
transform(ast, {
nodeTransforms: [transformExpression]
nodeTransforms: [transformExpression],
});

const { code } = generate(ast);
console.log(code);
});

test("element and interpolation", () => {
const ast = baseParse("<div>hi,{{msg}}</div>");
transform(ast, {
nodeTransforms: [transformExpression, transformElement],
});

const { code } = generate(ast);
console.log(code);
console.log(code.children[0])
});
32 changes: 31 additions & 1 deletion src/compiler-core/src/codegen.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { NodeTypes } from "./ast";
import { helperNameMap, TO_DISPLAY_STRING } from "./runtimeHelpers";
import {
CREATE_ELEMENT_VNODE,
helperNameMap,
TO_DISPLAY_STRING,
} from "./runtimeHelpers";

export function generate(ast, options = {}) {
// 先生成 context
Expand Down Expand Up @@ -65,11 +69,37 @@ function genNode(node: any, context: any) {
genExpression(node, context);
break;

case NodeTypes.ELEMENT:
genElement(node, context);
break;

case NodeTypes.TEXT:
genText(node, context);
break;

default:
break;
}
}

function genText(node: any, context: any) {
// Implement
const { push } = context;

// TODO 是如何处理添加 + 操作符的呢?
push(`'${node.content}'+`);
}

function genElement(node, context) {
const { push, helper } = context;

push(`${helper(CREATE_ELEMENT_VNODE)}("${node.tag}", {}, `);
node.children.forEach((n) => {
genNode(n, context);
});
push(`)`)
}

function genExpression(node: any, context: any) {
context.push(node.content, node);
}
Expand Down
3 changes: 2 additions & 1 deletion src/compiler-core/src/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { generate } from "./codegen";
import { baseParse } from "./parse";
import { transform } from "./transform";
import { transformExpression } from "./transforms/transformExpression";
import { transformElement } from "./transforms/transformElement";

export function baseCompile(template, options) {
// 1. 先把 template 也就是字符串 parse 成 ast
Expand All @@ -10,7 +11,7 @@ export function baseCompile(template, options) {
transform(
ast,
Object.assign(options, {
nodeTransforms: [transformExpression],
nodeTransforms: [transformExpression, transformElement],
})
);

Expand Down
2 changes: 2 additions & 0 deletions src/compiler-core/src/runtimeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export const TO_DISPLAY_STRING = Symbol(`toDisplayString`);
export const CREATE_ELEMENT_VNODE = Symbol("createElementVNode");

export const helperNameMap = {
[TO_DISPLAY_STRING]: "toDisplayString",
[CREATE_ELEMENT_VNODE]: "createElementVNode"
};
9 changes: 9 additions & 0 deletions src/compiler-core/src/transforms/transformElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NodeTypes } from "../ast";
import { CREATE_ELEMENT_VNODE } from "../runtimeHelpers";

export function transformElement(node, context) {
if (node.type === NodeTypes.ELEMENT) {
// TODO 没有实现 block 所以这里直接创建 element
context.helper(CREATE_ELEMENT_VNODE);
}
}
2 changes: 1 addition & 1 deletion src/runtime-core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ export * from "./createApp";
export { getCurrentInstance, registerRuntimeCompiler } from "./component";
export { inject, provide } from "./apiInject";
export { renderSlot } from "./helpers/renderSlot";
export { createTextVNode } from "./vnode";
export { createTextVNode, createElementVNode } from "./vnode";
export { createRenderer } from "./renderer";
export { toDisplayString } from "../shared";
2 changes: 2 additions & 0 deletions src/runtime-core/vnode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ShapeFlags } from "../shared";

export { createVNode as createElementVNode }

export const createVNode = function (
type: any,
props?: any,
Expand Down

0 comments on commit a0d791d

Please sign in to comment.