source map介绍

705 阅读3分钟

为什么使用source map

js脚本变得越来越复杂,大部分源码都要经过转换才能再浏览器端运行。这就导致实际运行的代码不同于开发代码,debug变得很困难。sourcemap要解决的就是这个问题。

source map 是什么

sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术。

sourcemap的原理是通过在构建时,依赖特定的文件,记录构建前后代码的映射关系。

得益于浏览器的支持,通过开发者工具便能直接查看对应的代码位置。

source map的关键字

  • eval(性能最好)
    • 生成文件:使用eval包裹模块代码,然后在末尾添加模块来源 //# sourceURL,依靠sourceURL找到原始代码的位置。
    • 错误追踪:文件名、源码行和列位置
    • 包含eval关键字的配置项不产生.map文件(eval依靠sourceURL定位原始代码,其他都是.map定位)
  • source-map(性能最低)
    • 生成文件:产生.map文件
    • 错误追踪: 文件名、源码行和列位置
  • cheap:不包含原始代码的列信息
    • 如果包含cheap关键字,则产生的.map文件不包含列信息。也就是说当你在浏览器中点击该代码的位置,光标只定位到行数,而不包含具体字符位置。
    • 也不包含loaders的sourcemap:如果你使用了babel等代码编译工具,定位到的代码将是经过编译的代码位置,而不是原始代码。
  • module:包含loader的sourcemap(比如jsx to js ,babel的sourcemap)
  • inline:将.map经过base64编码作为DataURI嵌入,不单独生成.map文件(这个配置项比较少见)

项目中的使用

开发环境的使用

推荐使用cheap-module-eval-source-map

需求:

  • 快速 build 与 rebuild 速度(配合 HMR)
  • 清晰的 debug 定位信息

原因:

  • eval 优势是快速构建速度,但如果直接使用 eval-source-map 会导致在 bundle 尾部的 dataURL 过大(包含源代码),导致包体积增大。

  • cheap 不生成列信息,可以大幅提高 souremap 生成的效率。

  • 使用 module 可支持 babel 这种预编译工具(在 webpack 里做为 loader 使用)。

总之:既能保证一定的 build 与rebuild 速度,同时能确保在 debug 时正确定位代码位置,又能相对地降低 source map 的体积。

生产环境的使用

推荐使用cheap-module-source-map

需求:

  • 清晰的 debug 定位信息
  • 尽可能小的 bundle 且只包含 source map 加载链接
  • 在打开 {Browser} Dev Tool 时才加载 source map

原因:

  • eval 的方式不适合在生产环境使用(鉴于 eval 本身的安全性和性能等问题)
  • 不带列映射
  • 独立的.map文件,只有打开浏览器调试工具才会加载

另外,如果需要经常线上调试bug,直接使用source-map也是可以的,毕竟上线过程中只打包一次,打包速度慢也木事~

压根不需要上线调试的话,那配置false应该也可以吧?~~