一文看懂 webpack 的所有 source map !🤔

神经接口师
• 阅读 2467

一直以来对source map 都懵懵懂懂, 被webpack 所提供的多样的source 给乱花了眼。 这次就决定来一一尝试一下各种source map的区别

什么是source map

现代的前端开发总是伴随的各种框架, 在使用这些框架开发的代码需要经过编译才可以在生产环节使用, 编译后就伴随着可读性的降低,也会影响我们的错误调试。
那source map就是为了解决这个问题。

Source map可以理解为一个地图, 通过它可以获知编译后的代码 对应编译前的代码位置。这样当代码遇到异常, 我们就可以通过报错信息定位至准确的位置。 同时在浏览器 sources 也可以查看到源码。

编译后的代码内只需要包含这样一句

// @ sourceMappingURL=map文件路径

就可以关联上 source map文件了

devtool

webpack 通过 devtool 控制需要生成的 source map 类型

我们来看一下 devtool 的支持的属性devtool, 可以看到 source map 同时也分为很多种,但大体上都是加载形式的区别, 本质的核心还是相同的。

把它们罗列出来居然有这么多

  • eval
  • eval-cheap-source-map
  • eval-cheap-module-source-map
  • eval-source-map
  • cheap-source-map
  • cheap-module-source-map
  • source-map
  • inline-cheap-source-map
  • inline-cheap-module-source-map
  • inline-source-map
  • eval-nosources-cheap-source-map
  • eval-nosources-cheap-module-source-map
  • eval-nosources-source-map
  • inline-nosources-cheap-source-map
  • inline-nosources-cheap-module-source-map
  • inline-nosources-source-map
  • nosources-cheap-source-map
  • nosources-cheap-module-source-map
  • nosources-source-map
  • hidden-nosources-cheap-source-map
  • hidden-nosources-cheap-module-source-map
  • hidden-nosources-source-map
  • hidden-cheap-source-map
  • hidden-cheap-module-source-map
  • hidden-source-map

看到这么多,已经开始慌了。 不过不用怕, 其实我们理解核心的几个关键字就可以了。

一文看懂 webpack 的所有 source map !🤔

来看一下文档上对这些命名的解释,

  • eval- :使用eval 生成source map , 不会生成额外的 .map 文件, 而是在eval 函数内附加 source map 。 推荐用于开发环境, 因为 相对来说构建和热更新都比较快。
  • inline-* : 将SourceMap内联到原始文件中,同样 不会生成额外的 .map 文件。
  • hidden-* :addition会生成source map 但是不会将其关联, 也就是不会在编译后的代码内添加上面提到的那个映射语句。
  • nosources-* :sourcemap 中不带源码, 但会有准确的错误行列信息, 避免源码泄露。
  • cheap-* : 忽略列信息,source map 只有行映射,可以加快打包速度
  • cheap-module-* : moudle 关键子一定是跟 cheap 一起使用的, 表示所映射的阶段, 如果没有 module 映射的是 loader 处理前的代码信息,如果加了 module 那就是 loader 处理后的源码, 举个例子, const a = 1 这行, 如果没加 module 那拿到的就是转为 es5 的 var a = 1, 如果加了module , 那拿到的就是 const a = 1

理解了这些之后,再来看上面这一堆不同类型的 source map 也就能看懂了。

什么? 还不懂? 那我们来动手尝试一下几个典型的!

我们在代码内故意打印未定义的变量 c, 看看不同的 source map 下的错误信息结果

一文看懂 webpack 的所有 source map !🤔

注意: 行号为 9

eval

修改配置

一文看懂 webpack 的所有 source map !🤔

首先我们在 devtool 填写 eval 。

运行构建

进行一次 run build 构建看看。

可以看到生成的结果, 上方注释写明了这是来自哪个文件的编译结果, 当然这个是 webpack 的加载逻辑, 我们这里可以不用太过关系, 往内部看, 内部是一个 eval 函数, 内部是编译后的代码。

一文看懂 webpack 的所有 source map !🤔

然后我们看到末尾, eval 的末尾有 sourceURL=webpack:///./src/views/About.vue?

一文看懂 webpack 的所有 source map !🤔

错误信息

然后我们运行一下项目, 看看他的报错信息如何。

一文看懂 webpack 的所有 source map !🤔

可以看到其实并不是非常清晰的, 瞅一眼大概能明白是哪个文件爆的错, 但行号之类的完全不对,而且点击进去的也是编译后的信息

查看详情:

一文看懂 webpack 的所有 source map !🤔

完全是编译后的代码。

这就是 eval 模式下的 source map 方式, 他不会生成实际的 .map 文件, 但会在 eval 函数末尾添加对原本文件的映射语句, 指向源文件本地地址, 同时调试体验也较差。 因此也就无法在生产环境使用了。

如果想要更清晰的错误信息还是需要使用 eval-source-map

source-map

最标准的 source-map 打包形式

修改配置:

一文看懂 webpack 的所有 source map !🤔

运行构建:

一文看懂 webpack 的所有 source map !🤔

可以看到生成了很多 .map 文件

一文看懂 webpack 的所有 source map !🤔

进入一份js文件, 我们可以看到代码的末尾关联了一份 .map 文件

错误信息:

一文看懂 webpack 的所有 source map !🤔

可以看到错误定位还是比较准确的, 找到了正确的 9 行,然后我们点进去看看

