注册
web

项目没发版却出现了bug,原来是chrome春节前下毒

前言

  • 农历: 腊月二十五

  • 阳历: 2023-01-16

过年和年兽

已经临近过年,公司的迭代版本也已经封版,大家都在一片祥和又掺杂焦虑的气氛中等待春节的到来。 当然,等待的人群里面也有我,吼吼哈嘿。

突然企业微信的一声响,我习惯性的抬头瞅了一眼屏幕,嗯? 来至线上bug群?

不过因为最近咱前端项目也没有发版,心里多少有点底气的。

于是怀着好奇的心情点开了群消息, 准备看看是什么情况。

结果进群看到是某前端页面元素拖拽功能的位置失效了。晴天霹雳啊,我们有一个类似给运营做自定义活动页面,说是无法拖拽了。然后需要做活动比较紧急,需要尽快修复。

这活脱脱就是跟着春节来的年兽啊。我还没放烟花打年兽,年兽就先朝我冲过来了,那说什么也得较量较量了。

96c4ffdb627c4bb9bd6debc2ab5e6b53~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp

项目背景

我们这个功能是属于一个基础功能,通过npm私有仓库维护版本

这个基础功能呢,很多项目中都在使用。

如果基础功能发了新版本,业务部门不进行升级安装,那么这个业务线的项目也是不会出问题的。所以只要线上出了问题,那么要满足两个条件

1、基础功能进行了发布了npm新版本,且这个版本有问题

2、业务部门进行了升级,使用了这个新版本

排查问题

一般来说:造成问题的可能性有

  1. 有人发过新迭代版本

  2. 是不是存在莫名的缓存

  3. 有人在以前的版本里面下毒了,然后现在发作了(可能性不大)

经过粗略排查

猜测结果
1、发版导致?近期两周,该服务部分未更新,排除
2、缓存导致已经清理,没用,排除
3、下毒了看了相关代码,没什么问题,排除

问题初见端倪

接着发生了两件事情

1、然后我本地跑了一下项目的时候,在操作的时候,存在报错。

2、一个测试兄弟反馈说他那儿可以正常操作

这他么莫不是浏览器兼容问题了吧。

我去他那看了一下,都是chrome浏览器(这个项目我们只支持到chrome就可以)

这时的我感觉可能问题有点大了,莫不是chrome又调整了吧

点开测试兄弟的版本看了下,是108,而且处于重启就会升级的状态。 我赶紧回到我的工位,打开电脑发现是109。

d20479d951ac48f68dd8e000a9738e82~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?

在看了下那个报错, event.path为undefined, 这里先介绍下path是个什么玩意,他是一个数组,里面记录着从当前节点冒泡到顶层window的所有node节点。我们借助这个功能做了一写事情。。。

这直接被chrome釜底抽薪了。(path属于非标准api, 这些非标准api慎用,说不定什么时候就嘎了)

解决问题

1、问题一

既然是event.path没了,那么我们怎么办呢,首先得找到代替path的方法, 上面我们也说了,path里面记录的是从当前节点冒泡到顶层window的所有node节点(我们是拖拽事件)

a635607203b142afb517675275eb3661~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?

那么我们可以自己遍历一下当前节点+他的父节点+父节点的父节点+...+window

    let path = [];
   let target = event.target;
   while(target.parentNode !== null){
     path.push(target);
     target = target.parentNode;
  }
   path.push(document, window);
   return path;

在项目里面试了一下,emm,很稳定。

1、问题二

但是我们又遇到了第二个问题,使用到event.path的项目还比较多,这就日了狗了 如果没有更好的方法,那么我只能挨个项目改,然后测试,然后逐个项目发版

这种原始的方法我们肯定是不会采用的,换个思路,既然event下的path被删除了,那么我们在event对象下追加个一个path属性就可以了

当然我们要记得判断下path属性是否存在,因为有部分用户的chrome是老版本的,我们只对升级后的版本做一些兼容就可以了

if (!Event.prototype.hasOwnProperty("path")){
   Object.defineProperties(Event.prototype, {
     path: {
         get: function(){
             var target = this.target;
             console.log('target', target)
             var path = [];
             while(target.parentNode !== null){
                 path.push(target);
                 target = target.parentNode;
            }
             path.push(document, window);
             return path;
        }
    },
     composedPath: {
         value: function(){
             return this.path;
        },
         writable: true
    }
  });
}

这样,我们只需要在每个项目的根html,通过script引入这个js文件就可以了

反思

如题,这个事情怪chrome吗?其实不能怪的。 1、chrome在之前就已经给出了更新通知,只是我们没有去关注这个事情 2、本身event.path不是标准属性,我们却使用了(其实其他浏览器是没有这个属性的,只是chrome提供了path属性, 虽然现在他删除了) 3、总之还是自己不够警惕,同时使用了不标准的属性,以此为戒,共勉

作者:大鱼敢瞪猫
来源:juejin.cn/post/7193520080808837180

0 个评论

要回复文章请先登录注册