JavaScript Source Map:你应该了解的信息

JavaScript已经成为Web开发人员的基本编程语言。它用于开发具有动态和交互特性的复杂Web应用程序。

然而,调试和故障排除JavaScript代码可能是一项艰巨的任务,特别是当代码库很大时。这就是JavaScript源映射派上用场的地方。

它们提供了一种将被缩小或转译的代码映射回其原始源代码的方法,从而使调试和故障排除问题变得更容易。

当浏览器在被缩小的代码中遇到错误时,它使用源映射来定位错误发生的原始源文件和行号。这使得开发人员更容易调试和故障排除他们的代码中的问题。

在这篇博客文章中,我们将探讨JavaScript源映射的概念以及如何开始使用它们。我们还将探讨不同类型的源映射以及如何为您自己的代码生成它们。

JavaScript Source Maps是什么?

Source Maps是一种文件,提供了在浏览器中执行的被压缩或转译代码与开发人员编写的原始未被压缩的源代码之间的映射。它们包括有关原始代码的文件结构、变量名称和与被缩小代码的逐行对应关系的信息。

您可以在源映射中搜索,并获取生成的·JavaScript·查询特定行和列号时的初始位置。

源映射可以立即被开发者工具解析(目前支持WebKit夜间版本构建、Google ChromeFirefox 23+),给人一种你正在操作未被缩小和未被组合的文件的印象。

Source Maps的必要性

尽管已经讨论过编译到JavaScript的语言(如CoffeeScript)以及添加对CSS预处理器(如SASSLESS)的支持的潜力,但源映射目前仅在未压缩/组合的JavaScript与压缩/未组合的JavaScript之间起作用,未来看好。

Source Maps是一个或多个初始源文件与生成的、转译的或被压缩的JavaScript文件之间的关系。Source Maps主要用于辅助故障排除。本质上,如果生成的代码文件包含错误,映射可以标识出初始源文件的位置。

因此,这些源文件是为程序员准备的。它们是您几乎每天都会使用的资源。这些文件主要旨在帮助软件开发,在促进有效的团队合作和问题解决方面发挥着关键作用。

被称为Source Maps的文件夹用于将您的源(原始)代码转移到生成的代码中。换句话说,生成代码中的一行代表了源代码中源映射标识的行。

使用uglify-js生成JavaScript Source Maps

在开始之前,您需要一个工具来帮助创建源映射,作为创建JavaScrip的压缩版本的一部分。就我们个人而言,我们使用UglifyJS,并认为它是一个很棒的实用工具。

如果您已经安装了Node.js(即使您不是Node开发人员),您可以执行以下命令来安装它:

1
npm install uglify-js -g

上述命令将全局安装Uglify JS,因此您可以从命令行中使用它。

假设您有一个名为example.jsJavaScript文件,其内容如下:

1
2
3
4
5
function add(a, b) {
return a + b;
}

console.log(add(2, 3));

要生成带有Source Maps的压缩代码,您可以使用uglifyjs命令行工具,如下所示:

1
uglifyjs example.js --compress --mangle --output example.min.js --source-map
  • example.js 是输入JavaScript文件。
  • --compress--mangle 选项启用了代码压缩和变量名混淆,以减小文件大小。
  • --output 指定了输出文件的名称,缩小后的代码将保存在其中(example.min.js)。
  • --source-map 指示 uglify-js 生成与缩小代码一起的源映射。

运行此命令后,您将获得两个文件:example.min.js(缩小后的代码)和在缩小文件末尾的一个 sourceMappingURL 注释,它指向源映射文件(example.min.js.map)。

1
//# sourceMappingURL=example.min.js.map

这个注释很重要,因为它告诉浏览器在调试时找到相应的Source Maps的位置。它将压缩的代码与其Source Maps关联起来,使开发人员能够使用原始源代码进行调试。

在您的HTML文件中,您可以包含缩小的JavaScript文件并使用以下代码链接到源映射:

1
2
<script src="example.min.js"></script>
<script src="example.min.js.map"></script>

浏览器将使用源映射将错误和调试信息映射回原始的 example.js 文件。

