成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

細(xì)說 js 壓縮、sourcemap、通過 sourcemap 查找原始報(bào)錯(cuò)信息

douzifly / 1964人閱讀

摘要:文件就是記錄了從源代碼文件到壓縮文件的一個(gè)代碼對(duì)應(yīng)關(guān)系記錄表,通過壓縮文件和文件可以原原本本找出源代碼文件。

細(xì)說 js 壓縮、sourcemap、通過 sourcemap 查找原始報(bào)錯(cuò)信息 1. js 壓縮

js 壓縮對(duì)前端開發(fā)者來說是一門必修課。

一般來說,壓縮 js 主要出于以下兩個(gè)目的:

減小代碼體積,加快前端資源加載速度

保護(hù)源代碼不被別人獲取

壓縮 js 使用的工具庫:

UglifyJS2: 壓縮 es5

uglify-es: 壓縮 es6+

closure-compiler、closure-compiler-js: googlejs 壓縮、優(yōu)化工具

壓縮 js 的主要過程:

移除無用代碼

混淆代碼中變量名稱、函數(shù)名稱等

預(yù)編譯代碼

對(duì)結(jié)構(gòu)進(jìn)行扁平化處理

1. 移除無用代碼

去掉所有對(duì)解析引擎來說無用的字符,包括空格、注釋、換行、沒有用的變量聲明、函數(shù)聲明等。

2. 混淆代碼中變量名稱、函數(shù)名稱等

把一些局部變量名稱、函數(shù)名稱等用 a, b, ...$1, $2, ...、_1, _2, ... 之類的簡略字符進(jìn)行替換,達(dá)到混淆的目的。

源代碼

(function () {
  var hello = "hi";
  var print = function (str) {
    console.log(str);
  };

  print(hello);
})();

壓縮后的代碼(僅演示混淆功能)

(function () {
  var a = "hi";
  var b = function (c) {
    console.log(c);
  };

  b(a);
})();
3. 預(yù)編譯代碼

把不依賴外部環(huán)境的邏輯提前進(jìn)行運(yùn)算,并把運(yùn)算結(jié)果替換到相應(yīng)的源碼處,然后從源碼中移除這段邏輯。

源代碼

(function () {
  var hello = "hi" + " everyone, ";
  var count = 3 * 5;

  console.log(hello + count + " girls");
})();

壓縮后的代碼(僅演示預(yù)編譯功能)

(function () {
  var hello = "hi everyone, ";
  var count = 15;

  console.log(hello + count + " girls");
})();
4. 對(duì)結(jié)構(gòu)進(jìn)行扁平化處理

對(duì)于 js 來說,嵌套越深,執(zhí)行越慢,對(duì)代碼進(jìn)行扁平化處理也是優(yōu)化代碼的一種方式。

源代碼

(function () {
  var say = {
    hello: function (str) {
      console.log("hello " + str);
    }
  };

  say.hello("everyone");
})();

壓縮后的代碼(僅演示扁平化結(jié)構(gòu)功能)

!function(str){console.log("hello "+str)}("everyone");
完整示例

源代碼

(function () {
  var say = {
    hello: function (str) {
      console.log("hello " + str);
    }
  };

  say.hello("everyone");
})();

壓縮后的代碼

!function(l){console.log("hello "+l)}("50 girls");
2. sourcemap

通常 js 壓縮后只有一行代碼,并且里面的變量名與函數(shù)名等都是混淆了的,這在實(shí)際運(yùn)行中會(huì)有一個(gè)問題,就是 js 的報(bào)錯(cuò)信息將會(huì)失真,無法追蹤到是在源代碼哪一行哪一列報(bào)的錯(cuò)。

sourcemap 便是為了解決這個(gè)問題而生的。

sourcemap 文件就是記錄了從源代碼文件到壓縮文件的一個(gè)代碼對(duì)應(yīng)關(guān)系記錄表,通過壓縮文件和 sourcemap 文件可以原原本本找出源代碼文件。

查看阮一峰老師的 JavaScript Source Map 詳解 了解 sourcemap 的原理與格式。

一般在壓縮 js 的過程中,會(huì)生成相應(yīng)的 sourcemap 文件,并且在壓縮的 js 文件末尾追加 sourcemap 文件的鏈接 //# sourceMappingURL=bundle-file-name.js.map。這樣,瀏覽器在加載這個(gè)壓縮 js 的時(shí)候,就知道還有一個(gè)相應(yīng)的 sourcemap 文件,也一并加載下來,運(yùn)行的過程中如果 js 報(bào)錯(cuò),也會(huì)給出相應(yīng)源代碼的行號(hào)與列號(hào),而非壓縮文件的。

