模拟Vue,将一个 template 生成为 render
用例
采用快照的形式来看自己生成的 code string
import { codegen } from "../src/codegen";
test('text', () => {
const template = 'hi'
const ast = baseParse(template)
transform(ast)
const code = codegen(ast)
// toMatchSnapshot 会生成一个快照,会在当前文件夹生成一个 __snapshots__ 存储快照
expect(code).toMatchSnapshot()
})
实现
codegen.ts
/*
* @Author: Lin ZeFan
* @Date: 2022-04-17 10:40:19
* @LastEditTime: 2022-04-17 12:15:07
* @LastEditors: Lin ZeFan
* @Description:
* @FilePath: \mini-vue3\src\compiler-core\src\codegen.ts
*
*/
export function codegen(ast) {
const context = createCodegenContext()
const { push } = context
const funcName = 'render'
push(`export `)
// 函数固定的回调参数
const args = ['_ctx', '_cache']
const signature = args.join(', ')
push(`function ${funcName}(${signature}) { `)
push(`return `)
genNode(ast.codegenNode, context)
push(` }`)
return context.code
}
function genNode(node, context) {
const { push } = context
push(`'${node.content}'`)
}
// 封装 code 追加,降低耦合
function createCodegenContext() {
const context = {
code: '',
push(source: string) {
context.code += source
},
}
return context
}