日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

你知道source map如何帮你定位源码么?

發(fā)布時(shí)間:2023/12/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 你知道source map如何帮你定位源码么? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家好,我是若川。今天分享一篇我們經(jīng)常會(huì)忽略的定位原始代碼位置原理的文章。文章不長,例子不錯(cuò),可以先收藏,有空時(shí)動(dòng)手試試。

學(xué)習(xí)源碼系列、年度總結(jié)、JS基礎(chǔ)系列


前言

我們知道,代碼上線前要經(jīng)過壓縮,美化,混淆等步驟,真正上線之后的代碼親媽都不認(rèn)識(shí)。這也可以理解,為了防止別人看到你的源碼發(fā)現(xiàn)你的漏洞從而去攻擊你的網(wǎng)頁。

但問題是,如果自己的代碼在線上跑出了bug,連自己都看不懂錯(cuò)在了哪里。這時(shí)候就需要代碼還原工具來幫助我們還原一下代碼,從而找到出錯(cuò)位置。

這個(gè)還原神器就是我們今天的主角source map。今天我們來聊聊它是怎么還原我們的代碼的。

source map在哪

通常,我們用webpack的構(gòu)建去生成代碼的時(shí)候,可以去配置devtool 讓它生成source map,這樣在最后生成的dist就會(huì)找到.js.map的文件。

以這個(gè)list.js為例

const a = 111;console.log(a);

生成的dist文件

有一行代碼去引用了js.map文件,我們?cè)诖蜷_這個(gè)文件,可以看到,生成的map文件長這樣

{"version":3,"file":"vote/list/list.c1e192cf.js","sources":["webpack:///webpack/bootstrap","webpack:///./src/pages/vote/list/list.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/mpres/zh_CN/htmledition/pages/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","var a = 111;\nconsole.log(a);"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AClFA;AACA;;;;A","sourceRoot":""}

別看這段那么多,其實(shí)也就這幾個(gè)字段:

{"version": 3, // source map的版本"file": "", // 轉(zhuǎn)換后的文件名"source": [], // 來源文件的代碼"names": [], // 轉(zhuǎn)換前所有的變量和屬性名"mapping": "" // 記錄位置信息的字符串 }

這其中真正用于定位的就是這個(gè)mapping字段里的信息。

source map 是如何還原代碼的

由于上面的例子過于復(fù)雜,這里我們用個(gè)簡(jiǎn)單的例子來說明一下。

源代碼

/* 注釋 */ var name = "abc";

壓縮后的代碼

var name="abc"; //# sourceMappingURL=a.js.map

對(duì)應(yīng)的source-map

{"version":3,"sources":["a.js"],"names":["name"],"mappings":";AACA,IAAIA,KAAO","file":"a.js","sourcesContent":["/* 注釋 */\nvar name = \"abc\";"] }

接下來我們看看這個(gè);AACA,IAAIA,KAAO在說什么。

其中分號(hào);代表一個(gè)空行。逗號(hào),代表一個(gè)位置。

AACA標(biāo)明的是var的位置,它是先經(jīng)過VLQ編碼,在經(jīng)過base64編碼而成。VLQ跟base64不懂都沒什么關(guān)系,我們這里知道它是一種編碼方式即可。

下面舉個(gè)栗子,來看看188經(jīng)過VLQ 與 base64編碼的過程及結(jié)果。

首先188的二進(jìn)制表示是10111100,不能滿足VLQ 6字節(jié)的要求,所以這里將它拆成兩部分,在交換一下。

接著1100前面補(bǔ)1,因?yàn)楹竺孢€有一塊block。結(jié)尾補(bǔ)0,因?yàn)?88是一個(gè)正數(shù)。第一段最終轉(zhuǎn)出來就是111000。

在看后面一段1011,我們只需要在前面補(bǔ)兩個(gè)0。其中第一個(gè)0表示沒有block在后面了,第二個(gè)0是因?yàn)椴蛔?位左邊補(bǔ)0。第二段最終轉(zhuǎn)出來就是001011。

111000對(duì)應(yīng)VLQ就是56,然后在對(duì)應(yīng)base64的4。

而001011對(duì)應(yīng)VLQ是11,在對(duì)應(yīng)base64就是L。

AACA轉(zhuǎn)回來就是逆方向操作。

有點(diǎn)麻煩,我估計(jì)你們也不想算,所以我們先用一個(gè)庫vlq來幫忙轉(zhuǎn)換一下它。

打印結(jié)果如下:

可以看到AACA解析出來是0010。其中,

第一位,表示這個(gè)位置在(轉(zhuǎn)換后的代碼的)的第幾列。

第二位,表示這個(gè)位置屬于sources屬性中的哪一個(gè)文件。

第三位,表示這個(gè)位置屬于轉(zhuǎn)換前代碼的第幾行。

第四位,表示這個(gè)位置屬于轉(zhuǎn)換前代碼的第幾列。

這里有兩點(diǎn)需要注意:

1、位置都是以0為基數(shù)算起。

2、計(jì)算的是相對(duì)與前一個(gè)位置的相對(duì)位置。

所以這個(gè)0010,這里就代表著var在壓縮后代碼的第0列,對(duì)應(yīng)第0個(gè)源碼文件的1行0列。

同理,第二個(gè)IAAIA轉(zhuǎn)過來是4004,這個(gè)是相對(duì)于上一個(gè)字符的位置,所以我們需要加起來,也就是4014。說明name在壓縮后代碼的第4列,對(duì)應(yīng)第0個(gè)源碼文件的的第1行,第4列。

