項目沒發版卻出現了bug,原來是chrome春節前下毒
highlight: a11y-dark theme: fancy
前言
- 農曆: 臘月二十五
- 陽曆: 2023-01-16
過年和年獸
已經臨近過年,公司的迭代版本也已經封版,大家都在一片祥和又摻雜焦慮的氣氛中等待春節的到來。 當然,等待的人羣裏面也有我,吼吼哈嘿。
突然企業微信的一聲響,我習慣性的抬頭瞅了一眼屏幕,嗯? 來至線上bug羣?。
不過因為最近咱前端項目也沒有發版,心裏多少有點底氣的。
於是懷着好奇的心情點開了羣消息, 準備看看是什麼情況。
結果進羣看到是某前端頁面元素拖拽功能的位置失效了。晴天霹靂啊,我們有一個類似給運營做自定義活動頁面,説是無法拖拽了。然後需要做活動比較緊急,需要儘快修復。
這活脱脱就是跟着春節來的年獸啊。我還沒放煙花打年獸,年獸就先朝我衝過來了,那説什麼也得較量較量了。
項目背景
我們這個功能是屬於一個基礎功能,通過npm私有倉庫維護版本
這個基礎功能呢,很多項目中都在使用。
如果基礎功能發了新版本,業務部門不進行升級安裝,那麼這個業務線的項目也是不會出問題的。所以只要線上出了問題,那麼要滿足兩個條件
1、基礎功能進行了發佈了npm新版本,且這個版本有問題,
2、業務部門進行了升級,使用了這個新版本
排查問題
一般來説:造成問題的可能性有 1. 有人發過新迭代版本 2. 是不是存在莫名的緩存 3. 有人在以前的版本里面下毒了,然後現在發作了(可能性不大)
經過粗略排查
| 猜測 | 結果 | | --- | --- | | 1、發版導致? | 近期兩週,該服務部分未更新,排除 | | 2、緩存導致 | 已經清理,沒用,排除 | | 3、下毒了 | 看了相關代碼,沒什麼問題,排除 |
問題初見端倪
接着發生了兩件事情
1、然後我本地跑了一下項目的時候,在操作的時候,存在報錯。
2、一個測試兄弟反饋説他那兒可以正常操作
這他麼莫不是瀏覽器兼容問題了吧。
我去他那看了一下,都是chrome瀏覽器(這個項目我們只支持到chrome就可以)
這時的我感覺可能問題有點大了,莫不是chrome又調整了吧
點開測試兄弟的版本看了下,是108,而且處於重啟就會升級的狀態。 我趕緊回到我的工位,打開電腦發現是109。
在看了下那個報錯, event.path為undefined, 這裏先介紹下path是個什麼玩意,他是一個數組,裏面記錄着從當前節點冒泡到頂層window的所有node節點。我們藉助這個功能做了一寫事情。。。
這直接被chrome釜底抽薪了。(path屬於非標準api, 這些非標準api慎用,説不定什麼時候就嘎了)
解決問題
1、問題一
既然是event.path沒了,那麼我們怎麼辦呢,首先得找到代替path的方法, 上面我們也説了,path裏面記錄的是從當前節點冒泡到頂層window的所有node節點(我們是拖拽事件)
那麼我們可以自己遍歷一下當前節點+他的父節點+父節點的父節點+...+window
js
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、總之還是自己不夠警惕,同時使用了不標準的屬性,以此為戒,共勉