为了提升 Web App 的性能,通常我们会把源码压缩混淆后再发布到服务器上
当 App 出现问题时这些压缩过后的代码就会使得我们很难具体定位到错误出现在哪
Source Map 的出现正是为了解决这个难题
通过在压缩后的代码中加入如下注释
// 注意此处的 sourceMappingURL 支持 http uri 以及 data uri 俩种形式
//# sourceMappingURL=/path/to/script.js.map
并在压缩混淆同时生成相应的 map 文件
{
version: 3,
file: "script.js.map",
sources: [
"a.js",
"b.js",
"c.js"
], // 所有源文件的路径
sourceRoot: "/",
names: ["foo", "bar", "func"], // 所有源文件中出现的变量名 函数名
// 关键所在 具体原理就不管了 有点复杂 大致是通过 Base64-VQL 编码做映射
mappings: "AABASD,ASDFDSA,OAAOC,OAAO..."
}
这样浏览器就可以反向定位到错误具体出现在源码中的哪个文件的哪一行中
Ps: 关于原理
浏览器默认只会在打开开发者工具时才去请求 .map 文件
所以在 network 中看不到记录 Stackoverflow
很不幸,答案是会的
更不幸的是,通过 .map 文件以及压缩后的代码可以反向生成源代码
这意味着在公开的生产环境下我们不应该去使用 Source Map
因为这样相当于把整个 App 的源码暴露在外,是一种很危险的行为
建议在类似预发环境(也就是与正式环境相同但是是私有的环境)下来利用 Source Map 进行 Debug
Ps: 还可以通过服务器端的配置来禁止普通用户下载 .map 文件,这样就可以安全的把 .map 文件也放到正式环境上
开发环境我们通常不会采用混淆代码,对于简单的 Javascript 应用可能意义并不大
但当我们在开发 React App 或者 Vue App 时
Source Map 可以将我们 Webpack 打包后的文件直接映射为源代码中的 .jsx/.vue 文件
而不利用 Source Map 我们就只能去 Debug 编译过后的文件
所以即是在开发环境下,Source Map 也是能给我们提供很大帮助的
Webpack 中可以通过这项配置来决定具体使用何种 Source Map
默认值为 false
也就是不启用 Source Map
从方便 Debug 的角度从差到好排列,Webpack 一共提供了如下几种形式的 Source Map
关于 Devtool 的配置大致由如下几种关键字组合而来,每个关键字代表着不同特性
就目前来说
个人感觉在开发环境下设为 cheap-module-eval-source-map
可以获得较好的 Debug 体验,以及较快的编译速度
在预发环境下设为 source-map
可以获得最完整的映射
在正式环境下设为 false
避免源文件暴露
当然碰到具体问题时可以进行调整
要记住 Source Map 的终极目的是为了方便开发者定位问题
所以只要能帮助我们找到问题的配置就是好配置
Ps: Webpack V4 中,当 mode 设为 'production' 时
默认使用的 uglifyjs-webpack-plugin
会默认设置 sourceMap: true
当我们手动去新配置 uglifyjs-webpack-plugin
时会覆盖掉默认配置
所以要注意像如下配置一样加上 sourceMap: true
否则 Souce Map 会不生效
// webpack.prod.config.js
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
module.exports = {
// ...
mode: 'production',
optimization: {
minimizer: [
new UglifyJsPlugin({
// ...
sourceMap: true // 注意这里!!!!!!
// ...
})
]
}
// ...
}