1. 程式人生 > 實用技巧 >壓縮程式碼如何快速定位到指令碼異常位置

壓縮程式碼如何快速定位到指令碼異常位置

  線上的程式碼幾乎都經過了壓縮處理,幾十個檔案打包成了一個並醜化了的程式碼,當我們收到a is not defined的時候,我們根本不知道這個變數 a 究竟是什麼含義,此時報錯的錯誤日誌顯然是無效的。

  那麼如何去快速定位到指令碼異常的位置呢?

  第一想到的辦法是利用 sourcemap 定位到錯誤程式碼的具體位置

  另外也可以通過在打包的時候,在每個合併的檔案之間新增幾行空格,並相應加上一些註釋,這樣在定位問題的時候很容易可以知道是哪個檔案報的錯誤,然後再通過一些關鍵詞的搜尋,可以快速地定位到問題的所在位置。

一、壓縮程式碼定位錯誤困難

// 1、原始碼(存在錯誤)
function test() {
    noerror 
// <- 報錯 } test(); // 2、經 webpack 打包壓縮後產生如下程式碼 !function(n){function r(e){if(t[e])return t[e].exports;var o=t[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var t={};r.m=n,r.c=t,r.i=function(n){return n},r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{configurable:!1
,enumerable:!0,get:e})},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},r.p="",r(r.s=0)}([function(n,r){function t(){noerror}t()}]); // 3、程式碼如期報錯,並上報相關資訊 { msg: 'Uncaught ReferenceError: noerror is not defined
', url: 'http://127.0.0.1:8077/main.min.js', row: '1', col: '515' }

  此時,錯誤資訊中行列數為 1 和 515。 結合壓縮後的程式碼,肉眼觀察很難定位出具體問題。

二、如何定位到具體錯誤

1、不壓縮 js 程式碼

  這種方式簡單粗暴,但存在明顯問題:1. 原始碼洩漏,2. 檔案的大小大大增加。

2、將壓縮程式碼中分號變成換行

  uglifyjs 有一個叫 semicolons 配置引數,設定為 false 時,會將壓縮程式碼中的分號替換為換行符,提高程式碼可讀性, 如:

!function(n){function r(e){if(t[e])return t[e].exports
var o=t[e]={i:e,l:!1,exports:{}}
return n[e].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var t={}
r.m=n,r.c=t,r.i=function(n){return n},r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:e})},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n}
return r.d(t,"a",t),t},r.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},r.p="",r(r.s=0)}([function(n,r){function t(){noerror}t()}])

  此時,錯誤資訊中行列數為 5 和 137,查詢起來比普通壓縮方便不少。但仍會出現一行中有很多程式碼,不容易定位的問題。

3、js 程式碼半壓縮,保留空格和換行

  uglifyjs 的另一配置引數 beautify 設定為 true 時,最終程式碼將呈現壓縮後進行格式化的效果(保留空格和換行),如

!function(n) {
    // ...
    // ...
}([ function(n, r) {
    function t() {
        noerror;
    }
    t();
} ]);

  此時,錯誤資訊中行列數為 32 和 9,能夠快速定位到具體位置,進而對應到原始碼。但由於增加了換行和空格,所以檔案大小有所增加。

4、SourceMap 快速定位

  SourceMap 是一個資訊檔案,儲存著原始檔的資訊及原始檔與處理後文件的對映關係。

  在定位壓縮程式碼的報錯時,可以通過錯誤資訊的行列數與對應的 SourceMap 檔案,處理後得到原始檔的具體錯誤資訊。

5、開源方案 sentry

  sentry 是一個實時的錯誤日誌追蹤和聚合平臺,包含了上面 sourcemap 方案,並支援更多功能,如:錯誤呼叫棧,log 資訊,issue管理,多專案,多使用者,提供多種語言客戶端等,具體介紹可以檢視 getsentry/sentrysentry.io,這裡暫不展開。