source map 你知道多少?-- 调试原理渗透还原源码

Posted 奋飛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了source map 你知道多少?-- 调试原理渗透还原源码相关的知识,希望对你有一定的参考价值。

压缩 css 和 javascript 代码,是一种简单且见效明显的的提高 web 性能的方式。但是,当需要调试这些压缩文件中的代码时变成了“噩梦”。source map 是解决该问题的方式之一,其提供了一种将压缩文件中的代码映射回源文件中的原始位置的方法。

Chrome 和 Firefox 开发人员工具都附带了对 source map 的内置支持,这意味着,即使在压缩后,也可以轻松地调试应用程序。

注意
Firefox:开发人员工具默认启用对源地图的支持;
Chrome:手动启用支持。启动Chrome开发者工具,然后打开“设置”窗格(齿轮位于右下角)。在常规选项卡开启 Enable JavaScript source mapsEnable CSS source maps

source map 是如何工作

为每个压缩文件指定不同的源映射。通过在优化文件的底部添加特殊注释,向浏览器指示源映射可用。

//# sourceMappingURL=chunk-14550d63.7edfeb19.js.map

在这里插入图片描述

该注释由用于生成源映射的程序添加(上述是由webpack构建追加)。仅当启用了对源映射的支持并且打开了开发人员工具时(webpack 通过 Devtool 指定),开发人员工具才会加载此文件。

还可以通过 X-SourceMap 在压缩 JavaScript 文件的响应中发送 HTTP 标头来指定源映射可用。

X-SourceMap: /path/to/script.js.map

source map 格式

包含一个 JSON 对象,其中包含有关 source map 本身和原始 JavaScript 文件的信息。一个简单的示例:

{
  "version": 3,
  "sources": [
    "webpack:///./src/views/asset/asset-info-maintenance/asset-info-maintenance.vue?1146",
    "webpack:///src/views/asset/asset-info-maintenance/asset-info-maintenance.vue",
    "webpack:///./src/views/asset/asset-info-maintenance/asset-info-maintenance.vue?b582",
    "webpack:///./src/views/asset/asset-info-maintenance/asset-info-maintenance.vue"
  ],
  "names": [
    "render",
    "_vm",
    "this",
    "_h",
    "$createElement",
    "_c",
    "_self",
    "staticClass",
    "staticStyle"
  ],
  "mappings": "uHAAA,IAAIA,EAAS,WAAa,IAAIC,EAAIC,KAASC,E",
  "file": "js/chunk-14550d63.7edfeb19.js",
  "sourcesContent": [
    "var render = function () { ... }"
  ],
  "sourceRoot": ""
}
  • version:此属性指示文件遵循的Source Map版本。
  • sources:原始源文件的URL数组。
  • names :包含源文件中所有变量和函数名称的数组。
  • mappings:包含实际代码映射的一串Base64 VLQ。(让source map文件变小的核心)
  • file:源映射文件的名称。
  • sourcesContent:源内容(渲染函数)。
  • sourceRoot:(可选)sources将从中解析数组中所有文件的URL 。

生成 source map

可以通过 UglifyJS 等工具来生成 source map。这里也可以通过上述讲的来手动验证其机制。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <script src="./a.js"></script>
  <script src="./a.js.map"></script>
</head>

<body>
  <script>
    console.log(add(1, 2))
  </script>
</body>
</html>

a.js(模拟混淆后)

function add(p1,p2) {
  return p1+p2;
}
//# sourceMappingURL=a.js.map

a.js.map(source map文件)

{
  "version": 3,
  "file": "a.js.map",
  "sources": [
    "./math.js"
  ],
  "sourceRoot": "",
  "names": [
    "add"
  ],
  "mappings": "..."
}

math.js (源文件)

function add (param1, param2) {
  return param1 + param2;
}

在这里插入图片描述
a.js 打断点会自动跳到 math.js

通过 source map 还原源代码

npm 上有一些从 sourcemaps 反编译成 JavaScript 和 CSS 源码的库,如 reverse-sourcemap

执行步骤

第一步:全局安装 reverse-sourcemap

$ npm install -g reverse-sourcemap

第二步:找到相关 sourcemap,进行反编译

# test-dir:导出路径
# app.024fcfd0.js.map:入口文件
$ reverse-sourcemap --output-dir test-dir app.024fcfd0.js.map

生成内容:

├── test-dir
│   ├── src  
│   │   ├── ...     
│   ├── webpack      
│   │   └──bootstrap          
│   └── index.js

src 下为工程源码。

总结

source map 为调试提供了便利,但在生产环境下,一定要关闭 source map。防止通过一些渗透手段,来获取源码。

以上是关于source map 你知道多少?-- 调试原理渗透还原源码的主要内容,如果未能解决你的问题,请参考以下文章

Source Map调试压缩后代码

Webpack 中使用source map 在开发过程中进行调试

Webpack 中使用source map 在开发过程中进行调试

sourcemap详解

前端线上调试之source maps

用 source map 调试生产环境