第三個(gè)KAAO轉(zhuǎn)過來是5007,相加前面的也就是90111,說明abc是轉(zhuǎn)換后的代碼第9列,對(duì)應(yīng)第0個(gè)源碼文件的的第1行,第11列。

再來個(gè)栗子

這是轉(zhuǎn)換前的scipt.js代碼

這是編譯后的代碼scipt-transpiled.js

這個(gè)是source map 文件

這個(gè)mapping對(duì)應(yīng)回轉(zhuǎn)換后的代碼就長這樣:


大家可以自行分析一下這個(gè)例子 。

以上,就是今天分享的source map 所有內(nèi)容。

參考文檔:

https://medium.com/@trungutt/yet-another-explanation-on-sourcemap-669797e418ce



最近組建了一個(gè)江西人的前端交流群,如果你是江西人可以加我微信 ruochuan12 拉你進(jìn)群。


點(diǎn)擊方卡片關(guān)注我、加個(gè)星標(biāo)

一個(gè)愿景是幫助5年內(nèi)前端人成長的公眾號(hào)

可加我個(gè)人微信?ruochuan12,長期交流學(xué)習(xí)

推薦閱讀

我在阿里招前端,該怎么幫你(可進(jìn)面試群)

2年前端經(jīng)驗(yàn),做的項(xiàng)目沒技術(shù)含量,怎么辦?

·················?若川簡(jiǎn)介?·················

你好,我是若川,畢業(yè)于江西高校。現(xiàn)在是一名前端開發(fā)“工程師”。寫有《學(xué)習(xí)源碼整體架構(gòu)系列》多篇,在知乎、掘金收獲超百萬閱讀。

從2014年起,每年都會(huì)寫一篇年度總結(jié),已經(jīng)寫了7篇,點(diǎn)擊查看年度總結(jié)。

同時(shí),活躍在知乎@若川,掘金@若川。致力于分享前端開發(fā)經(jīng)驗(yàn),愿景:幫助5年內(nèi)前端人走向前列。

今日話題

我經(jīng)常推薦學(xué)會(huì)使用技術(shù)完成開發(fā)的同時(shí)也要多要研究原理。其實(shí)就是不停留在只會(huì)使用的層面,重基礎(chǔ)懂原理,知其然知其所以然。歡迎分享、收藏、點(diǎn)贊、在看我的公眾號(hào)文章~

總結(jié)

以上是生活随笔為你收集整理的你知道source map如何帮你定位源码么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人在线三级 | 日韩欧美超碰 | 久久国产劲爆∧v内射 | 午夜免费片 | 欧美特黄一区二区三区 | 熟妇高潮一区二区高潮 | a级免费观看 | 4虎最新网址 | 精品在线视频免费观看 | 爱爱中文字幕 | 亚洲毛片视频 | 国产热| 亚洲视频高清 | 久久精品www | 人人看人人干 | 成人h动漫精品一区二区下载 | 国产精华7777777| 红桃视频成人在线 | 丁香六月综合激情 | 日本特黄成人 | 91精品免费 | 亚洲精品.www| av网站免费在线播放 | 夜夜干夜夜 | 日本黄色免费大片 | 亚洲在线中文字幕 | 欧美精品一卡二卡 | 欧美久久久久久久久久久久 | 粗大黑人巨茎大战欧美成人免费看 | 日韩免费a | 超碰天天操 | 日本中文在线视频 | 伊人看片 | 亚洲天堂欧美 | 在线观看日韩av | 久草资源在线观看 | 日本免费一区二区视频 | 国产又大又黄又爽 | 国产精品一区电影 | 国产色a| www.久久精品.com| 精品无码av一区二区三区不卡 | 色com| 国产精品中文在线 | 天天摸夜夜| 波多野结衣一区二区在线 | 精品无码免费视频 | 学生孕妇videosex性欧美 | 中文幕无线码中文字夫妻 | 国产国语对白 | 国产精品99久久久久久久久久久久 | 超碰在线一区 | 狠狠躁夜夜躁人人爽天天高潮 | 亚洲a√| 视频一区二区在线 | 91亚色| 国产第一页在线 | h色视频在线观看 | 久久久久成人精品 | 亚洲国产精品久久久久久6q | 亚洲天堂2016 | 中文字幕一区二区在线播放 | 少妇的性事hd | 调教在线观看 | 亚洲女人久久久 | 99热成人| 欧美精品久久久久久久久久 | 1区2区视频 | 亚洲一区二区综合 | 国产精品久久久久久久久久久久午夜片 | 亚洲色鬼| 午夜美女在线 | 日日操网 | 91久久综合 | 国产精品卡一 | 精品一区二区三区免费毛片 | 天堂在线视频免费 | 日本美女高潮 | 精品美女在线观看 | 国产精品av在线播放 | 国产69视频在线观看 | 伊人中文字幕在线 | 国产精品96久久久久久 | aa视频网站 | 99热日本 | 亚洲综合成人在线 | 国产美女福利视频 | 国产精品无码久久久久一区二区 | 亚洲第一av | 婷婷五月综合缴情在线视频 | 蜜臂av | 亚洲综合色吧 | 欧美激情一级精品国产 | 长河落日电视连续剧免费观看01 | 成人精品一区二区三区中文字幕 | 久久免费看少妇 | 相亲对象是问题学生动漫免费观看 | 中文字幕永久在线播放 | 亚洲av无码片一区二区三区 |