news 2026/4/15 21:31:11

43-mini-vue 实现代码生成 string 类型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
43-mini-vue 实现代码生成 string 类型

实现代码生成 string 类型

  1. 整体转换流程,本节考虑的是 generate 将 ast 转换为 function render 函数

  2. 展示生成 render 函数的样子

https://template-explorer.vuejs.org/#eyJzcmMiOiI8ZGl2PkhlbGxvIFdvcmxkPC9kaXY+Iiwib3B0aW9ucyI6e319
  1. 单测
// compiler-core/src/tests/codegen.spec.tsimport{generate}from'../src/codegen'import{baseParse}from'../src/parse'describe("codegen",()=>{it("string",()=>{constast=baseParse('hi')const{code}=generate(ast)// 快照测试 把我们的代码拍了张照片// 1. 抓 bug// 2. 更新快照expect(code).toMatchSnapshot()})})
  1. 先简单跑通
// compiler-core/src/codegen.tsexportfunctiongenerate(ast){return{code:`return function render(_ctx, _cache, $props, $setup, $data, $options) { return "hi" }`}}
  1. 我们稍作修改对快照功能进行熟悉
// codegen.spec.tsexportfunctiongenerate(ast){return{code:`return function render(_ctx, _cache, $props, $setup, $data, $options) { return "hi 1" // ✅ 这里多了1 }`}}
  • 可以看到,修改完毕以后,这里会报错
1snapshot failed.Snapshot Summary ›1snapshot failed from1test suite.Inspect your code changes or press`u`to update them.
  • 我们使用命令进行主动修改: pnpm test codegen.spec.ts -t ‘codegen string’ -u, 执行完毕以后,发现测试通过了,
    在生成的 __snapshots__里面的文件已经主动进行了修改
  1. tips: jest 是给 react 创建的一个测试的概念,为了让开发人员更容易得去写测试,等于我们这里不用手动更新 codegen.spec.ts , -u 替我们在快照层面进行了相关操作
  2. 后续实现思路,
  • render后续可能更改可以提出去,
  • 参数可以提出去,
  • 返回参数可以提出去
returnfunctionrender(_ctx,_cache,$props,$setup,$data,$options){return"hi 1"// ✅ 这里多了1}
  1. 简单的先实现一版
exportfunctiongenerate(ast){// ✅️letcode=""code+="return "constfunctionName="render"constargs=["_ctx","_cache"]constsignature=args.join(",")code+=`function${functionName}(${signature}){`code+="return hi 1"code+="}"return{code}}
  1. 将返回值使用模板字符串进行动态展示
exportfunctiongenerate(ast){letcode=""code+="return "constfunctionName="render"constargs=["_ctx","_cache"]constsignature=args.join(",")code+=`function${functionName}(${signature}){`// code += "return 'hi 1'"constnode=ast.children[0]// ✅️code+=`return '${node.content}'`// ✅️code+="}"return{code}}
  1. 我们检查代码, 发现这里的 node 的获取并不灵活,有一些场景没有考虑到
  • 我们现在取得是 children[0] ,但实际情况我们并不知道这个入口是在哪个下标,此时 children 有多个, 所以这块逻辑需要放在 transform.ts 文件里面
exportfunctiongenerate(ast){letcode=""code+="return "constfunctionName="render"constargs=["_ctx","_cache"]constsignature=args.join(",")code+=`function${functionName}(${signature}){`constnode=ast.children[0]// 💡code+=`return '${node.content}'`code+="}"return{code}}
  1. 标记入口进行优化
// transform.ts// 标识入口 nodeexportfunctiontransform(root,options={}){constcontext=createTransformContext(root,options)traverseNode(root,context)// 这里处理 返回参数逻辑createRootCodegen(root)// ✅️}functioncreateRootCodegen(root:any){// ✅️root.codegenNode=root.children[0]}
// transform.spec.ts// 调用transform 函数✅入口 node 进行标识describe("codegen",()=>{it("string",()=>{constast=baseParse('hi')transform(ast)// ✅const{code}=generate(ast)expect(code).toMatchSnapshot()})})
  1. 获取 node 代码抽离
exportfunctiongenerate(ast){letcode=""code+="return "constfunctionName="render"constargs=["_ctx","_cache"]constsignature=args.join(",")code+=`function${functionName}(${signature}){`code=getNode(ast,code)// ✅code+="}"return{code}}functiongetNode(ast:any,code:string){// ✅constnode=ast.codegenNode code+=`return '${node.content}'`returncode}
  1. 对上下文进行抽离封装
exportfunctiongenerate(ast){constcontext=createCodegenContext()// ✅const{push}=context// ✅constfunctionName="render"constargs=["_ctx","_cache"]constsignature=args.join(",")push("return ")// ✅push(`function${functionName}(${signature}){`)// ✅getNode(ast.codegenNode,context)// ✅push("}")// ✅return{code:context.code// ✅}}functioncreateCodegenContext(){// ✅constcontext={code:"",push(source){context.code+=source}}returncontext}functiongetNode(node:any,context){const{push}=contextpush(`return '${node.content}'`)}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 17:11:33

3种场景拯救你的桌面颜值:TranslucentTB任务栏美化全攻略

3种场景拯救你的桌面颜值:TranslucentTB任务栏美化全攻略 【免费下载链接】TranslucentTB 项目地址: https://gitcode.com/gh_mirrors/tra/TranslucentTB 你是否也曾经历这样的桌面困境:精心挑选的4K壁纸被厚重的任务栏遮挡大半,精心…

作者头像 李华
网站建设 2026/4/9 16:44:53

WAV文件结构与VS1053 PCM录音实现详解

1. WAV文件格式深度解析:PCM编码与RIFF容器结构WAV(Waveform Audio File Format)并非一种独立的音频编码算法,而是一个基于RIFF(Resource Interchange File Format)规范构建的容器格式。其核心价值在于提供…

作者头像 李华
网站建设 2026/4/13 23:49:13

STM32嵌入式图像存储:BMP无损封装与JPEG硬件编码实践

1. 照相机实验:BMP与JPEG图像文件生成原理与工程实现在嵌入式视觉系统中,将摄像头捕获的原始图像数据保存为标准格式的文件,是连接硬件采集与上位机分析的关键环节。本实验聚焦于STM32平台下,利用OV2640摄像头模块,通过…

作者头像 李华