通过这种设置,当发生错误或您需要调试代码时,您的浏览器开发者工具将在原始源代码(example.js)的上下文中显示错误和堆栈跟踪,从而更容易地识别和修复代码中的问题。

通过遵循这些步骤,您可以使用uglify-js生成JavaScript Source Maps,从而改善您的缩小JavaScript代码的调试体验。

Source Maps文件的详细解析

源映射文件的分解文件是JSON数据。它包括以下关键组件,例如:

  • "version":表示源映射版本。
  • file:生成代码文件的名称(例如 "app.min.js")。
  • "sources":原始源文件的路径数组。
  • "names":标识符和变量名称的数组。
  • "mappings":包含编码映射信息的字符串。
  • "sourcesContent":原始源文件的实际内容。
  • sourceRoot:指定解析源文件路径的基本路径的可选字段。
  • …(其他可选字段):一些源映射可能包括附加信息,如包含的模块列表、元数据等。

这是Source Maps的一个示例:

1
2
3
4
5
6
7
8
9
{
"version": 3,
"file": "app.min.js",
"sources": ["src/file1.js", "src/file2.js"],
"sourcesContent": ["/* Contents of file1.js */", "/* Contents of file2.js */"],
"mappings": "AAAA;ACAA;AAAA;...",
"names": ["console", "log", "add"],
"sourceRoot": "/source-maps"
}

在实践中,"mappings" 部分通常是源映射中最复杂的部分。它使用base64 VLQ(可变长度数量)编码来高效地表示映射数据,包括关于行、列、源文件和符号名称的信息。

通过将源映射中的信息与原始源代码结合起来,浏览器和调试工具可以准确地显示原始源代码,设置断点,并像未被缩小或转译的代码一样逐步执行代码。

利用Source Maps简化调试

想象一下,您有一个被压缩的JavaScriptCSS文件以及一个关联的Source Maps。当出现错误时,浏览器可以利用源映射将错误映射回原始源代码的确切位置。这意味着开发人员可以识别出问题所在的行、列,甚至变量名称,极大地简化了调试过程。

Source Maps为简化调试提供了几个好处:

  • 原始代码视图:轻松调试您的原始、人类可读的代码,使问题识别和更改更简单。
  • 精确定位错误位置:源映射将缩小的代码错误链接到确切的原始代码行和列号,确保准确调试。
  • 可读的变量名称:将缩小的变量和函数名称映射回原始、可理解的形式,便于代码检查。
  • 高效的工作流程:开发人员可以像处理原始代码一样调试缩小的代码,包括断点、变量检查和熟悉的工具。
  • 更快的调试:源映射加快了问题识别,减少了调试时间,提高了生产效率和代码质量。
  • 跨浏览器支持:现代浏览器(如ChromeFirefoxSafariEdge)支持Source Maps,确保了在各种开发环境中一致的调试体验。
    在使用Source Maps进行调试时,有三种常见类型或策略用于包含和使用源映射:
1. 内联源映射

内联Source Maps嵌入在编译后的文件中,使用数据URL。这消除了对额外HTTP请求的需求,但稍微增加了文件大小。开发人员可以通过引用此内联源映射注释,轻松将编译后的代码与原始源相关联。

  • 用法:当您希望有一个包含缩小代码和源映射的单个、自包含文件时,这些源映射非常有用。

  • 优点:
    简单性:无需管理单独的源映射文件。
    方便性:更容易分发单个文件。

  • 缺点:
    增加文件大小:内联Source Maps增加了JavaScript文件的大小。
    缓存效率低:对源代码或Source Maps的更改需要重新生成和重新分发整个文件。
    内联源映射注释的示例,在JavaScript文件末尾:

1
//# sourceMappingURL=data:application/json;base64, ...

