源代码映射是现代 Web 开发中的一种重要工具, 大大简化本页介绍了源代码映射的基础知识,以及它们是如何 以及它们如何改善调试体验。
对源映射的需求
早期的 Web 应用是以较低的复杂性构建的。开发者部署了 HTML、CSS 和 JavaScript 文件直接上传到网络。
更现代和更复杂的 Web 应用可能需要各种工具 开发工作流。例如:
- 模板语言和 HTML 预处理器:Pug、 Nunjucks、 扣分。
- CSS 预处理器:SCSS、 LESS、PostCSS。
- JavaScript 框架:Angular、React、 Vue、Svelte。
- JavaScript 元框架:Next.js、 Nuxt、Astro。
- 高级编程语言: TypeScript、 Dart、 CoffeeScript。
![各种工具的简要概览。](https://web.developers.google.cn/static/articles/source-maps/image/a-brief-overview-various-769879995ff7c.png?authuser=7&hl=ro)
这些工具需要通过构建流程将您的代码转译为标准 HTML, 包括浏览器可以理解的 JavaScript 和 CSS 文件一种常见的做法是 使用 Terser。
例如,使用构建工具,我们可以转译和压缩以下代码 TypeScript 文件扩展为一行 JavaScript。您可以在 GitHub 上的这个演示。
/* A TypeScript demo: example.ts */
document.querySelector('button')?.addEventListener('click', () => {
const num: number = Math.floor(Math.random() * 101);
const greet: string = 'Hello';
(document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
console.log(num);
});
压缩版本为:
/* A compressed JavaScript version of the TypeScript demo: example.min.js */
document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));
不过,压缩代码会增加调试难度。源代码映射 可以解决这个问题:通过将编译后的代码映射回原始代码, 可帮助您快速找到错误的根源。
生成源代码映射
源映射是名称以 .map
结尾的文件(例如,
example.min.js.map
和 styles.css.map
)。大多数构建
包括 Vite、Webpack、
Rollup、Parcel 和
esbuild。
默认情况下,某些工具包含源代码映射。其他人可能需要额外的 以生成它们:
/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */
export default defineConfig({
build: {
sourcemap: true, // enable production source maps
},
css: {
devSourcemap: true // enable CSS source maps during development
}
})
了解源代码映射
为帮助调试,以下源映射文件包含重要信息 与原始代码之间的对应关系这里的 源代码映射:
{
"mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
"sources": ["src/script.ts"],
"sourcesContent": ["document.querySelector('button')..."],
"names": ["document","querySelector", ...],
"version": 3,
"file": "example.min.js.map"
}
源代码映射最重要的部分是 mappings
字段。它使用
VLQ base 64 编码字符串
将编译文件中的行和位置映射到对应的原始
文件。您可以使用如下源代码映射可视化工具查看此映射:
source-map-visualization 或
源代码映射可视化。
![源代码映射可视化。](https://web.developers.google.cn/static/articles/source-maps/image/a-source-map-visualizatio-4866bc351df59.png?authuser=7&hl=ro)
左侧的 generated 列显示了压缩的内容, 原始列会显示原始来源。
可视化工具会用颜色标记 original 列中的每一行, 相应的代码(位于 generated 列中)。
映射部分显示了代码的解码映射。例如,
条目 65 -> 2:2
是指:
- 生成的代码:单词
const
从压缩内容中的位置 65 开始。 - 原始代码:在原始内容中,单词
const
从第 2 行和第 2 列开始。
![映射条目。](https://web.developers.google.cn/static/articles/source-maps/image/mapping-entry-dc9df15808405.png?authuser=7&hl=ro)
65 -> 2:2
条目。这样,开发者就可以快速确定缩减后的代码之间的关系 和原始代码,从而使调试过程变得更加顺畅。
浏览器开发者工具会利用这些源代码映射, 以便在浏览器中快速调试问题。
<ph type="x-smartling-placeholder">![用于应用源映射的开发者工具。](https://web.developers.google.cn/static/articles/source-maps/image/developer-tools-applies-ea66f57e838eb.png?authuser=7&hl=ro)
源代码映射扩展
来源映射支持以 x_
前缀开头的自定义扩展字段。一个
示例是 Chrome 建议的 x_google_ignoreList
扩展程序字段
开发者工具。请参阅 x_google_ignoreList
,详细了解这些扩展程序如何帮助您专注于编写代码。
源代码映射的缺点
遗憾的是,源映射并非总能如期完成。
在第一个示例中,变量 greet
在构建期间被优化了
处理,即使其值直接嵌入到最终字符串输出中也是如此。
![变量问候语未映射。](https://web.developers.google.cn/static/articles/source-maps/image/variaqble-greet-is-map-a93a440f3c171.png?authuser=7&hl=ro)
greet
变量
映射中缺少代码。在这种情况下,当您调试代码时,开发者工具可能无法 推断并显示实际值。此类错误会导致您的代码 加大监控和分析的难度。
<ph type="x-smartling-placeholder">![变量问候语未定义。](https://web.developers.google.cn/static/articles/source-maps/image/variable-greet-is-undefin-19fcbf9a06a26.png?authuser=7&hl=ro)
greet
”的值。这是需要在源映射的设计中解决的问题。一个 可能的解决方案是将范围信息添加到 就像其他编程语言处理调试信息一样。
不过,这需要整个生态系统通力合作,共同改善 源映射规范和实现。为了跟踪 改进源代码映射的可调试性,请参阅 Source Maps v4 。