Skip to content

SourceMap

SourceMap 是什么?

  • SourceMap 就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码

SourceMap 解决了什么问题?

  • 在前端开发中,为了提高网页性能,我们通常会对代码进行转换、压缩和合并等操作。然而,这些转换后的代码往往难以阅读和调试,因为它们与原始源代码之间的映射关系丢失了。这就导致了在生产环境中调试代码变得困难,开发者很难定位到错误的具体位置。
  • SourceMap 解决了这个问题,它通过记录转换后的代码与原始源代码之间的映射关系,使得开发者能够在调试工具中看到原始源代码的位置信息。这样,开发者就能够更轻松地进行错误定位、调试和优化,提高了开发效率和代码质量。

SourceMap 如何生成?

最常用的方法是使用 Google 的 Closure 编译器

SourceMap 的工作原理

Source map 文件,它大概是这个样子

javascript

{
  version: 3,
  file: "out.js",
  sourceRoot: "",
  sources: ["foo.js", "bar.js"],
  names: ["src", "maps", "are", "fun"],
  mappings: "AAgBC,SAAQ,CAAEA",
};

// version:Source map的版本,目前为3。
// file:转换后的文件名。
// sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
// sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。
// names:转换前的所有变量名和属性名。
// mappings:记录位置信息的字符串。

mappings 属性

text
第一层是行对应,以分号(;)表示,每个分号对应转换后源码的一行。所以,第一个分号前的内容,就对应源码的第一行,以此类推。
第二层是位置对应,以逗号(,)表示,每个逗号对应转换后源码的一个位置。所以,第一个逗号前的内容,就对应该行源码的第一个位置,以此类推。
第三层是位置转换,以 VLQ 编码表示,代表该位置对应的转换前的源码位置。

举例来说,假定mappings属性的内容如下:
{
  mappings: "AAAAA,BBBBB;CCCCC";
}
就表示,转换后的源码分成两行,第一行有两个位置,第二行有一个位置

位置对应的原理

text

第一位,表示这个位置在(转换后的代码的)的第几列。
第二位,表示这个位置属于 sources 属性中的哪一个文件。
第三位,表示这个位置属于转换前代码的第几行。
第四位,表示这个位置属于转换前代码的第几列。
第五位,表示这个位置属于 names 属性中的哪一个变量

特殊说明:
所有的值都是以0作为基数的。其次,第五位不是必需的,如果该位置没有对应names属性中的变量,可以省略第五位。再次,每一位都采用VLQ编码表示;由于VLQ编码是变长的,所以每一位可以由多个字符构成。

如果某个位置是AAAAA,由于A在VLQ编码中表示0,因此这个位置的五个位实际上都是0。它的意思是,该位置在转换后代码的第0列,对应sources属性中第0个文件,属于转换前代码的第0行第0列,对应names属性中的第0个变量

SourceMap 如何配置?

javascript

// webpack
{
  devtool: 'source-map',
  // https://webpack.js.org/configuration/devtool/
}

// vite build.sourcemap
{
  sourcemap: true // boolean | 'inline' | 'hidden'
  // https://vitejs.dev/config/build-options#build-sourcemap
}

// rollup output.sourcemap
{
  sourcemap: true // boolean | 'inline' | 'hidden'
  // https://rollupjs.org/configuration-options/#output-sourcemap
}

参考文献

Released under the MIT License.