这个独特的注释指示Web浏览器如何连接编译后的代码到初始版本,并添加到您的常规`JavaScript文件中。

2. 外部Source Maps

外部Source Maps提供了一种替代方法。在这种情况下,Source Maps存储在单独的文件中。这种技术在生产环境中特别有益,因为不需要实时加载Source Maps

通过选择外部Source Maps,您可以保持较小的生产文件,而不会牺牲调试能力。此分离简化了应用程序的结构,使其在生产环境中更容易检查。

在某些情况下,您可能选择不为生产包生成Source Maps,这也可以通过禁用Source Maps来提供一定程度的混淆。这种方法在测试期间非常有价值,以确定是否希望为生产启用Source Maps

  • 位置:外部Source Maps存储在具有 .map 文件扩展名的单独文件中(例如,script.js 和 script.js.map)。

  • 用法:这些通常在开发环境中使用,在构建过程中生成源映射,但只提供缩小的JavaScript给用户。

  • 优点:
    较小的文件大小:缩小的JavaScript文件保持较小,减少了网络传输时间。
    更好的缓存:对源代码或Source Maps的更改不需要重新分发整个JavaScript文件。

  • 缺点:
    稍微更复杂的设置:管理单独的Source Maps文件。
    链接到JavaScript文件中的外部源映射的示例:

1
//# sourceMappingURL=/path/to/script.js.map
3. 隐藏Source Maps

Source Maps映射具有特定的目的:它们在部署的应用程序中发生错误时提供了必要的堆栈跟踪信息。

当错误发生时,这些映射尤其有价值,可以准确定位故障的原因,并帮助解决问题的情况。为了利用这些信息,开发人员可以将隐藏的Source Maps链接到跟踪服务。

虽然不是最理想的解决方案,但这种做法确保即使在实时环境中,您也可以了解潜在的问题。了解潜在问题的好处超过了没有优化解决方案的缺点。

  • 位置:隐藏的Source Maps存储在服务器上,客户端浏览器无法访问。它们主要用于安全原因,以保持原始源代码的保密性。

  • 用法:当您希望保护您的知识产权或敏感代码,同时仍然在开发过程中受益于源映射时,这些是必不可少的。

  • 优点:
    代码保护:即使使用Source Maps进行开发,也可以防止用户
    访问原始源代码。

  • 缺点:
    调试限制:开发人员无法在其浏览器中使用源映射进行调试,因为Source Maps对客户端不可见。
    隐藏源映射的使用示例:Source Maps安全地存储在服务器上,不在客户端代码中引用或暴露。

浏览器对Source Maps的支持

Source Maps已经在现代Web浏览器中得到了广泛的接受,结果是内置的支持,确保在各种开发环境中获得一致且有效的调试体验

以下是主流浏览器中Source Maps的兼容性概述:

    1. Google Chrome
      Google Chrome广泛受到开发人员的使用,并提供了强大的源映射支持。当您在Chrome开发者工具中遇到错误时,如果有Source Maps可用,它会自动加载相关的Source Maps。这使您可以直接在浏览器中检查和调试原始源代码。
  1. Mozilla Firefox
    Firefox是另一个完全支持Source Maps的浏览器。它将它们无缝集成到其开发者工具中,使开发人员能够轻松地导航和调试他们的代码。Firefox通过源映射集成提供了用户友好的调试体验。

  2. Safari
    苹果的Safari浏览器也支持源映射,允许使用macOSiOS设备的开发人员从高效的调试工作流程中受益。与ChromeFirefox类似,Safari的开发者工具充分利用了源映射进行准确的调试。

    1. Microsoft Edge
      作为Internet Explorer的继任者,Microsoft Edge采用了现代的Web开发实践,并支持源映射。使用Edge的开发人员可以在处理缩小或转译代码时期望一致且高效的调试体验。

结论

通过Source Maps,快速有效地修复代码,回到原始源文件,并更好地了解浏览器的操作成为可能。当Source MapsChrome和Firefox等开发者工具结合使用时,调试和查看问题立即变得更加简单。

在本博客中,我们看到了Source Maps的必要性以及在使用Source Maps时调试变得更加简单的原因。还了解了源映射的类型以及它们如何与其他浏览器配合使用。

现在,我们可以轻松地在我们的JavaScript的缩小形式和未缩小的代码之间进行映射。任何处理过的文件都可以使用源映射,一种基于JSON的映射格式,来建立源和处理结果之间的映射连接。

对于我们的缩小JavaScript,我们从CoffeeScript输出的内容,我们从Less输出的内容,以及我们从Sass输出的内容,我们都可以使用源映射!我们的目标是创建一个JavaScript源映射,用于管理我们的缩小JavaScript的本地化。