一文看懂 webpack 的所有 source map !🤔

很完美,是我们正确的源码信息, 并且成功定位到具体列。

inline-source-map

运行构建:

一文看懂 webpack 的所有 source map !🤔
没有 .map 文件的产出

一文看懂 webpack 的所有 source map !🤔

source map 数据直接内联

错误信息:

一文看懂 webpack 的所有 source map !🤔

能定位到 行号

查看详情:

一文看懂 webpack 的所有 source map !🤔

完美展示,同样也能够定位至列

nosources-source-map

运行构建:

一文看懂 webpack 的所有 source map !🤔

有 .map 文件

一文看懂 webpack 的所有 source map !🤔

有路径映射

错误信息:

一文看懂 webpack 的所有 source map !🤔

行号准确

查看详情:

一文看懂 webpack 的所有 source map !🤔

没有源码信息, 无法加载

hidden-source-map

运行构建:

一文看懂 webpack 的所有 source map !🤔

有 .map 文件

一文看懂 webpack 的所有 source map !🤔

没有映射路径

错误信息:

一文看懂 webpack 的所有 source map !🤔

错误信息模糊

查看详情:

一文看懂 webpack 的所有 source map !🤔

完全是编译后的代码

cheap-source-map

运行构建:

一文看懂 webpack 的所有 source map !🤔

有 .map 文件

一文看懂 webpack 的所有 source map !🤔

有映射路径

错误信息:

一文看懂 webpack 的所有 source map !🤔

行号不正确

查看详情:

一文看懂 webpack 的所有 source map !🤔

是被处理过的代码,并且没有定位到具体列

cheap-module-source-map

运行构建:

一文看懂 webpack 的所有 source map !🤔

有 .map 文件

一文看懂 webpack 的所有 source map !🤔

有映射路径

错误信息:

一文看懂 webpack 的所有 source map !🤔

行号正确

查看详情:

一文看懂 webpack 的所有 source map !🤔

正确的源码,但无法定位到具体列。

结尾

搞清楚 source map 这些区别的关键就在于先要弄懂关键字所表示的含义,其余的都是 “组装” 。

点赞
收藏
评论区
推荐文章
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
不才 不才
4年前
JavaScript sourceMap 笔记
jssourcemap建议打开一个真实的项目的sourceMap对照食用由于前端项目在网络中访问导致为了减少体积进行一系列优化操作,最后导致生产环境出问题无法定位到项目代码中的指定位置,使得调试变成一件很难得事。由此产生了SourceMap。它是个什么东西简单说,sourceMap就是一个文件,里面储存着位置信息。仔细点说,这个
九路 九路
4年前
Swift开发-OC与Swift混编以及纯Swift编码所遇到的问题(二)
上篇在介绍了Swift与OC混编开发所需要准备的一些必要条件 SwiftObjectiveC混编注意事项(https://www.jianshu.com/p/52ab6a316cbe),今天只说一下我在实际项目中所踩过的坑,希望你们以后绕过这些坑吧。1、使用cocopods管理Swift文件所遇到的问题:我们在开发的过程中,各种优秀的框架
Jacquelyn38 Jacquelyn38
4年前
Vue3.0系列——「vue3.0学习手册」第一期
Vue3.0一、项目搭建vite是尤大大开发的一款意图取代webpack的工具。其实现原理是利用ES6的import发送请求加载文件的特性。拦截这些请求,做一些编译,省去webpack冗长的打包时间。并将其与Rollup捆绑在一起用于生产。在开发过程中没有捆绑。源代码中的ESImport语法直接提供给浏览器,浏览器通过本机<scriptmodule支持对
Wesley13 Wesley13
3年前
vite2 引入 vectorize
这个库在webpack中是正常的,但是在vite2项目中无法使用也不报错,只是结果总是空....看了下是个老项目了,依赖的也都是好几年没更新的库...看来webpack在兼容性方面还是要强不少的    尝试使用parcel打包后使用,不太行...用webpack打包后使用....也不行...有时间再研究研究,看看能不能写个类似的.
Easter79 Easter79
3年前
The way of Webpack learning (VI.)
使用commonChunkPlugin的都是基于webpack3.10.0,在webpack4中直接配置optimization就可以了。一:什么是长缓存?浏览器在用户访问页面的时候,为了加快加载速度,对用户请求的静态资源都会进行存储,但是每次代码更新或者升级的时候,我们都需要浏览器去加载新的代码。最方便的方法就是引入新的文件名称,只下载新的
Wesley13 Wesley13
3年前
Java Spring 教程网站推荐
Spring是一个企业Java框架。它旨在简化JavaEE开发并提高开发人员的生产力。Spring利用控制反转和依赖注入来促进良好的软件编码实践并缩短开发时间。Spring框架是Java平台的应用程序框架和控制容器的倒置。该框架的核心功能可以被任何Java应用程序使用。尽管该框架没有强加任何特定的编程模型,但是它已在Java社区中流行起来,它包括提供各种
警惕!自定义注解使用不当的排查实录
一、引言大家好,在日常开发过程中,Java注解(Annotation)是开发中经常使用的一个手段,用于给代码添加元数据的标记。它们可以提供代码额外的信息,这些信息可以在编译时或运行时被访问。注解不会改变代码的执行逻辑,但可以被编译器、JVM或框架等工具用于