比如,對(duì)下面的源碼進(jìn)行壓縮:

(function () {
  var say = {
    hi: function () {
      console.log("hi");
    }
  };

  say.hello();

  return say;
})();

未加 sourcemap 文件時(shí),報(bào)錯(cuò)信息是:

加上 sourcemap 文件時(shí),報(bào)錯(cuò)信息是:

sourcemap 擴(kuò)展

webpack 對(duì) sourcemap 做了擴(kuò)展,定義在 devtool 配置項(xiàng)中:

eval: 每個(gè)模塊都使用 eval() 執(zhí)行,并且都有 //@ sourceURL,構(gòu)建很快,但無法正確顯示行號(hào)

eval-source-map: 每個(gè)模塊使用 eval() 執(zhí)行,并且 source map 轉(zhuǎn)換為 DataUrl 后添加到 eval() 中,一般開發(fā)模式中使用這種方式

cheap-eval-source-map: 類似 eval-source-map,但只映射行,不映射列,并忽略源自 loadersource map,僅顯示轉(zhuǎn)譯后的代碼

cheap-module-eval-source-map: 類似 cheap-eval-source-map,但會(huì)保留源自 loadersource map

inline-source-map: source map 轉(zhuǎn)換為 DataUrl 后添加到 bundle

cheap-source-map: 只映射行,不映射列,并忽略源自 loadersource map,僅顯示轉(zhuǎn)譯后的代碼

inline-cheap-source-map: inline-source-mapcheap-source-map 的結(jié)合

cheap-module-source-map: 類似 cheap-module-eval-source-map,但不使用 eval() 執(zhí)行

inline-cheap-module-source-map: inline-source-mapcheap-module-source-map 的結(jié)合

source-map: 整個(gè) source map 作為一個(gè)多帶帶的文件生成,產(chǎn)品環(huán)境一般使用這種模式

hidden-source-map: 類似 source-map,但不會(huì)把 //# sourceMappingURL=bundle-file-name.js.map 追加到壓縮文件后面

nosources-source-map: 類似 source-map,但只有堆棧信息,沒有源碼信息

更詳細(xì)信息可以參考:

webpack devtool(英文)

webpack devtool(中文)

使用建議

對(duì)于使用 webpack 來構(gòu)建項(xiàng)目,建議在開發(fā)時(shí)使用 eval-source-map,產(chǎn)品環(huán)境使用 source-map。

因?yàn)橛脡嚎s文件與 sourcemap 文件是可以原原本本的找到源代碼的,所以,為了保護(hù)源代碼,可以這樣隱藏 sourcemap 文件:

web 服務(wù)器設(shè)置外部不能訪問 sourcemap 文件,只能內(nèi)部訪問

直接把 sourcemap 文件存放到其他地方

3. 通過 sourcemap 查找原始報(bào)錯(cuò)信息

一般而言,在產(chǎn)品階段,我們會(huì)用 window.onerror 來捕獲 js 報(bào)錯(cuò),然后上報(bào)到服務(wù)器,以此來收集用戶使用時(shí)發(fā)生的 bug

window.onerror = function(message, source, lineno, colno, error) {
  // message: 錯(cuò)誤信息
  // source: 報(bào)錯(cuò)腳本的 url 地址
  // lineno: 行號(hào)
  // colno: 列號(hào)
  // error: 錯(cuò)誤對(duì)象
  // 上報(bào)必要的信息到服務(wù)器
}

但產(chǎn)品環(huán)境的代碼都是壓縮的,行號(hào)和列號(hào)都是失真的,所以就需要用 sourcemap 文件來找到錯(cuò)誤對(duì)應(yīng)源代碼的行號(hào)與列號(hào),以及其他的信息。

使用工具: mozilla/source-map

源代碼

(function () {
  var say = {
    hi: function () {
      console.log("hi");
    }
  };

  say.hello();

  return say;
})();

壓縮后報(bào)錯(cuò)信息

window.onerror = function(message, source, lineno, colno, error) {
  console.log(`message: ${message}`);
  console.log(`source: ${source}`);
  console.log(`lineno: ${lineno}`);
  console.log(`colno: ${colno}`);
  console.log(`error: ${error}`);
}

// message: Uncaught TypeError: e.hello is not a function
// source: url/to/bundle.min.js
// lineno: 1
// colno: 982
// error: TypeError: e.hello is not a function

通過 source-map 查找原始報(bào)錯(cuò)信息

const fs = require("fs");
const SourceMap = require("source-map");

const { readFileSync } = fs;
const { SourceMapConsumer } = SourceMap;

const rawSourceMap = JSON.parse(readFileSync("path/to/js/map/file", "utf8"));

