Vue template模板AST解析问题

项目中遇到一个场景,想自动化合并两个vue组件,template自动合并,script合并,style合并。

script的合并目前已经完成,实现了方法和data名字冲突的问题。

style合并简单,字符串拼接。

template合并碰到了些问题。我想像script一样,可以用babel遍历默认导出的对象,然后进行ast转换,替换冲突的data变量。也是目前卡住的地方

我已经使用了vue-template-compiler解析出了template的ast结构,render字符串表示。但是解析出的ast结构,不是规范的es node节点。是vue自己的一套DSL节点。所以势必不能用@babel/traverse直接遍历。

然后我想到一个法子,就是render字符串,render字符串是规范的es语法。我用@babel/parse解析出规范的es node的AST结构,然后就可以用@babe/tarverse遍历了,之后经历AST转换(替换冲突的data变量),重新生成 新的render字符串。这样子就会遇到一个问题,render字符串,能否反编译出vue的 template模板语法?我需要新的template字符串去插入要合并的vue组件的template

问问大伙,是否有render反解析成template字符串(或者反解析成template AST结构)的工具。倘若不行,手写一套render -> vue template的方案是否可行?

目前的demo,name如果有冲突,就单纯的想改成name1(全局替换不太可行,毕竟如果name是解构出来的话就会乱):

<template>
    <div>
        {{name}}
    </div>
</template>

vue-template-compiler解析出的内容
ast

{
    "type": 1,
    "tag": "div",
    "attrsList": [],
    "attrsMap": {},
    "rawAttrsMap": {},
    "children": [
        {
            "type": 2,
            "expression": "\"\\n    \"+_s(name)+\"\\n\"",
            "tokens": [
                "\n    ",
                {
                    "@binding": "name"
                },
                "\n"
            ],
            "text": "\n    {{name}}\n",
            "static": false
        }
    ],
    "plain": true,
    "static": false,
    "staticRoot": false
}

render字符串内容

"with(this){return _c('div',[_v("\n    "+_s(name)+"\n")])}"

目测不太可行,除非只需要处理一个模板语法子集(从业务角度简化需要处理的问题)。否则 Vue 3 的模板静态分析优化就可以照顾到手写 render 函数的场景了。只能说理论上可以做到,但实现难度较大。

不清楚你的业务需求是什么。外套一个函数式组件把两个目标组件包裹起来呢?似乎实现起来还容易一些。

我的需求就是合并两个vue组件的data,methods,watch等内容。并解决他们的冲突问题。是一个能效的工具,不是具体业务。类似vscode插件,帮助开发生成代码模板,但是功能稍强一点。

vue3的模板静态分析优化也还是template的ast到render函数的优化吧,比如删除不会抵达的分支

我想做的有点类似@babel/generator的活,根据template的ast,生成template字符串。暂且认为有工具的话,babel能否遍历template的ast也是头疼的问题。没有官方支持的工具,自己搞逆向确实麻烦。不过,思路感觉还是一个深度优先可以搞出来。

请问问题解决了吗? 现在同样遇到了ast 转换回template 模板的问题,不知可不可行