Vue中通过jscodeshift操作AST抽象语法树的方式

jscodeshift + codemods就是项目重构/升级的超级利器,以前在react和纯js项目深刻体会到自动化发挥到巨大作用。

最近在工作中尝试用处理vue代码,结果却不尽如人意。

  • 无法只使用jscodeshift完成
  • 需要区分vue后缀和js后缀
  • template代码无法输出

解析适配vue代码

vue文件包含三块内容:templatescriptstyle

我首先采用的方案是:@vue/compiler-dom获取 templatevue-template-compiler获取script

script的内容不需要特殊处理,提取出代码后交由jscodeshift即可。

const compiler = require('vue-template-compiler');

const sfcDescriptor = compiler.parseComponent(fileInfo.source);

// sfcDescriptor.script 就是对应的script代码块
console.log(sfcDescriptor.script)

sfcDescriptor里面还包含了template的内容,所以我们不需要单独获取模板内容,可以这样:

const domCompiler = require('@vue/compiler-dom');

const templateAST = domCompiler.compile(sfcDescriptor.template.content)

这种方式最大的问题在于处理AST麻烦,如何输出源码也是很大的问题,我目前没有找到可以直接使用的工具,如果想打通整个流程,可能需要写一个generate插件读取AST结构,再输出源码。

jscodeshift支持vue文件

function vueAdapterWrapper(transform) {
    return function wrappedTransform(fileInfo, api, options) {
        // 如果不是vue文件,则使用jscodeshift默认处理
        if (!fileInfo.path.endsWith('.vue')) {
            return transform(fileInfo, api, options);
        }

        // 否则按照vue文件处理

        // 1. template
        // 2. script
    }
}

module.exports = function vueAdapter(transform) {
    return vueAdapterWrapper(transform);
}

使用时通过下面方式:

const someCodemod = require('some-codemod');

module.exports = vueAdapter(someCodemod);

结果

使用jscodeshift处理script代码,目前看是没有问题的,麻烦在于template的处理,我另外想到的是可以直接用babel或者基于ast的工具(如PostHTML),这样只要能解决语法解析的问题,就什么都不是问题了。

0 条评论