Source Map 详解

1. 面试题

Q: Webpack 的 devtool 配置有哪些?eval, source-map, cheap-module-source-map 的区别?如何选择生产环境的 Source Map?

2. 核心解答

Source Map 是一种将压缩、混淆后的代码映射回源代码的技术。它记录了代码的行号、列号、原始变量名等信息。

Webpack 提供了 20 多种 source-map 配置,看似复杂,其实都有规律可循:

(1) 关键词含义

  • eval: 将 Source Map 作为字符串,用 eval() 包裹执行。速度极快,但 map 信息很少,适合开发时用。
  • source-map: 生成独立的 .map 文件。最完整,包含列信息,但最慢。
  • inline: 将 map 以 Base64 形式内联到 JS 文件末尾。不生成独立文件。
  • hidden: 生成 map 文件,但不引用。用于错误上报平台 (Sentry),防止浏览器控制台直接看到源码。
  • cheap: 低开销。只包含行信息,不包含列信息。对调试来说足够了。
  • module: 包含 loader 处理之前的源代码。如果不加 module,你看到的可能是 babel 编译后的代码 (如 ES5),而不是你写的 ES6 源码。

(2) 最佳实践

开发环境

推荐:eval-source-mapeval-cheap-module-source-map

  • 速度快:利用 eval 的缓存机制,rebuild 速度极快。
  • 调试清晰:能看到原始代码,方便打断点。
  • cheap: 如果不需调试列信息,用 cheap 更快。

生产环境

推荐:hidden-source-mapnone

  • 安全:不要把 map 文件部署到公网,防止源码泄露。
  • 监控:生成 map 文件上传到 Sentry,用于还原线上报错堆栈。
  • none: 如果不需要复原报错,直接关掉 (false) 甚至更快,更安全。

3. 面试加分项

Q: 为什么 vue-cli 默认生产环境生成 map?

便于排查线上 bug。但为了安全,通常会在 Nginx 配置里禁止访问 .map 文件,只允许内网或监控平台访问。

Source Map 原理?

Source Map 本质是一个 JSON 文件,包含 mappings 字段。这个字段是一个经过 Base64 VLQ (Variable Length Quantity) 编码的字符串。它可以极其精简地表示行列映射关系。

4. 总结

  • Dev: Use eval-cheap-module-source-map. Fast & Debuggable.
  • Prod: Use hidden-source-map + Sentry. Secure.