SourceMapConsumer.with(rawSourceMap, null, consumer => {
  const pos = consumer.originalPositionFor({
    line: 1,
    column: 982
  });

  console.log(pos);
});

查找到的原始信息

{ 
  source: "path/to/index.js",
  line: 8,
  column: 7,
  name: "hello" 
}

這樣,便找到了原始報(bào)錯(cuò)信息:

原始報(bào)錯(cuò)文件:path/to/index.js

原始報(bào)錯(cuò)行號(hào):8

原始報(bào)錯(cuò)列號(hào):7

原始對(duì)象名稱:hello

如此,便能一下子就找到錯(cuò)誤在哪里了。

更多用法,參考 mozilla/source-map

后續(xù)

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99228.html

相關(guān)文章

  • 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目

    摘要:從到再到搭建編寫構(gòu)建一個(gè)前端項(xiàng)目選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架搭建一個(gè)前端項(xiàng)目的方式有兩種選擇現(xiàn)成的項(xiàng)目模板自己搭建項(xiàng)目骨架。使用版本控制系統(tǒng)管理源代碼項(xiàng)目搭建好后,需要一個(gè)版本控制系統(tǒng)來管理源代碼。 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目 1. 選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架 搭建一個(gè)前端項(xiàng)目的方式有兩種:選擇現(xiàn)成的項(xiàng)目模板、自己搭建項(xiàng)目骨架。 ...

    call_me_R 評(píng)論0 收藏0
  • 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目

    摘要:從到再到搭建編寫構(gòu)建一個(gè)前端項(xiàng)目選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架搭建一個(gè)前端項(xiàng)目的方式有兩種選擇現(xiàn)成的項(xiàng)目模板自己搭建項(xiàng)目骨架。使用版本控制系統(tǒng)管理源代碼項(xiàng)目搭建好后,需要一個(gè)版本控制系統(tǒng)來管理源代碼。 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目 1. 選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架 搭建一個(gè)前端項(xiàng)目的方式有兩種:選擇現(xiàn)成的項(xiàng)目模板、自己搭建項(xiàng)目骨架。 ...

    wzyplus 評(píng)論0 收藏0
  • 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目

    摘要:從到再到搭建編寫構(gòu)建一個(gè)前端項(xiàng)目選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架搭建一個(gè)前端項(xiàng)目的方式有兩種選擇現(xiàn)成的項(xiàng)目模板自己搭建項(xiàng)目骨架。使用版本控制系統(tǒng)管理源代碼項(xiàng)目搭建好后,需要一個(gè)版本控制系統(tǒng)來管理源代碼。 從 0 到 1 再到 100, 搭建、編寫、構(gòu)建一個(gè)前端項(xiàng)目 1. 選擇現(xiàn)成的項(xiàng)目模板還是自己搭建項(xiàng)目骨架 搭建一個(gè)前端項(xiàng)目的方式有兩種:選擇現(xiàn)成的項(xiàng)目模板、自己搭建項(xiàng)目骨架。 ...

    aristark 評(píng)論0 收藏0
  • 談?wù)勄岸水惓2东@與上報(bào)

    摘要:另外這樣的異常捕獲不能捕獲的異常錯(cuò)誤信息,這點(diǎn)需要注意。最終大致的流程圖如下結(jié)語前端異常捕獲與上報(bào)是前端異常監(jiān)控的前提,了解并做好了異常數(shù)據(jù)的收集和分析才能實(shí)現(xiàn)一個(gè)完善的錯(cuò)誤響應(yīng)和處理機(jī)制,最終達(dá)成數(shù)據(jù)可視化。 關(guān)于 微信公眾號(hào):前端呼啦圈(Love-FED) 我的博客:勞卜的博客 知乎專欄:前端呼啦圈 前言 Hello,大家好,又與大家見面了,這次給大家分享下前端異常監(jiān)控中需...

    Kosmos 評(píng)論0 收藏0
  • vue-cli解析

    摘要:在中,設(shè)置了一些配置,代碼如下通過它的注釋,我們可以理解它在中配置了靜態(tài)路徑本地服務(wù)器配置項(xiàng)等參數(shù)。下面還有一個(gè)的對(duì)象,它是在本地服務(wù)器啟動(dòng)時(shí),打包的一些配置,代碼如下其中包括模版文件的修改,打包完目錄之后的一些路徑設(shè)置,壓縮等。 前言 這段時(shí)間,算是空出手來寫幾篇文章了。由于很久都沒有時(shí)間整理現(xiàn)在所用的東西了,所以,接下來會(huì)慢慢整理出一些文檔來記錄前段時(shí)間的工作和生活。 這篇文章的主...

    KunMinX 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<