写一个Eslint插件:VueTemplate中Class顺序的检查和自动修复

有小伙伴问我如何修复 vue template 中的 class 名的顺序、属性名顺序,还有 options 中的属性顺序的问题,用 eslint 可以做到么。

成都创新互联是一家专注于网站建设、成都网站设计与策划设计,乌鲁木齐网站建设哪家好?成都创新互联做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:乌鲁木齐等地区。乌鲁木齐做网站价格咨询:18982081108

答案是能,但是需要写 eslint 插件来检查和修复。

考虑到他可能没有写过 eslint 插件,所以我先把相对简单的校验和修复 class 名的顺序的插件摘出来实现了一下。

思路分析

首先,eslint 是否能 parse vue 的模版呢?

是可以的,因为 eslint 的 parser 支持切换,而 vue 实现了对应的 parser,所以可以在 eslint 中使用 vue-eslint-parser 来解析模版。

我们可以使用 astexplorer.net 来看一下 parse 生成的 AST。

我们要处理的是 class 属性,也就是 VAttribute 的 value 部分

可以支持传入比较器来自定义顺序,排序完之后设置回去。

当然,vue 的模版支持 {} 来引用 data,这种我们不处理,可以过滤掉。

思路比较简单,下面我们写代码来实现一下。

代码实现

我们可以给插件起名为 vue-class-order。

首先,我们引入 eslint,设置 useEslintrc 为 false 也就是不使用配置文件,然后在 overrideConfig 属性设置各种配置,rules 里填入这个插件。

 
 
 
 
  1. const { ESLint } = require("eslint"); 
  2.  
  3. const engine = new ESLint({ 
  4.     fix: false, 
  5.     overrideConfig: { 
  6.         parser: 'vue-eslint-parser', 
  7.         parserOptions: { 
  8.             sourceType: 'module' 
  9.         }, 
  10.         rules: { 
  11.             "vue-class-order": [ "error" ] 
  12.         } 
  13.     }, 
  14.     rulePaths: ['./'], 
  15.     useEslintrc: false 
  16. }); 

这里的 parser 要使用 vue-eslint-parser 才可以,并且 rulePaths 也就是查找 rule 的路径也要设置下。fix 设置为 false 代表不自动修复。

之后,调用它的 lintText 方法来对代码进行 lint。

 
 
 
 
  1. (async function main() { 
  2.   const results = await engine.lintText(` 
  3.  
  4.  
  5.  
  6. `); 
  7.  
  8.   console.log(results[0].output); 
  9.  
  10.   const formatter = await engine.loadFormatter("stylish"); 
  11.   const resultText = formatter.format(results); 
  12.   console.log(resultText); 
  13. })(); 

之后在插件里面取出来:

 
 
 
 
  1. module.exports = { 
  2.      meta: { 
  3.          fixable: true 
  4.      }, 
  5.      create(context) { 
  6.          const comparator = context.options[0]; 
  7.           
  8.      } 
  9.  }; 
  10.   

这里的 comparator 就是从 context 中取出的参数。

插件的结构是 meta,create 两部分,meta 是各种描述插件本身的元信息,create 部分是插件的主要逻辑。

create 部分返回一个 visitor,声明对什么节点进行什么操作。但是因为我们用的 parser 是 vue 自定义的(vue-eslint-parser),所以这里 visitor 也要用它提供的,也就是:

 
 
 
 
  1. module.exports = { 
  2.      meta: { 
  3.          fixable: true 
  4.      }, 
  5.      create(context) { 
  6.          const comparator = context.options[0]; 
  7.          return context.parserServices.defineTemplateBodyVisitor({ 
  8.             "VAttribute[key.name=class]"(node) {   
  9.                  
  10.             } 
  11.          }); 
  12.      } 
  13.  }; 

在 context.parserServices.defineTemplateBodyVisitor 方法中传入具体的 visitor,比如我们需要对 VAttribute 节点做处理。

eslint 支持esqury 的写法,也就是可以通过选择器的方式来指定要处理的节点,这里我们指定 key.name 为 class 的 VAttribute 节点

之后要拿到节点的值,排序一下,看看是否是对的,不对就报错。

 
 
 
 
  1. "VAttribute[key.name=class]"(node) {   
  2.     const classStr = node.value.value; 
  3.     if (!classStr.includes('{')) { //过滤掉有插值表达式的 class 
  4.         const curOrder = classStr.split(/\s/); 
  5.         const shouldOrder = [...curOrder].sort(comparator); 
  6.         if (curOrder.some((item, index) => curOrder[index] !== shouldOrder[index])) { 
  7.             context.report({ 
  8.                 node, 
  9.                 message: 'className 顺序不对:' + classStr, 
  10.                 loc: node.value.loc 
  11.             }); 
  12.         } 
  13.     } 

这样,我们就实现了对 vue 模版中 class 的顺序的 lint。

我们试一下效果:

我们实现了对 className 顺序的 lint!

当然,只报错不修复比较耍流氓,我们还得实现下自动修复。

修复的话就是把 value 的部分替换掉,也就是拿到 value 的 range(开始和结束的下标),把该 range 的文本使用 fixer 的 api 替换掉。(这里要考虑引号)

 
 
 
 
  1. context.report({ 
  2.     node, 
  3.     message: 'className 顺序不对:' + classStr, 
  4.     loc: node.value.loc, 
  5.     *fix(fixer) { 
  6.         const [ start, end ] = node.value.range; 
  7.         yield fixer.replaceTextRange([start + 1, end - 1], shouldOrder.join(' ')) 
  8.     } 
  9. }); 

我们把 fixer 设置为 true,再跑一下:

做了自动的修复,没有报错了!

我们实现了对 vue 模版中 class 的顺序的检查和自动修复!

总结

Eslint 可以基于 AST 做代码格式的检查和修复。

基于 AST 那就得有对应的 parser, eslint 支持 parser 的扩展,所以有很多 eslint parser 可用,要 parse vue 模版就可以用 vue-eslint-parser。可以用 astexplorer.net可视化的查看。

我们要实现对 vue 模版中 class 的顺序的检查,分析之后就是要取出 key 为 class 的 VAttribute 节点的 value,然后根据传入的比较器进行排序,如果顺序不一致,就报错。并且还可以通过 fixer 的 api 进行自动修复,也就是对该段 range 的文本进行替换。

这里我们通过 api 来调用的 eslint,通过 cli 也一样。

这篇文章实现了一个相对简单的 eslint 插件,对 vue template 中的代码格式做了检查和修复,希望能够帮助大家理清 eslint 插件开发的思路。

新闻名称:写一个Eslint插件:VueTemplate中Class顺序的检查和自动修复
分享路径:http://www.stwzsj.com/qtweb/news37/15187.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联