Skip to content

Commit

Permalink
feat: support using dynamic components in templates
Browse files Browse the repository at this point in the history
  • Loading branch information
zcf0508 committed Sep 14, 2023
1 parent cd1854d commit 9e8ac17
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 14 deletions.
5 changes: 4 additions & 1 deletion packages/playground/server/api/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ export default defineEventHandler(async (ctx) => {
graph = analyzeSetupScript(sfc.descriptor.scriptSetup?.content!);
}
else if(sfc.descriptor.script?.content) {
if (sfc.descriptor.script.lang === 'tsx' || sfc.descriptor.script.lang === 'jsx') {
if (
(sfc.descriptor.script.lang === 'tsx' || sfc.descriptor.script.lang === 'jsx')
&& !sfc.descriptor.template?.content
) {
const res = await analyzeTsx(sfc.descriptor.script?.content!);
graph = res.graph;
nodes = res.nodesUsedInTemplate;
Expand Down
5 changes: 4 additions & 1 deletion packages/vscode/src/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ export async function analyze(code: string) {
);
}
else if(sfc.descriptor.script?.content) {
if (sfc.descriptor.script.lang === 'tsx' || sfc.descriptor.script.lang === 'jsx') {
if (
(sfc.descriptor.script.lang === 'tsx' || sfc.descriptor.script.lang === 'jsx')
&& !sfc.descriptor.template?.content
) {
const res = await analyzeTsx(sfc.descriptor.script?.content!,
(sfc.descriptor.script.loc.start.line || 1) - 1,
);
Expand Down
14 changes: 12 additions & 2 deletions src/analyze/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function analyze(
const ast = babelParse(content, { sourceType: 'module',
plugins: [
'typescript',
'jsx',
],
});

Expand Down Expand Up @@ -166,12 +167,21 @@ export function analyze(
// 3 filter data by return
traverse(setupNode, {
ReturnStatement(path2) {
// only process return in setupNode scope
if(path2.scope !== path1.scope) {
return;
}

if(path2.node.argument?.type === 'ObjectExpression') {
const returnNode = path2.node.argument;
traverse(returnNode, {
ObjectProperty(path3) {
if(path3.parent === returnNode) {
if(path3.node.key.type === 'Identifier' && path3.node.value.type === 'Identifier') {
if(
path3.node.key.type === 'Identifier'
&& path3.node.value.type === 'Identifier'
&& tempNodes.has(path3.node.value.name)
) {
const valName = path3.node.value.name;
if(!graph.nodes.has(valName)) {
graph.nodes.add(valName);
Expand Down Expand Up @@ -234,7 +244,7 @@ export function analyze(
},
}, path2.scope, path2);
} else {
console.warn('setup return type is not ObjectExpression');
console.warn(`setup return type(${path2.node.argument?.type}) is not ObjectExpression`);
}
},
}, path1.scope, path1);
Expand Down
1 change: 1 addition & 0 deletions src/analyze/setupScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ export function analyze(
const ast = babelParse(content, { sourceType: 'module',
plugins: [
'typescript',
'jsx',
],
});

Expand Down
9 changes: 9 additions & 0 deletions src/analyze/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export function analyze(
}
}
},
// component
CallExpression(path) {
if(path.node.callee.type === 'Identifier' && path.node.callee.name === '_resolveComponent') {
if(path.node.arguments[0].type === 'StringLiteral') {
const name = path.node.arguments[0].value;
name && nodes.add(name);
}
}
},
});

return nodes;
Expand Down
18 changes: 10 additions & 8 deletions test/options-setup/TestComponent.graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ import { NodeType, TypedNode } from '@/analyze/utils';

const edges = new Map<TypedNode, Set<TypedNode>>();

const number: TypedNode = {label: 'number', type: NodeType.var, info: {line: 65, column: 6}};
const count: TypedNode = {label: 'count', type: NodeType.var, info: {line: 67, column: 10}};
const plus: TypedNode = {label: 'plus', type: NodeType.fun, info: {line: 70, column: 6}};
const add: TypedNode = {label: 'add', type: NodeType.fun, info: {line: 74, column: 6}};
const a: TypedNode = {label: 'a', type: NodeType.var, info: {line: 81, column: 10}};
const b: TypedNode = {label: 'b', type: NodeType.var, info: {line: 82, column: 10}};
const c: TypedNode = {label: 'c', type: NodeType.var, info: {line: 87, column: 6}};
const number: TypedNode = {label: 'number', type: NodeType.var, info: {line: 66, column: 6}};
const count: TypedNode = {label: 'count', type: NodeType.var, info: {line: 68, column: 10}};
const plus: TypedNode = {label: 'plus', type: NodeType.fun, info: {line: 71, column: 6}};
const add: TypedNode = {label: 'add', type: NodeType.fun, info: {line: 75, column: 6}};
// const a: TypedNode = {label: 'a', type: NodeType.var, info: {line: 82, column: 10}};
const b: TypedNode = {label: 'b', type: NodeType.var, info: {line: 83, column: 10}};
const c: TypedNode = {label: 'c', type: NodeType.var, info: {line: 89, column: 6}};
const ComponentD: TypedNode = { label: 'ComponentD', type: NodeType.var, info: {line: 84, column: 10}};

edges.set(number, new Set([]));
edges.set(b, new Set([count]));
edges.set(c, new Set([count]));
edges.set(count, new Set([]));
edges.set(plus, new Set([plus]));
edges.set(add, new Set([number, add, count]));
edges.set(ComponentD, new Set([]));
// edges.set(a, new Set([count]));

export const graph = {
nodes: new Set([number, b, count, c, plus, add]),
nodes: new Set([number, b, count, c, plus, add, ComponentD]),
edges,
};
2 changes: 1 addition & 1 deletion test/options-setup/TestComponent.nodes.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const nodes = new Set(['msg', 'plus', 'count', 'number', 'add']);
export const nodes = new Set(['msg', 'plus', 'count', 'number', 'add', 'ComponentD']);
6 changes: 5 additions & 1 deletion test/options-setup/TestComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
<ComponentD></ComponentD>
</template>

<script lang="ts">
<script lang="tsx">
export default {
name: 'TestComponent',
props: {
Expand Down Expand Up @@ -81,13 +82,16 @@ export default {
const a = {count};
const b = count;
const ComponentD = (<>hello d</>)
return {
...toRefs(data),
b,
c: count,
...methods,
ComponentD,
}
}
}
</script>
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"jsx": "preserve",
"baseUrl": "./",
"paths": {
"@/*": [
Expand Down

0 comments on commit 9e8ac17

Please sign in to comment.