11. source-map

215 阅读3分钟

相关代码

通过 Webpack 将源码 index.js 打包成 index.bundle.js,那么浏览器中运行的就是打包后的 index.bundle.js,一旦代码报错,报的将是 index.bundle.js 中的错误,这不利于我们快速定位问题解决 bug。

那么如何将打包后的文件中的错误映射到源码上呢?通过 source-map 可以做到。

一、基本使用

Webpack 内置了 source-map 的功能,只需要通过简单的配置,就可以开启它:

module.exports = {
    // 开启 source map
    devtool: 'source-map',    // 开发环境推荐使用 'source-map',生产环境一般不开启 sourcemap
}

当执行打包命令之后,我们发现 bundle 的最后一行总是会多出一个注释,指向打包出的 bundle.js.map(SourceMap 文件)。 SourceMap 文件用来描述源码文件和 bundle 文件的代码位置映射关系。基于它,可以将 bundle 文件的错误信息映射到源码文件上。

二、devtool 常用的几种 SourceMap 模式

模式解释
eval(默认值)每个 module 会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL
source-map生成一个 SourceMap 文件,并在 bundle 末尾追加注释
hidden-source-map生成一个 SourceMap 文件,但不会在 bundle 末尾追加注释
inline-source-map生成一个 DataUrl 形式的 SourceMap 文件
eval-source-map每个 module 会通过 eval() 来执行,并且生成一个 DataUrl 形式的 SourceMap 文件
cheap-source-map生成一个没有列信息(column-mappings)的 SourceMap 文件,不包含 loader 的 sourcemap(比如 babel 的 sourcemap)
cheap-module-source-map(开发环境推荐使用)生成一个没有列信息(column-mappings)的 SourceMap 文件,同时 loader 的 sourcemap 也被简化为只包含对应行的

1. devtool: 'eval'(默认值)

每个 module 会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL

image.png

2. devtool: 'source-map'

生成一个 SourceMap 文件,并在 bundle 末尾追加注释。

image.png

3. devtool: 'hidden-source-map'

生成一个 SourceMap 文件,但不会在 bundle 末尾追加注释。

image.png

4. devtool: 'inline-source-map'

生成一个 DataUrl 形式的 SourceMap 文件。

image.png

5. devtool: 'eval-source-map'

每个 module 会通过 eval() 来执行,并且生成一个 DataUrl 形式的 SourceMap 文件。

image.png

6. devtool: 'cheap-source-map'

生成一个没有列信息(column-mappings)的 SourceMap 文件,不包含 loader 的 sourcemap(比如 babel 的 sourcemap)。

示例中使用了 babel 转译,不能映射到源代码:

image.png

7. devtool: 'cheap-module-source-map'

生成一个没有列信息(column-mappings)的 SourceMap 文件,同时 loader 的 sourcemap 也被简化为只包含对应行的。

示例中使用了 babel 转译,可以映射到源代码:

image.png

开发环境中推荐使用 cheap-module-source-map 的原因:

  • 会生成一个单独的 SourceMap 文件;
  • 不记录列数,减小 SourceMap 文件体积;
  • 包含 loader 的 SourceMap,可以映射到源代码。

三、生产环境一般不会开启 source-map 功能

注意,生产环境我们一般不会开启 source-map 功能,主要有两点原因:

  • 通过 bundle 和 SourceMap 文件,可以反编译出源码,也就是说,线上产物有 SourceMap 文件的话,就意味着有暴露源码的风险;
  • SourceMap 文件的体积相对比较大,而生产环境追求更小更轻量的 bundle。