37- codegen 生成 text

134 阅读1分钟

模拟Vue,将一个 template 生成为 render

image.png

用例

采用快照的形式来看自己生成的 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()
})

image.png

实现

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
}