前言

作為一個前端開發,

在除錯生產環境的程式碼時,是否苦於生產環境程式碼被壓縮,沒有sourcemap?

有沒有想過將生產環境的js直接重定向為本地開發環境的js?

玩微前端時,有沒有想過用本地的子應用js去替換線上的子應用js?

或者有沒有想過修改別人網站的檔案,直接完成某些非常規操作?

最近因為專案開發中有這麼一個小需要,我寫了個chrome擴充套件外掛解決這個問題,當然Edge瀏覽器也能用。

這個擴充套件外掛安裝後,可以直接將一個js重定向為另一個js。

先給上這個擴充套件外掛的倉庫地址:Demo

週六在家半天寫完的程式碼,糙了些,但還算能看。

原理

chrome擴充套件外掛是什麼或者解壓縮的擴充套件外掛怎麼玩,想要了解直接百度,這裡不會講這些。

這裡直接預設大家對擴充套件外掛有一些基礎瞭解。

現在讓我們進入正題,本擴充套件外掛使用的是Manifest V2的一個API:chrome.webRequest,Manifest V3中的declarativeNetRequest是不支援js重定向的。

直接貼簡化後的關鍵程式碼:

// 識別的所有js
let origins = {
common: 'nodeModules_eeb5887.js',
}; // 重定向的js
let redirects = {
common: 'https://s1.hdslb.com/bfs/static/blive/live-region/libs/area-tags/vue_2.6.14.js',
}; chrome.runtime.onInstalled.addListener(() => {
// 請求時回撥
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
// 如果請求的js,以origins.common結尾
if(details.url.endsWith(origins.common)){
// 直接將這個js替換為redirects.common
return { redirectUrl: redirects.common };
}
},
{
types:["script"],
urls: ["*://*/*.js"] // 進一步過濾js,這裡沒做進一步篩選
},
["blocking"]
);
});

我們在程式碼中直接監聽請求,在請求前看請求js的url是否以nodeModules_eeb5887.js結尾,如果是的話直接替換為vue_2.6.14.js

有的朋友可能要問了,這個nodeModules_eeb5887.js和那個那麼長的一串vue_2.6.14.js是啥啊?

我是直接用百度翻譯那個頁面除錯的擴充套件外掛,所以nodeModules_eeb5887.js是百度翻譯的一個js檔案,而很長的那個vue_2.6.14.js是B站隨便找的的一個js檔案。

使用之後可以直接將百度翻譯頁面這個js檔案,重定向為B站的這個js檔案。

使用

其實這個擴充套件外掛只是個demo,所以大家使用的時候可能要替換一點東西才能用,總共兩個地方:

  • 第一點找到manifest.json這個檔案,可以看到有這麼兩行程式碼:

      "permissions": [
    // ...
    "*://fanyi.baidu.com/",
    "*://fanyi-cdn.cdn.bcebos.com/"
    ],

    這是因為我除錯時用的百度翻譯頁面,所以要申請訪問許可權,這裡要把你想要修改的頁面的域名和想要重定向的js的域名都替換上去。

  • 第二點找到background.js這個檔案,可以看到下面這個配置:

      // 識別的所有js
    let origins = {
    common: 'nodeModules_eeb5887.js',
    framework: 'public_10b9d27.js'
    }; // 重定向的js
    let redirects = {
    common: 'https://s1.hdslb.com/bfs/static/blive/live-region/libs/area-tags/vue_2.6.14.js',
    framework: 'https://s1.hdslb.com/bfs/static/blive/live-region/libs/area-tags/vue_2.6.14.js'
    };

    上面的origins寫上被重定向的js,redirects寫上重定向的目標js。至於common和framework這兩個屬性,你看不懂程式碼就別動,只替換值即可。

大概修改完這兩個地方就可以使用了

演示

修改完之後我們用百度翻譯這個網站看下具體的效果,載入完擴充套件外掛後,左鍵點選我們的擴充套件外掛圖示(就是那個寫輪眼的圖示),可以撥出彈窗:

此時我們可以看到common那一行選擇的是線上,此時它不會重定向百度翻譯這個頁面裡js的請求。

我們可以看到這個頁面的nodeModules_eeb5887.js這個js仍然是請求的原地址。

當我們操作彈窗,選擇本地這個選項後:



再去重新整理百度翻譯這個頁面:

我們可以看到頁面在請求nodeModules_eeb5887.js這個js檔案時直接重定向,去請求vue_2.6.14.js這個js檔案了。

總結

寫這個東西自己查查開發文件看看資料就寫完了,就是最開始的方案是使用Manifest V3中的declarativeNetRequest,這玩意看文件看到最後才發現特別標註js不能重定向,浪費了不少時間。

另外一個特別有感觸的點就是,寫這個擴充套件外掛要用原生js。

我一直在寫react,已經很久沒寫原生js了,當我想著單選框radio應該用哪個元素時,一時竟然完全想不起來了,最後靠百度才知道要用input元素。

我又想起了一個月前面試的時候,別人問我js繼承有哪些,我知道他想問的是寄生式組合式這些鬼東西,但是我卻完全回憶不起來了,只能跟他說原型和class,只能說當時非常尷尬。

我曾經還專門寫了篇部落格講這個東西:【JS複習筆記】03 繼承(從ES5到ES6),最終的結果還是記憶模糊。

很多東西長期不用,真的就忘了。

說到部落格,最有趣的是,我自己寫的部落格,自己做的東西很多都忘記了。

比如那個看react的useEffect原始碼的部落格,完全沒什麼印象了。

只能安慰自己是個CPU而不是硬碟了。

好了,不瞎扯了,本篇部落格到此結束。如有疏漏之處,還請不吝賜教。