Sunday面试指南

Source Map 是什么?线上压缩后的 JavaScript 报错怎么定位到源码?

下面是一段教学用的模拟面试。

🧑‍💻 面试官:线上报错显示 app.min.js 的某个列位置,你怎么知道是哪个组件?

🙋‍♂️ 我:使用 Source Map,把构建后的代码位置映射回原始源码。

🧑‍💻 面试官:拿今天重新构建的一份 map,去解析昨天的报错,可以吗?

🙋‍♂️ 我:不能保证对应,应该用当时发布产物配套的 map。

🧑‍💻 面试官:map 放在公网,会不会泄露源码?不公开以后,错误监控又怎么解析?

能否定位,取决于发布产物与映射是否准确对应;能否安全使用,还取决于谁可以读取它们。

面试速答(60 秒版)

Source Map 保存构建后代码位置到原始源码位置的映射。浏览器或错误监控拿到对应映射,就可以把压缩文件里的行列位置还原成更容易排查的源码位置。

浏览器实际执行的仍然是发布后的 JavaScript,显示原始 TypeScript 或组件源码,不代表浏览器直接执行了这些文件。

线上最重要的是版本匹配。代码产物、map 和发布标识要来自同一次构建,不能用当前源码去猜旧错误。

如果不希望公开源码,可以将 map 作为受控构建产物上传到错误监控,不随静态站点公开。但要验证上传、关联和访问控制。Source Map 帮助定位,不替代业务日志、调用链和错误复现。

同版本构建产物通过SourceMap映射到源码

知识点详解:一个列位置,怎样回到组件里的某一行?

构建之后,为什么位置变了?

假设原始组件调用了一个校验函数。构建工具把多个模块合并、转换语法,又压缩变量名和空白。

原来的一个函数可能被移到输出文件的一长行里。错误栈仍然能描述执行位置,但这个位置属于构建产物,不再等于源文件的行号。

格式化压缩文件只能把它重新排版。它不会自动恢复原模块名、类型和原始位置,不能代替 Source Map。

map 保存了什么?

它描述生成代码的位置怎样对应到原始文件位置,还可以包含源文件名称、符号名称,以及可选的源码内容。

某个生成位置可能对应一个源码位置,但并不是每一个字符都必然有完美的一一映射。转译和优化步骤也可能影响定位的细致程度。

开发者工具可以依据映射展示源码、关联断点和调用栈。基本工作方式见 Chrome DevTools 的说明。

浏览器怎样找到它?

构建文件可以通过 sourceMappingURL 注释指向关联 map,开发者工具再尝试读取它。具体构建配置还可以选择其他组织方式。

map 如果只记录源路径,没有内嵌源码,显示完整原文还可能需要能够访问对应源码内容。因此拿到了一个 map 文件,不代表必然具备全部调试材料。

反过来,浏览器成功展示 TypeScript,也不意味着它执行了 TypeScript。执行代码与调试展示是两条关系。

为什么同一个文件名,仍然可能配错?

假设每次发布都叫 app.js,但内部压缩结果已经变化。昨天列位置 500 指向一个函数,今天同样的位置可能指向另一个函数。

因此需要用构建标识、内容哈希或其他可靠关联,保证错误事件找到当时的产物与 map。回滚、CDN 缓存和多版本并存,也要保留各自的对应关系。

如果构建后又有工具修改 JavaScript,却没有同步正确映射,位置也可能偏离。版本匹配不只是把两个文件放在同一个目录。

Source Map必须匹配错误来自的同一构建产物

图中的行号只是示意,不表示两个构建会映射到同一源码行。真正要对应的是产物、map 与构建身份。

不公开 map,怎样排查线上错误?

可以在构建阶段保留 map,上传到受控错误监控,并绑定发布标识与相应代码产物。公网只提供执行需要的文件,监控系统收到错误位置后,在后台解析。

这里的“不公开”要检查实际上传与静态目录。只移除 sourceMappingURL,不等于 map 无法被访问;知道地址的人仍可能直接请求文件。

map 还可能包含源码内容、路径和注释。应用源码本来就不应该包含密钥,但限制 map 的访问依然有价值。不能把安全性建立在“没人会猜到文件名”上。

上线前,怎样证明流程能用?

在测试发布中制造一个已知位置的受控错误,确认监控收到正确发布标识,并还原到预期源文件与行附近。

再检查旧版本事件能否使用旧 map 解析,公网是否能访问不该公开的映射,静态资源是否遗漏。失败时区分上传失败、关联错误、映射缺失与源内容缺失,别都归结为“监控不好用”。

受控测试应在合适环境完成,不能为了文章示范向真实用户制造线上异常。

面试官继续追问

map 会影响业务运行吗?

正常情况下,业务执行依赖构建后的 JavaScript;map 主要服务调试工具。具体发布体积与工具加载开销仍取决于配置,不能把它混进业务执行逻辑。

只能定位前端 JavaScript 吗?

其他编译或打包场景也可能使用源映射。本文聚焦浏览器与前端监控,Python 后端普通异常栈不需要伪造同样的打包过程。

拿到源码行号,事故就查清了吗?

还需要请求数据、版本、环境与调用顺序。源码位置告诉你在哪里报错,不自动告诉你为什么收到这个输入。

面试速记卡

  • Source Map 连接构建位置与原始源码位置。
  • 浏览器执行产物,开发工具展示源码。
  • 同一次构建的代码、map 与发布标识一起保存。
  • 去掉注释不等于限制了 map 的公网访问。
  • 私有上传也要验证关联、旧版本与访问控制。
  • 定位源码后,还要结合输入、日志和复现排查。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历