【工具】es6-killer---别让es6毁了你的老项目!!!

145 阅读8分钟

先放插件链接:

github:

lenovo-filez/es6-killer​github.com/lenovo-filez/es6-killer

npm:

es6-killer​www.npmjs.com/package/es6-killer

前段日子我的leader神秘兮兮的告诉了我一个神秘的任务,他告诉我说只要完成,就可以升职加薪,走向人生巅峰...(当然这是虚构情节)废话不多说,到底是什么任务需要做呢?没错,就是检测老项目 (非VUE项目) 中的es6语法,并且像揪出混蛋一样的揪出他们。为什么会有这样的需求产生呢?那当然是:

神奇的IE浏览器

IE是一个相当神奇的浏览器,令众多前端开发者脑壳痛,恨不得将IE从世界上删除,对IE的兼容与适配一次一次挑战着前端开发者的耐心。那怎么办呢,还是得屈服于IE。于是乎,我们的老项目在一些IE浏览器上发生一些令人烦躁的错误,一些常见的es6语法就会导致项目在IE浏览器上发生崩溃。(老项目心声:我太难了......)例如,我们常常将一些变量定义时用const或者let定义,亦或是使用了一些箭头函数,一些版本稍微低一些的IE浏览器就罢工了,想要造反。为了安抚‘民心’,我们只能在老项目里禁用es6语法。但是,人总有手滑或者粗心的时候,一个不小心,es6语法又写上去了,在某一块功能,项目就又挺不住了,我们就又得去一点点找,浪费了大量的时间和精力。

那我们就去想想办法去会会这个问题吧。

ES-check

起初给出了三种实现方案:

经过调研,AST语法树(abstract syntax code,AST),作为源代码的抽象语法结构的树状表示,树上的每个节点都表示源代码中的一种结构,这所以说是抽象的,是因为抽象语法树并不会表示出真实语法出现的每一个细节。这种抽象的概念对于我而言很难去熟练地掌握运用,于是去社区上去找相关的解析器来生成对应的语法树,但是大批量的代码导入解析也是一个相当繁琐的过程,遂放弃这一方法。

自己进行正则校验同样面临着类似的挑战,如何识别es6语法光凭几个正则匹配难以覆盖到整个项目里去,而且大量的代码文件去一一进行正则匹配也相当的低效,于是我注意到了一个好东西:Acorn。

按照 Acorn 作者的说法,当时造这个轮子更多只是好玩,速度可以和 Esprima 媲(Esprima 是很经典的一个解析器,Acorn 在它之后诞生),但是实现代码更少。其中比较关键的点是这两个解析器出来的 AST 结果(对,只是 AST,tokens 不一样)都是符合 The Estree Spec 规范(这是 Mozilla 的工程师给出的 SpiderMonkey 引擎输出的 JavaScript AST 的规范文档,也可以参考:SpiderMonkey in MDN)的,也就是得到的结果在很大部分上是兼容的。

现在很出名的 Webpack 解析代码时用的也是 Acorn。

于是查找到了使用Acorn解析器的插件:es-check

此插件需使用命令行驱动,如下

es-check es5 './vendor/js/*.js' './dist/**/*.js'

使用起来也蛮方便,但是就在我使用起来沾沾自喜的时候,新的问题出现了:扫描出来的es6语法实在是太多了,大部分是来自于node_modules中的文件,虽然有--not参数可以配置忽略文件,如果忽略的文件过多--not也很繁琐还有输错的可能,而且我修改了哪些文件都需要进行一次全局扫描,还是不够节约时间,也没办法阻止粗心的人将含有es6代码提交到远程仓库,令人头大,这可怎么办呢?

husky与lint-staged的加入

husky 是一个 Git Hook 工具。本文主要实现提交前 eslint 校验和 commit 信息的规范校验,可以防止使用 Git hooks 的一些不好的 commit 或者 push。

