- 為什么要使用
sourceMap
? -
sourceMap
如何實(shí)現(xiàn)資源定位?
1、sourceMap
為了讓資源更小,加載速度更快扑媚,在js
項(xiàng)目部署之前都會(huì)將代碼混淆壓縮腰湾。但是這樣也帶來(lái)了影響雷恃,當(dāng)代碼中出現(xiàn)問(wèn)題時(shí),只能定位到壓縮之后的代碼费坊。而壓縮之后的代碼一般就只有一兩行倒槐,每一行上萬(wàn)字符,對(duì)排除檢查幾乎沒(méi)有幫助附井。而sourceMap
的存在就是為了解決這個(gè)問(wèn)題讨越,它幫助將壓縮的代碼復(fù)原到源文件之中。
Source map
就是一個(gè)信息文件永毅,里面儲(chǔ)存著位置信息把跨。也就是說(shuō),轉(zhuǎn)換后的代碼的每一個(gè)位置沼死,所對(duì)應(yīng)的轉(zhuǎn)換前的位置着逐。
{
version : 3,
file: "out.js",
sourceRoot : "",
sources: ["foo.js", "bar.js"],
names: ["src", "maps", "are", "fun"],
mappings: "AAgBC,SAAQ,CAAEA"
}
- version:
source map
的版本 - file: 生成的文件
- sourceRoot: 源文件根目錄
- sources: 源文件
- names: 源文件中變量、方法名
- mappings: 映射字符串,文件最核心部分耸别,
2健芭、如何轉(zhuǎn)換?(Base64 VLQ的解碼過(guò)程)
如何只單純的記錄原文件的所在行秀姐、所在列慈迈、所在具體位置,那么生成的source map
文件將是源文件的十倍之多省有,而現(xiàn)在一般的大小并沒(méi)有那么嚇人痒留。而這主要使用了一種叫VLQ(variable-length-quantity)的編碼方式。
基礎(chǔ)補(bǔ)充:
Base64 是一種基于64個(gè)可打印字符來(lái)表示二進(jìn)制數(shù)據(jù)的表示方法蠢沿。由于2^6=64狭瞎,所以每6個(gè)比特為一個(gè)單元,對(duì)應(yīng)某個(gè)可打印字符搏予。
Base64
編碼是將文本先ASCII編碼熊锭,然后二進(jìn)制轉(zhuǎn)化,再講二進(jìn)制數(shù)每6個(gè)一位雪侥,不足的用0補(bǔ)充碗殷,接著映射到對(duì)應(yīng)的字符。
sourceMap中的VLQ:
A single base 64 digit can contain 6 bits of data. For the base 64 variable length quantities we use in the source map spec, the first bit is the sign, the next four bits are the actual value, and the 6th bit is the continuation bit. The continuation bit tells us whether there are more digits in this value following this digit.
Continuation
| Sign
| |
V V
101011
上面是sourceMap源碼中的一段注釋速缨。解釋了锌妻,base64
每單位(6Bit)最高位(左側(cè)第一位)表示是否連續(xù),即如果是1表示后面的6位跟當(dāng)前這6位為同一個(gè)數(shù)字旬牲;而最低位為符號(hào)位仿粹。所以實(shí)際表示大小的只有中間4位,所以每單位只能表示-15~+15的值原茅。超過(guò)這個(gè)值得話就需要兩個(gè)6位表示了吭历。
Base64 VLG 編碼:
比如: 10 -> K
16 -> 10000 -> 100000(大于0的符號(hào)位) -> 00001 00000(每五位分割) -> 00000 00001 (little-endian從低到高) -> 100000 000001(最后一組最高位為0 其他都是1 表連續(xù)) -> 32 1 -> gB
Base64 VLG 解碼:
A -> 0
A -> 0
g -> 32
B -> 1
C -> 2
所以AAgBC -> 0 0 32 1 2 -> 0 0 16 2
根據(jù)下面的每一位具體含義比對(duì),就能得到含義: 該位置在轉(zhuǎn)換后代碼的第0列擂橘,對(duì)應(yīng)sources屬性中第0個(gè)文件晌区,屬于轉(zhuǎn)換前代碼的第16行第2列
- 第一位,表示這個(gè)位置在(轉(zhuǎn)換后的代碼的)的第幾列通贞。
- 第二位朗若,表示這個(gè)位置屬于sources屬性中的哪一個(gè)文件。
- 第三位昌罩,表示這個(gè)位置屬于轉(zhuǎn)換前代碼的第幾行哭懈。
- 第四位,表示這個(gè)位置屬于轉(zhuǎn)換前代碼的第幾列茎用。
- 第五位遣总,表示這個(gè)位置屬于names屬性中的哪一個(gè)變量你虹。
參考資料:
introduction to JavaScript Source Maps
Base64
Variable-length_quantity
JavaScript Source Map 詳解