返回
手写Vue源码——代码生成器
前端
2023-11-27 07:28:45
在前面的学习vue源码(6)熟悉模板编译原理中,我们谈到了,模板编译分为解析器,优化器,代码生成器。 前面两部分已经实现,现在 就来看看 代码生成器怎么实现吧。
代码生成器的作用
代码生成器的作用是使用 AST 生成 render 函数代码字符串。 生成后的代码字符串中看到了有几个函数调用 _c,_v…
手写一个简单的代码生成器
/**
* codegen AST 对象,转换成可执行 render 函数字符串
* @param {*} ast
*/
function generate (ast) {
const context = createCodegenContext()
const code = genElement(ast, context)
return {
render: code.render
}
}
/**
* 创建代码生成器的上下文
*/
function createCodegenContext () {
const context = {
// code
code: '',
// 当前渲染函数的行号
line: 1,
// 当前渲染函数的列号
column: 1,
// 优化标记,用来提升 render 函数代码质量
optimize: true,
// 在生成变量名称之前,保存变量的序列号,减少变量名之间的重复
varSeq: 0,
// 在代码中保存变量名,避免重复声明
saved: []
}
return context
}
/**
* 生成可执行的 render 函数字符串
* @param {*} elementAst 节点 AST
* @param {*} context 上下文环境
*/
function genElement (elementAst, context) {
const {children, tag, attrs} = elementAst
// 开头生成 _c 函数调用,调用形式 _c('标签',属性,孩子...)
const code = `_c('${tag}', ${
attrs.length ? genProps(attrs) : 'undefined'
}${
children.length ? `,${genChildren(children, context)}` : ''
})`
return {
render: code
}
}
上面的 genElement
方法处理了最基本的一个 DOM 节点的渲染函数生成逻辑。 在 generate
方法中,我们创建了一个 codegen 上下文对象,然后调用 genElement
方法来生成 render 函数代码字符串。
完整版本的代码生成器可以生成一个完整的 render 函数代码字符串, 包括对动态数据、事件和插槽的支持。