javascript - 解码(javascript)源 map

标签 javascript source-maps

我一直对找到的以下图像感到困惑here

Decoding the source map

以及以下描述它应该如何工作:

The above diagram AAgBC once processed further would return 0, 0, 32, 16, 1 – the 32 being the continuation bit that helps build the following value of 16. B purely decoded in Base64 is 1. So the important values that are used are 0, 0, 16, 1. This then lets us know that line 1 (lines are kept count by the semi colons) column 0 of the generated file maps to file 0 (array of files 0 is foo.js), line 16 at column 1.

我隐约明白为什么B会被转换成16,但是C是什么?以及它是如何转换为 1 的?

最佳答案

该页面上的解释非常困惑。它忘记提及的关键是 base64 和 VLQ 系统基于 6 位字母表而不是通常的 8 位字母表;例如,base64 数据与“普通”base64 解码器不兼容,例如 JavaScript 自己的 atob 函数(atob("AAgBC") 会产生错误)。我想this page提供了更好的解释。

假设我们有一个函数 decodeLine() 来解码单行的数字,"IACH,mBAA0B,CAAS,EAAE,SAAgB"。这只是成功的一半,因为每个 4 数组(或 5 数组)都与前一个 4 数组相关。

在此示例中,第一个 base64 字符串“IACH”表示数组 [4,0,1,-3],但此信息本身无用,因为它是相对于前一个数组的 - of-4(第一个数字除外,它在每行的开头重置为 0)。因此,如果前面的 4 数组之和是 [11,1,10,3],我们可以计算出“IACH”的真正含义是 [4, 1+ 0, 10+1,3+-3] = [4,1,11,0] - 表示“输出第 4 列对应于源文件 1,源代码行 11,源代码列 0”。类似地,“mBAA0B”解码为 [19,0,0,26] 添加到 [4,1,11,0] 得到 [23,1,11,26] 这意味着“输出列 23 对应于源文件1,来源第 11 行,来源第 26 列。

所以我在这里编写了代码来解码整个 "mappings" 字符串。它有两部分,decodeLine 解码单行和 scanMappings 解码所有行并为每个解码的 6 个值集(行、列、源文件)调用一个函数、源代码行、源代码列和可选的名称索引):

function decodeLine(line) { 
  function digit(c) { return atob("AAA"+c).charCodeAt(2); }
  if (line==="") return [];
  return line.split(",").map(token => {
    var output = [], num;
    for (var i = 0; i < token.length;) {
      var v = 0, shift = 0;
      do {
        var d = digit(token[i++]);  // d = next 6-bit value decoded from base64
        v |= (d & 31) << shift;     // put lowest 5 bits of d into v
      } while (shift += 5, d & 32); // repeat if high bit of d is set
      output.push(v & 1 ? -(v >> 1) : v >> 1); // low bit is sign
    }
    return output;
  });
}
function scanMappings(data, callback) {
  var lines = data.split(";"), output = [];
  var sum = [0,0,0,0,0];
  for (var line = 0; line < lines.length; line++) {
    sum[0] = 0;
    decodeLine(lines[line]).forEach(p => {
      for (var i = 0; i < p.length; i++) sum[i] += p[i];
      callback(line, ...sum);
    })
  }
}

// Example taken from one of my TypeScript files
console.log(JSON.stringify(decodeLine("IACH,mBAA0B,CAAS,EAAE,SAAgB")));
scanMappings(
 ";;;;;;;;;;;ICAA;;;;;;;;;;OAUG;IACH,mBAA0B,CAAS,EAAE,SAAgB;QACnD,uEAAuE",
  (line,col,srcFile,srcLine,srcCol) => 
    console.log(`(${line},${col}) is from src file ${srcFile} at (${srcLine},${srcCol})`));

行和列是从零开始的。规范是here .

关于javascript - 解码(javascript)源 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29263051/

相关文章:

javascript - Laravel 中的国家/地区选择后没有出现任何国家

javascript - 扩展类但不能访问子类的功能

javascript - 是否可以在 Safari 6 中启用 JavaScript 源映射?

typescript - src ➜ tsc ➜ rollup ➜ `source maps` 能否指向原来的TypeScript src?

visual-studio-code - SourceMaps 的 VSCode Gatsy 调试错误

javascript - 有条件地链接数组方法

javascript - Bootstrap 模态框不会启动

javascript - 通过键盘控制页面行为

javascript - Chrome 扩展 : Not loading source-maps

typescript - Webpack 4 加载库 Sourcemap