大家好,又见面了,我是你们的朋友全栈君。
官方手册传送门
官方对devtool配置的定义很简单:选择一种 source map 格式来增强调试过程,不同的值会明显影响到构建build和重新构建rebuild的速度。
不过,什么是source map,官方用提供了许多种的source map,其中的区别是什么,我们在开发中应该怎么选择,都是我们要学习的。
1. 什么是 source map
现在的前端代码会通过babel编译或者各类的压缩,在debug时,只能调试编译或者压缩后的代码。简单来说,source map 提供了一种将压缩文件中的代码映射回源文件中的原始位置的方法。
下为 react 项目代码使用source map前后图
编译后的代码
使用source map后的代码
使用source map后,我们可以相当于是在自己写的代码里调试了~
1.1 source map的分类
source map 文件分为2类,内联型和外联型
- 内联源映射,将映射的数据之间添加在生成的文件中,在
.map
文件中的sourcesContent
字段来存放源码 - 外联源映射,将映射数据存储在单独的映射文件中,使用标记将源链接到源码,一般会去掉源码中的注释
1.2 source map 关键字
webpack为 source map 提供了几个关键字,具体的看下表:
关键字 | 含义 |
---|---|
eval | 使用 eval 包裹代码 |
source-map | 生成.map文件 |
cheap | 不包含列信息,也不包括loader的sourcemap |
module | 包括loader的sourcemap |
inline | 将.map作为DataURL嵌入,不单独生成.map文件 |
2. webpack 提供的几种source map模式
source map模式都是上面介绍的关键字进行拼接构成
devtool | 构建速度 | 重新构建速度 | 生产环境 | 品质(quality) |
---|---|---|---|---|
(none) |
|
| yes | 打包后的代码 |
eval |
|
| no | 生成后的代码 |
cheap-eval-source-map |
|
| no | 转换过的代码(仅限行) |
cheap-module-eval-source-map | o |
| no | 原始源代码(仅限行) |
eval-source-map | – |
| no | 原始源代码 |
cheap-source-map |
| o | no | 转换过的代码(仅限行) |
cheap-module-source-map | o | – | no | 原始源代码(仅限行) |
inline-cheap-source-map |
| o | no | 转换过的代码(仅限行) |
inline-cheap-module-source-map | o | – | no | 原始源代码(仅限行) |
source-map | – | – | yes | 原始源代码 |
inline-source-map | – | – | no | 原始源代码 |
hidden-source-map | – | – | yes | 原始源代码 |
nosources-source-map | – | – | yes | 无源代码内容 |
非常快速,
快速,
比较快,
o
中等,-
比较慢,--
慢
2.1 品质(quality)说明
打包后的代码
– 将所有生成的代码视为一大块代码。你看不到相互分离的模块。
生成后的代码
– 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 生成的代码。示例:你会看到类似 var module__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42); module__WEBPACK_IMPORTED_MODULE_1__.a();
,而不是 import {test} from "module"; test();
。
转换过的代码
– 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 转换前、loader 转译后的代码。示例:你会看到类似 import {test} from "module"; var A = function(_test) { ... }(test);
,而不是 import {test} from "module"; class A extends test {}
。
原始源代码
– 每个模块相互分离,并用模块名称进行注释。你会看到转译之前的代码,正如编写它时。这取决于 loader 支持。
无源代码内容
– source map 中不包含源代码内容。浏览器通常会尝试从 web 服务器或文件系统加载源代码。你必须确保正确设置 output.devtoolModuleFilenameTemplate
,以匹配源代码的 url。
(仅限行)
– source map 被简化为每行一个映射。这通常意味着每个语句只有一个映射(假设你使用这种方式)。这会妨碍你在语句级别上调试执行,也会妨碍你在每行的一些列上设置断点。与压缩后的代码组合后,映射关系是不可能实现的,因为压缩工具通常只会输出一行。
3. source map 选择
3.1 开发环境
以下选项非常适合开发环境:
eval
– 每个模块都使用 eval()
执行,并且都有 //@ sourceURL
。此选项会非常快地构建。主要缺点是,由于会映射到转换后的代码,而不是映射到原始代码(没有从 loader 中获取 source map),所以不能正确的显示行数。
eval-source-map
– 每个模块使用 eval()
执行,并且 source map 转换为 DataUrl 后添加到 eval()
中。初始化 source map 时比较慢,但是会在重新构建时提供比较快的速度,并且生成实际的文件。行数能够正确映射,因为会映射到原始代码中。它会生成用于开发环境的最佳品质的 source map。
cheap-eval-source-map
– 类似 eval-source-map
,每个模块使用 eval()
执行。这是 “cheap(低开销)” 的 source map,因为它没有生成列映射(column mapping),只是映射行数。它会忽略源自 loader 的 source map,并且仅显示转译后的代码,就像 eval
devtool。
cheap-module-eval-source-map
– 类似 cheap-eval-source-map
,并且,在这种情况下,源自 loader 的 source map 会得到更好的处理结果。然而,loader source map 会被简化为每行一个映射(mapping)。
3.2 特定场景
以下选项对于开发环境和生产环境并不理想。他们是一些特定场景下需要的,例如,针对一些第三方工具。
inline-source-map
– source map 转换为 DataUrl 后添加到 bundle 中。
cheap-source-map
– 没有列映射(column mapping)的 source map,忽略 loader source map。
inline-cheap-source-map
– 类似 cheap-source-map
,但是 source map 转换为 DataUrl 后添加到 bundle 中。
cheap-module-source-map
– 没有列映射(column mapping)的 source map,将 loader source map 简化为每行一个映射(mapping)。
inline-cheap-module-source-map
– 类似 cheap-module-source-map
,但是 source mapp 转换为 DataUrl 添加到 bundle 中。
3.3 生产环境
这些选项通常用于生产环境中:
(none)
(省略 devtool
选项) – 不生成 source map。这是一个不错的选择。
source-map
– 整个 source map 作为一个单独的文件生成。它为 bundle 添加了一个引用注释,以便开发工具知道在哪里可以找到它。
hidden-source-map
– 与 source-map
相同,但不会为 bundle 添加引用注释。如果你只想 source map 映射那些源自错误报告的错误堆栈跟踪信息,但不想为浏览器开发工具暴露你的 source map,这个选项会很有用。
nosources-source-map
– 创建的 source map 不包含 sourcesContent(源代码内容)
。它可以用来映射客户端上的堆栈跟踪,而无须暴露所有的源代码。你可以将 source map 文件部署到 web 服务器。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。