lint-staged 是一个在git暂存文件上运行linters的工具,当然如果你觉得每次修改一个文件就给所有文件执行一次lint检查不恶心的话,这个工具对你来说就没有什么意义了,请直接关闭即可。它将根据package.json依赖项中的代码质量工具来安装和配置husky和lint-staged,因此请确保在此之前安装(npm install --save-dev)并配置所有代码质量工具,如ESlint。

这两个可是两个神器,组合起来可大有威能。我们可以在lint-staged里使用es-check命令,接到获得改变的文件,从而只检测我们修改的文件。而在husky里的‘pre-commit’的钩子里,我们可以就这么愉快的使用lint-staged了。

解释
 "husky": {
   "hooks": {
      "pre-commit": "lint-staged"
    }
  },
 "lint-staged": {
    "*.js": "es-check es5"
  },

黑名单的问题还是没有解决。

es6-killer诞生

为了解决黑名单配置问题,以及全局扫描和commit扫描的问题,我打算将此插件进行二次封装,并且开源使用。

首先是黑名单配置问题:

我设置了.escheckignore文件来配置要忽略的文件,而使用该插件的人也可以灵活的配置他们想要忽略的文件列表,不再用一个一个去塞,如果不配置该文件,我默认忽略node_modules,不用再扫描时一大堆es6检测结果报错。

而全局与commit时的扫描也做了分明处理:

 "scripts": {
    "es-check": "node node_modules/es6-killer/index.js"
  },

这里配置好后可以使用npm run es-check进行全局扫描检测es6语法,当然忽略了你的.escheckignore里的文件列表

解释
 "husky": {
    "hooks": {
    "pre-commit": "lint-staged",
     }
  },
 "lint-staged": {
    "*.js": "node node_modules/es6-killer/index.js"
  },

这里配置好后将会在你修改好文件准备git commit时,调用钩子检测你的语法是否合乎规范,如果有es6语法,就会阻止本次commit提交。

到此,基本任务告一段落,实现了对项目es6语法的检验,也可以成功给项目布上忽略黑名单,欢迎您来使用。


本文是我刚毕业的时候在第一家公司写的,标题写的相当标题党,当时开发了人生的第一款开源工具,并且实实在在为公司解决了问题,如今回头看,也令人唏嘘不少。 首先有几个问题可以回答下:
1. 这个项目为啥不用`babel`去把代码转成es5呢?
>- 经过这些年的工作,我也越来越明白当初的这个想法其实是反过来的,正常的逻辑就应该是转化成 es5的代码。但是由于项目实在是年久失修,用不了babel,直接往崩了跑。事已至此,是非我也无心解释,总之就是用不了用不了用不了。。。。。。
2. 四五年前的东西咋还拿上来说?
我只能说,时光荏苒,岁月如梭。当时做的东西写的文档,有些留下了,有些找不到了,回头整理的时候,才发现内容东写了几篇西写了几篇。所以准备一起归纳到掘金上看看。
我还记得我第一家公司离职的时候,领导跟我说,你现在凭借着这个 `es6-killer`是可以找到一份不错的 offer 的,只要你完完全全理解了它的背景,但是如果两三年后你的简历里还是只有这个可以说,那你就没什么值得吹嘘的了。事到如今,我的简历里`es6-killer`还是躺在我的项目介绍第一个。虽然简历里多了一些其他的内容,比如什么微前端,什么HarmonyOS 等等,但是我还是觉得自己对它可说的更多。所以归根结底我还是一个普普通通的前端开发,写一写普普通通的代码,那么当时刚毕业的时候意气风发的我去哪里了呢?
最终我还是接受了自己只是芸芸众生中的普通一员,没有那么高超的能力与思想,当时觉得自己“老子天下最牛逼”的想法不过是一种初生牛犊不怕虎的想法罢了。但是我也不甘于自己平平淡淡的混完开发生涯,所以要把自己的所谓的一些积累留下来。

当时评论区被喷完全不知道怎么反驳:

image.png

image.png