版权声明:本人文章仅在掘金平台发布,请勿抄袭搬运,转载请注明作者及原文链接 🦀
阅读提示:网页版带有主题和代码高亮,阅读体验更佳 🍇
最近写代码遇到一件烦心事儿。
项目临近上线,来了几个大需求,其他人要么忙,要么 hold
不住,只能我硬着头皮上。
要改内部的一个最核心的组件包,虽然之前我都做过很多这个包的需求了,但是因为这块真的很复杂,很多时候我都需要重新看代码。
这次改的这部分,核心组件 3000+
行,总行数近 10000
行。
问题就在于,我的项目中其它文件的 eslint
都是正常的,唯独这个核心文件的 eslint
崩了,整个文件功能非常复杂,这种地方的代码,改一处就牵一发动全身,导致很多莫名其妙的问题。
问题来了,我的需求每次都是大改。。。
我这人稍微有点代码洁癖,if
里的代码一多,就想着拆出来,这不拆不要紧,拆了问题一大堆。
其他文件因为有 eslint
检查,有点问题就提示了,但是这个文件很奇怪,eslint
不检查!!
我改动面积又大,每次手动检查完没有问题了,我就推分支上去打包,打完包部署线上再一看,功能又不生效。
就这样人肉检查了很久,代码推了好几个版本,但是因为改动比较大,人肉检查疏漏还是很多,拆出来的代码很多时候不在原来的作用域了,找不到对应的声明,就报错走不下去了。
一直改到差不多了,改到最后代码也没报错,但是功能还是没生效,最关键的是,我打的 console.log
也没出来!
这难搞哦。
那原因到底是啥呢?
问题1:代码没报错,console.log
为啥不执行?
这里其实原因很简单,因为我习惯使用可选链操作符 ?.
,这能有效防止属性不存在时代码报错导致线上白屏。但是正是因为这个操作符,导致我错误代码没报错,又不往下执行,所以我的功能不生效,打的 log
也出不来。
那这和 ?.
到底啥关系?为啥没有属性你还访问呢?
前面提到,我把打码拆出来了,因为以前都是挤在一个 if
分支里,代码非常臃肿,这回还加功能,更加臃肿了,所以不得不拆。但是拆出来的代码重新组成一个函数,代码都是复制粘贴的,不在原来的作用域后,代码自然报错了。加上我 eslint
刚好在此文件里失效了,没有提示,我遗漏了好几个变量,导致此次问题的产生。
那解决办法是啥呢?
办法1:不要写 ?.
操作符,有问题就暴露(这要是线上直接白屏了,算生产事故了就)。
办法2:最外层加一个 try catch
,捕获一下代码报错。
最后呢就是采用了方案2,发现了几个隐秘的变量,最终功能正常上线。
不过,我气不打一处来,这凭啥和你同级的组件文件都能被检查,就你不行???要是有检查,我也不至于耽误那么多功夫。这必须得查个清楚。
问题2:为什么 eslint
检查会单独在此文件失效?
其实 eslint
已经很早就把问题暴露给我了,每次我在 commit
时,git hook
都会执行 eslint --fix
,但是每次都报了下面的这个错误。
这个报错的意思似乎是说某段代码是 unreachable
,也就是不能到达的意思。
不能到达是指?暂时不知道,但是我需求紧急诶,不想管,我只想尽快提测。
怎么解决呢?我一般直接 git commit -m 'feat: xxxx' --no-verify
,加一个 --no-verify
参数也就忽略了检查。
但是就是因为每次都忽略,导致我没有去仔细检查代码,追溯 eslint
失效的原因,导致我问题代码上线运行,功能不生效。
那回到标题,为什么 eslint
在其它文件都生效,为啥就这个文件不行?
那么我的排查思路来了。
排查文件首行是否存在禁用注释
可以在代码的最顶部通过注释 /** eslint-disabled */
来对该文件进行 eslint
全局禁用。
但我检查了之后,并没有发现,那看来不是这个原因。
此类注释还可以单独针对某一条规则进行禁用,例如,我写了一个表达式,用了下划线:__test_url__
,这时候 eslint
会报错,我既不希望它在此处校验我的代码,也不希望在配置文件里禁用该规则 ------ 因为可能其他人需要该规则,我就可以使用注释对该条 eslint
规则进行禁用。
例如:
js
/** eslint-disabled no-underscore-dangle */
const testURL = window.__test_url__;
如果将注释放在文件最顶部,则对整个文件都生效,该条规则在整个文件中将被禁用。
排查 .eslintignore
文件是否忽略了本文件
如果不希望 eslint
对某些文件进行代码检查,我们配置忽略文件:.eslintignore
。写法和其它的 ignore
文件是一样。
txt
build/
dist/
lib/
...
但是我并没有在此文件中看到相关的配置。
不过既然都讲到这里了,顺带讲讲这个配置规则是怎么写的。
一般我们的 ignore
文件都是配置在根目录下的,不管你是 gitignore
还是 eslintignore
。
但是其实这些忽略文件,我们可以写在任意位置,它查找匹配的位置一般是基于其所在位置进行,也局限在其所在目录范围
记住这个特性,虽然一般没人会将配置文件放在目录内部,但是这对理解此类配置文件很关键。
我们就假设都是配置在根目录下。
如果直接书写一个单词,那么意思就是匹配文件及文件夹,不管你层级嵌套多深。
这里会命中 lib
同名的文件夹及文件,且不管你层级多深,只要你在这个项目里都给你命中。
如果是书写类似 /lib
的规则,那么其匹配的是 lib
文件夹下的所有文件。那其它目录,例如什么 a/lib
、b/lib
、c/lib
、d/lib
的文件夹或者文件则不会去匹配。
那如果我书写的规则就是 a/lib
呢?那它匹配的就是 a
目录下的 lib
文件夹下的所有文件。
如果我书写的规则是 lib/
呢?那它会匹配项目下所有名为 lib
的文件夹。
那还有类似 *
、**
的匹配规则,这种匹配规则在很多配置里都是很常见的,*
差不多可以理解为任意文件名,**
则能理解为任意层级,匹配多级文件夹。
问题到底出在哪里呢?
既然能排查的点都查了,到底问题出在哪里呢?
当我白丝(百思)不得其姐(解)的时候,我忽然想到 unreachable
这个报错。
eslint
是静态分析,本质上也是 AST
语法树,靠词法来分析代码的错误,那它说不可到达,也就是说,eslint
去解析代码的时候,发现了一些它不认识的代码,导致他解析不通过。
另一个支撑这个观点的现象是,我看到项目里的 eslint
还是 4
的大版本,而现在的最新版都已经是 8
了,加上最近在项目里用了类似 ??
操作符,很多新语法,极有可能是新语法导致的。
所以为了验证猜想,我立即升级 eslint
至最新版,果然!代码检查出现了,文件里一堆报红,可喜可贺。
但是代码提交还是遇到了问题,为什么呢?eslint
太新了,但是配套的插件之类的没有更新,版本跨度过大,导致 eslint
和插件之间的配合出现了问题。
怎么办呢?
那当然就是渐进升级啦,先试试 5
的大版本是否可行。
下载大版本 5
后代码检查出现,代码提交也正常,完美解决问题!
写在最后
如果你在网上搜这个问题的答案,几乎清一色都是告诉你执行 --no-verify
参数,但是没人告诉你真正的解决办法。然后这种答案治标不治本,希望我的文章对你解决问题有所帮助。
敬请三连~
欢迎加群
最近新建了一个前端交流群,群里目前都是我的朋友,基本都是高学历的刻苦人士,个个都能带你卷~
群里写 React
、Vue
、Node
的小伙伴都有,大多是两三年经验的同学,群里很希望有新鲜血液融入。
群里还很需要一位资深的前端大佬坐镇,有没有大佬愿意来指教一二的?
欢迎大家加入。
关注我,后台私信 VX
二维码拉你进群。
往期推荐
别人休息我努力,悄悄写个 cli 工具,必须提升效率,skr~ 60+
👍🏻 110+
💚
一文掌握 eslint,再也不怕项目报错 20+
👍🏻 30+
💚
开发一个 npm 库应该做哪些工程配置? 40+
👍🏻 50+
💚
分享我在前端学习与开发中用到的神仙网站和工具 40+
👍🏻 110+
💚
uniapp 踩坑记录(二) 130+
👍🏻 150+
💚
闲来无事,摸鱼时让 chatgpt 帮忙,写了一个 console 样式增强库并发布 npm 100+
👍🏻 110+
💚
uniapp 初体验踩坑记录 30+
👍🏻 60+
💚
两小时学会 JS 正则表达式,终身不忘 50+
👍🏻
【一年前端必知必会】如何写出简洁清晰的代码 50+
👍🏻
【一年前端必知必会】了解 Blob,ArrayBuffer,Base64 40+
👍🏻 90+
💚