简介

Source Map 是⼀种源代码与构建后代码之间的映射技术。⽤于快速定位问题代码 构建后的代码出了问题不好定位(所有代码都被压缩到⼀⾏了),Source Map 可以将问题代码映射 (定位)到源代码。

使⽤ Source Map

// webpack.config.js module.exports = { // devtool: ‘映射模式 devtool: ‘source-map’ } source-map 模式打包后,会⽣成 xxxx.map ⽂件 映射模式:https://www.webpackjs.com/configuration/devtool/

.map ⽂件解析

version: Source Map 的版本,⽬前为 3 sources:源码⽂件,该项是⼀个数组,表示可能存在多个⽂件合并 names:包含源码⽂件所有变量和函数名的数组 mappings:包含代码映射的字符串(Base64-VLQs 编码) file:Source Map 指向的⽂件名称 sourcesContent:转换前的源码内容,与 sources 列表依次对应。 sourceRoot:转换前的⽂件所在的⽬录,如果与转换前的⽂件在同⼀个⽬录,该项为空。 其中,最终要的字段是 mappings,他是 Base64-VLQs 编码的字符串,包含代码映射关系。 “mappings”:“2HAGO,SAASA,IACd,MAAO,oB,2BAHTC,QAAQC,IAAI” 分割的⼀组对应⽣成代码中的⼀⾏;每⼀组⽤,分割的⼀段对应⽣成代码中的⼀个位置信息; 每⼀段⾥是5个数字的Base64 VLQ编码,⽐如[9,0,0,9,0]这5个数字的编码是SAASA: 第0个数字,表示这个位置在⽣成代码的第⼏列; 第1个数字,表示这个位置属于 sources 属性中的哪⼀个⽂件; 第2个数字,表示这个位置属于原始代码的第⼏⾏; 第3个数字,表示这个位置属于原始代码的第⼏列; 第4个数字,表示这个位置属于 names 属性中的哪⼀个变量。这个数字不是必需的,可以省略。 VLQ 在线编码解码⼯具:https://www.murzwin.com/base64vlq.html

映射模式

不同的映射模式,执⾏效果和执⾏速度不同。我们在充分了解各个映射模式的特点之后,可以依据⾃⼰的现实需要,选择最合适的⼀种。 Webpack 5 中的映射模式如下(先后顺序不能错) ^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$ 详情查看:https://webpack.js.org/configuration/devtool/

Webpack 4 中,⼀共有 13 中映射模式

源码映射(Source Map) - 图1

Webpack 5 中,⼀共有 26 中映射模式

webpack 5 中,映射模式的写法更为严格。例如:cheap-module-eval-source-map 在 Webpack 4 中是可以⽤的。但是,在 webpack 5 中,我们必须写成 eval-cheap-module-source-map

源码映射(Source Map) - 图2

source-map

⽣成独⽴的 .map ⽂件,.map ⽂件通过 //# sourceMappingURL=desc.bundle.js.map 与 .js 建⽴映 射关系。其中 //# sourceMappingURL=desc.bundle.js.map 在 .js ⽂件的末尾。

定位报错时,有详细的⾏列信息。

包含最详细的信息,也是打包最慢的⼀种。

源码映射(Source Map) - 图3

cheap-source-map

⽣成独⽴的 .map ⽂件,但是 .map ⽂件中没有 names 属性。定位错误时,只能定位到⾏,不能定位到 列。带有 cheap 关键字的映射模式,都少了列信息。是⼀个简化版的 source-map。其⽣成的 .map ⽂ 件,⽐ source-map 模式下的 .map ⽂件⼩。但是打包速度快。 ⼀般来说,报错定位到⾏已经⾜够了,没有必要定位到列

源码映射(Source Map) - 图4

源码映射(Source Map) - 图5

cheap-module-source-map

⽣成独⽴的 .map ⽂件,但是 .map ⽂件中,没有 names 和 sourcesContent 字段。即 .map ⽂件更为 简化。但它包含 loader 和第三⽅模块的映射。 有时候,我们除了要定位⾃⼰的代码报错之外。还需要考虑第三⽅模块报错的情况。此时,我们可以选择带有 module 关键字的模式。它会包含 loader 和第三⽅模块的映射信息。 源码映射(Source Map) - 图6 #### nosources-source-map ⽣成 .map ⽂件,但是 .map ⽂件中,没有 sourcesContent 字段。如果在浏览器查看,能够定位到报 错。但是不会在浏览器显示源码内容(nosources - 没有源码)。这种⽅式更安全,适合⽣产环境。 源码映射(Source Map) - 图7 #### hidden-source-map ⽣成 .map ⽂件,但是 .js 尾部没有关联 .map ⽂件的注释。 遇到报错时,⼯程师再⼿动关联,查看报错

源码映射(Source Map) - 图8

inline-source-map

不⽣成独⽴的 .map ⽂件,映射关系会追加到 .js ⽂件的尾部。(包含⾏列信息,不包含第三⽅映射)

源码映射(Source Map) - 图9

inline-cheap-source-map

不⽣成独⽴的 .map ⽂件,映射关系会追加到 .js ⽂件的尾部。只包含⾏信息(不包含第三⽅映射) 源码映射(Source Map) - 图10 #### inline-cheap-module-source-map 不⽣成独⽴的 .map ⽂件,映射关系会追加到 .js ⽂件的尾部。只包含⾏信息,包含第三⽅映射 源码映射(Source Map) - 图11 #### eval 不⽣成 .map ⽂件,映射关系会出现在 eval 函数的末尾。 报错时,只能定位到⽂件,不能定位⾏列信息。

包含的报错信息最少,打包速度最快。

源码映射(Source Map) - 图12

eval-source-map

不⽣成 .map ⽂件,映射关系会出现在 eval 函数的末尾。报错时,包含定位的⾏列信息。

源码映射(Source Map) - 图13

eval-cheap-source-map

不⽣成 .map ⽂件,映射关系会出现在 eval 函数的末尾。报错时,包含定位的⾏信息(没有列信息)。

报错信息⽐ eval-source-map 少,打包⽐ eval-source-map 快

源码映射(Source Map) - 图14

eval-cheap-module-source-map

不⽣成 .map ⽂件,映射关系会出现在 eval 函数的末尾。 报错时,包含定位的⾏信息(没有列信息)。包含第三⽅模块的映射 源码映射(Source Map) - 图15 只要掌握关键字,就能明确不同模式之间的区别

cheap: 报错时,只有⾏,没有列信息

inline: 没有独⽴的 .map ⽂件,映射信息在 .js 最后

eval:没有独⽴的 .map ⽂件,映射信息在 eval 函数最后

module:包含第三⽅模块的映射信息

nosources:只提供报错信息,看不到源码

hidden: 隐藏 .js 最后关联 .map ⽂件的注释

Webpack 5 中的模式更多,但关键字没变,还是上述的内容,只是排列组合更多了。

使⽤建议

如何选取合适的映射模式(个⼈建议 - 不绝对)

开发环境(eval-cheap-module-source-map)

⽣产环境(none | nosources-source-map)