这是一个合理的问题。“Source map” 是一个特殊文件,它将压缩/混淆后的资源(CSS 或 JavaScript)版本连接到原始编写的版本。假设您有一个名为 _header.scss
的文件,该文件被导入到 global.scss
中,然后编译成 global.css
。最终的 CSS 文件是在浏览器中加载的,因此例如,当您在 DevTools 中检查元素时,它可能会告诉您 <nav>
是 display: flex;
,因为它在 global.css
中的第 387 行是这么说的。

page.css
的第 528 行,我们可以发现 .meta
有 position: relative;
但是由于最终的 CSS 文件很可能是压缩的(所有空格都被删除),DevTools 可能会告诉我们声明在第 1 行!非常不幸,对开发没有帮助。
这就是 Source Map 的作用。正如我在上面所说,Source Map 是特殊文件,它们将最终输出文件(浏览器 实际使用的)连接到您实际使用的并写入代码的源文件(您 在文件系统上使用的)。
通常,Source Map 是预处理器中的一个配置选项。这是 Babel 的选项。我相信使用 Sass 时,您甚至不必在命令中传递任何标志,因为它默认生成 Source Map。
因此,这些 Source Map 是为开发人员 而设计的。它们对您和您的团队特别有用,因为它们在调试问题以及日常工作中提供了极大的帮助。我确信我每天都会使用它们。我敢说通常,它们用于本地开发。您甚至可能会将它们 .gitignore
掉,或者在部署过程中跳过它们,以便向生产环境提供和存储更少的资源。但是最近关于确保它们也部署到生产环境的讨论不断增多。
但是 Source Map 长期以来被视为仅仅是本地开发工具。并非用于部署到生产环境的工具,尽管有些人也这么做,这样可以更容易进行实时调试。这本身就是一个部署 Source Map 的绝佳理由。[…]
此外,Rails 6 默认在生产环境中部署 Source Map,这也要感谢 Webpack。您可以关闭该功能,但我希望您不要这么做。当我们允许其他人从我们的工作中学习时,网络会变得更加美好。
查看那个问题线程,了解更多关于将 Source Map 部署到生产环境的有趣讨论。好处归结为以下两点
- 它可能有助于您更轻松地追踪生产环境中的错误
- 它有助于其他人更轻松地从您的网站中学习
这两点都非常棒。就我个人而言,我会反对为了学习目的而部署性能优化的代码。去年我写过关于这个主题的文章
我不希望我的源代码可供人阅读,不是出于保护原因,而是因为我更关心网络性能。我希望我的网站能以光速在魔法网络数据包尘埃中到达,并开出完整网站。或者,根据计算机科学认为的绝对最快的速度在计算机之间发送网站数据。我更担心网络性能问题,而不是网络教育问题。但是即使我非常担心网络教育,我认为网络不应负责提供可教性。
将 Source Map 部署到生产环境是一个不错的折衷方案。它不会影响性能(除非您打开了 DevTools 才会加载 Source Map,我认为这与真正的性能讨论无关),同时又能提供调试和学习的好处。
最近的讨论中提到的缺点归结为以下几点
- Source Map 需要编译时间
- 它允许人们,我不知道,窃取您的代码之类的
我不关心 #2(抱歉),而且 #1 对小型网站(或者我们认为的普通网站)来说通常微不足道,尽管我担心我无法代表大型网站发言。
不过我要补充一点,Source Map 甚至可以为 CSS-in-JS 工具生成,因此对于那些将样式直接注入 DOM 的工具,它们的 Source Map 也会被注入。我看到过这种情况下出现严重延迟,因此我认为如果您无法将它们从主捆绑包中分离出来,那么绝对不要 将 Source Map 部署到生产环境。否则,我强烈建议您这么做。
一种既能兼顾鱼与熊掌的方法是控制 .map 文件的访问权限,使其只能通过公司的内网或特定 IP 地址访问,或者在需要时才部署 .map 文件(安全性较低)。
另一种方法是让生成的 Source Map 链接指向 localhost,然后从您自己的机器上“侧面提供” Source Map。您可以使用 Webpack 实现这一点。
最后,如果您使用的是 Chrome,您可以在生产环境中部署没有 Source Map 链接的文件,然后使用本地覆盖来添加链接,以便在需要时可以使用它。
老实说,这些方法都太过复杂,不是我想要的结果。我记得 Source Map 刚推出时,可以在 Chrome DevTools 中右键单击一个 .js 文件,然后选择“加载 Source Map”,这将打开一个文件对话框,让您选择 .map 文件。我认为这是最简单的方法。
这是一篇介绍该问题的更详细的文章:https://itnext.io/using-sourcemaps-on-production-without-revealing-the-source-code-%EF%B8%8F-d41e78e20c89
没错。此外,许多现代仪器工具都支持私有 Source Map。这意味着您的客户端堆栈跟踪在被这些工具/服务收集和处理后,会快速告诉您很多信息。
我一直没有考虑是否要将 Source Map 部署到生产环境。我喜欢在本地开发中使用它们带来的好处,而且它们不会被 Git 忽略,所以它们总是会被部署,而且我认为这没什么问题。
实际上,除了 CSS Tricks(双关语)或 JS 黑客攻击之外,没有人可以窃取任何东西。您仍然需要后端代码(PHP 或其他)才能让任何东西正常工作。
最重要的是,如果您的用户/客户遇到问题,在真实场景中会更容易诊断问题,因为您可以看到在实时服务器上出现问题的 JS/CSS 代码。
不过,这是一个值得思考的问题:)
没错。您应该这么做。如果这意味着解决重大问题所需的时间大幅缩短,那么更长的构建时间是可以接受的。
我同意 Source Map 文件应该部署到生产环境。如果您担心显示您的“真实代码”,Webpack 提供一个功能,可以在外部服务器上托管 Source Map 文件。这样,您可以将它们放在需要授权才能访问的地方。
https://webpack.js.cn/plugins/source-map-dev-tool-plugin#host-source-maps-externally
如果你有一个像我以前那样喜欢在实时服务器上编辑生产代码的老板,那么你真的需要 Source Map 在所有可能的地方都存在。
将它们打印出来,以便随时随地进行紧急调试。
我只是将所有源代码(未修改)通过 FTP 传输到生产系统,并应用一些过滤器来避免覆盖生产设置,因此不需要构建链或 Source Map。
JS 的 Source Map 也对错误跟踪很重要,因为像 Sentry 这样的工具可以使用它们从异常回溯中显示原始代码位置。
您应该始终拥有映射文件,特别是在生产环境中。但是,拥有映射文件和公开访问它们之间是有区别的。
根据我的经验,最好将它们放在一个单独的 .map 文件中,然后限制对该文件的访问权限。我的 Webpack 配置在将任何 .map 文件上传到我的 AWS S3 存储桶时会将其设置为私有文件。我必须先登录 AWS,然后才能从浏览器访问这些文件。
我还记录客户端 JS 错误,并将堆栈跟踪上传到报告服务器。从那里,我有一个节点脚本可以使用适当的凭据提取 .map 文件,并告诉我正确的行号和文件名。
也许我错了,但我假设 Source Map 只有在您将其嵌入或在浏览器的 DevTools 中查看时才会下载。否则,它们不会对网页产生任何影响,因此除了用于引用 .map 文件的几个字符之外,不应该有任何性能成本。
考虑到我们经常需要修复只在生产环境中出现的错误,它们是一个非常宝贵的工具,应该始终使用,无论环境如何。