Webpack中的sourcemap
Webpack中sourcemap的配置
sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术。尤其是如今前端开发中大部分的代码都经过编译,打包等工程化转换。比如开发环境下用scss写样式, 想在浏览器中在线编辑css那样编辑scss就不是那么容易了。从我自己看过的资料中, sourcemap的概念最早出现在12年, jquer1.9是较早支持sourcemap的库。这篇博客比较有代表性:Introduction to JavaScript Source Maps,阮一峰的文章JavaScript Source Map 详解也大量参考该博客。关于sourcemap的原理及作用,基本在这两篇文章中讲清楚了。回到webpack中的sourcemap,就我这几天的琢磨, 这方面资料相对比较零散,但凡搜索Webpack中sourcemap的配置, 总是能得到千篇一律的如下信息:
Sourcemap type Quality Notes
eval: 生成代码 每个模块都被eval执行,并且存在@sourceURL
cheap-eval-source-map: 转换代码(行内) 每个模块被eval执行,并且sourcemap作为eval的一个dataurl
cheap-module-eval-source-map: 原始代码(只有行内) 同样道理,但是更高的质量和更低的性能
eval-source-map: 原始代码 同样道理,但是最高的质量和最低的性能
cheap-source-map: 转换代码(行内) 生成的sourcemap没有列映射,从loaders生成的sourcemap没有被使用
cheap-module-source-map: 原始代码(只有行内) 与上面一样除了每行特点的从loader中进行映射
source-map: 原始代码 最好的sourcemap质量有完整的结果,但是会很慢
webpack中devtool的配置的官方文档在这 :webpack-devtool
疑问
反正我看完这些说明是云里雾里, 就我自己而言, 有3个疑问:
eval和sourcemap有什么关系,eval模式是sourcemap吗?
包含cheap关键字的配置中只有行内是什么意思?
这几种不同的配置有什么区别?
解答
看似配置项很多, 其实只是五个关键字eval
,source-map
,cheap
,module
,inline
的任意组合。这五个关键字每一项都代表一个特性, 这四种特性可以任意组合。它们分别代表以下五种特性(单独看特性说明有点不明所以,别急,往下看):
eval: 使用eval包裹模块代码
source-map: 产生
.map
文件cheap: 不包含列信息(关于列信息的解释下面会有详细介绍)也不包含loader的sourcemap
module: 包含loader的sourcemap(比如jsx to js ,babel的sourcemap)
inline: 将
.map
作为DataURI嵌入,不单独生成.map
文件(这个配置项比较少见)
了解了以上各种不同特性, 再来逐一解答以上问题。
eval和sourcemap有什么关系,eval模式是sourcemap吗?
eval
和source-map
都是webpack中devtool的配置选项, eval
模式是使用eval
将webpack中每个模块包裹,然后在模块末尾添加模块来源//# souceURL
, 依靠souceURL
找到原始代码的位置。包含eval关键字的配置项并不单独产生.map
文件(eval模式有点特殊, 它和其他模式不一样的地方是它依靠sourceURL来定位原始代码, 而其他所有选项都使用.map
文件的方式来定位)。包含source-map
关键字的配置项都会产生一个.map
文件,该文件保存有原始代码与运行代码的映射关系, 浏览器可以通过它找到原始代码的位置。(注:包含inline
关键字的配置项也会产生.map
文件,但是这个map文件是经过base64编码作为DataURI嵌入),举个栗子:eval-source-map
是eval
和source-map
的组合,可知使用eavl
语句包括模块,也产生了.map
文件。webpack将.map
文件作为DataURI替换eval
模式中末尾的//# souceURL
。按照我自己的理解, eval
和.map
文件都是sourcemap实现的不同方式,虽然大部分sourcemap的实现是通过产生.map
文件, 但并不表示只能通过.map
文件实现。下面是eval模式后产生的模块代码:
包含cheap关键字的配置中只有行内是什么意思?
这里的列信息指的是代码的不包含原始代码的列信息。 官方文档对于包含cheap
的解释是这样的:
> cheap-source-map - A SourceMap without **column-mappings**. SourceMaps
> from loaders are not used.
这句话翻译过来就是“在cheap-source-map模式下sourcemap不包含列信息,也不包含loaders的sourcemap”这里的“column-mappings”就是代码列数的意思,是否包含loaders的sourcemap有什么区别将在之后提到。debug的时候大部分人都只在意代码的行数, 很少关注列数, 列数就是该行代码从第一个字符开始到定位字符的位置(包括空白字符)包含cheap
关键字的模式不包含列信息,体现在webpack中就是:如果包含cheap
关键字,则产生的.map
文件不包含列信息。也就是说当你在浏览器中点击该代码的位置时, 光标只定位到行数,不定位到具体字符位置。而不包含cheap
关键字时, 点击控制台log将会定位到字符位置。
包含列信息后点击原始代码的定位,注意光标位置:
不包含列信息的光标位置:
这篇博客:Go to a line number at a specific column直观地展示了列数的概念。如果深入到webpack中的细节中体会该配置项,可以看这篇博客:SurviveJS:Source Maps ,该文章对比了webpack中所有配置项中.map
文件的代码,这里截取eval-source-map
和cheap-source-map
的模式产生的.map
文件代码中的mappings
字段对比:
devtool: 'eval-source-map'
"mappings": "AAAAA,QAAQC,GAAR,CAAY,aAAZ",
devtool: 'cheap-source-map'
"mappings": "AAAA",
注:这里使用了VLQ编码,(关于VLQ编码还可参考这里:前端构建:Source Maps详解) 在VLQ编码中,逗号,
表示字符列分割,分号;
表示行分割。包含cheap
关键字的配置项不包含列信息,也就没有逗号。关于VLQ编码, 本文最初的阮一峰的文章中有所解释。而不包含loader的sourcemap指的是不包含loader的sourcemap,不包含它时候如果你使用了诸如babel等代码编译工具时, 定位到的原始代码将是经过编译后的代码位置,而非原始代码。
比如当我用babel编译JS的时候,如果包含不包含loaders的sourcemap,此时debug到的将是编译后的代码, 而非原始代码,如图(这是使用cheap-source-map模式未包含loaders的sourcemap情况下的截图, debug的位置与之前的对比截图是同一个地方):
这几种不同的配置有什么区别?
通过以上两个问题的解释, webpack中的sourcemap各个配置项异同应该有了一定认识,乍看之下各个配置项很难记忆, 但其实从每个关键字所代表的特性入手, 就能体会到他们的异同。他们在webpack中的主要区别一个体现在重构的性能上, 总的来说eval
性能最好,source-map
性能最低,但就我自身的实践来看大多用的是最完整的source-map
,该模式对于不管是js还是css,scss等都能很好的覆盖, 相反其他模式都不完整, 在开发环境下重构性能似乎比不上功能的完善。
另外需要补充的是module
关键字, 当加上module
关键字webpack将会添加loader的sourcemap。
转载于:https://www.cnblogs.com/axl234/p/6500534.html
Webpack中的sourcemap相关推荐
- Webpack中的sourcemap以及如何在生产和开发环境中合理的设置sourcemap的类型
简要介绍:在webpack的官网,给出了十几种sourcemap,那么每一种sourcemap之间有什么区别,本文在理解sourcemap的基础上,分析在生产和开发环境中,应该采用何种形式的sourc ...
- 【转】webpack中关于source map的配置
Webpack中sourcemap的配置 sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术.尤其是如今前端开发中大部分的代码都经过编译,打包等工程化转换 ...
- 在Vue的webpack中结合runder函数
在Vue的webpack中结合runder函数 1.引入: <h1>下面是vue的内容:</h1><div id="app"><login ...
- 理解webpack中的devTool的配置项
2.1. eval eval 会将每一个module模块,执行eval,执行后不会生成sourcemap文件,仅仅是在每一个模块后,增加sourceURL来关联模块处理前后对应的关系.在webpa ...
- 彻底弄懂Webpack中的Loader机制
一.前言 面对这些框架所衍生出来的文件,现代的模块打包工具,例如 Webpack 本身只能处理 js 和 JSON 文件,其他类型文件它是不能够处理的.需要借助 Loader 来处理这些类型的文件, ...
- webpack打包之sourcemap
认识sourcemap 我们的代码通常运行在浏览器上时,是通过打包压缩的: 也就是真实跑在浏览器上的代码,和我们编写的代码其实是有差异的: 比如ES6的代码可能被转换成ES5: 比如对应的代码行号.列 ...
- Node.js webpack中导入vue的三种方法
在webpack 中使用 Vue: 安装 vue 模块 npm i vue -S 注意: 在 webpack 中, 使用 import Vue from 'vue' 导入的 Vue 构造函数,功能不完 ...
- Vue 单文件组件||Vue 单文件组件的基本用法||webpack 中配置 vue 组件的加载器|| 在 webpack 项目中使用 vue
Vue 单文件组件 传统组件的问题和解决方案 1. 问题 1. 全局定义的组件必须保证组件的名称不重复 2. 字符串模板缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \ 3. 不支持 CS ...
- webpack 中的加载器简介||webpack 中加载器的基本使用——1. 打包处理 css 文件 2. 打包处理 less 文件 3.打包处理 scss 文件
webpack 中的加载器 1. 通过 loader 打包非 js 模块 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块,其他非 .js 后缀名结尾的模块, webpa ...
最新文章
- Matlab 日常技巧 ,判断文件存在
- wxWidgets:wxDC类用法
- .NET Core开发实战(第13课:配置绑定:使用强类型对象承载配置数据)--学习笔记...
- xshell安装mysql步骤_mysql主从复制
- 教师资格证计算机考察知识点,教师资格证考试信息技术常考知识点同步练习题.docx...
- js获取数组中最大和最小值
- ASP文件上传方式大比拼
- BNU 背包密码(编码与解密)
- sql分页查询与offset的使用
- 周报、月报有多折磨人?万能报表模板建议收藏!(附模板)
- 【操作系统】-- 时间片轮转调度算法、优先级调度算法、多级反馈队列调度算法
- CCA分析图如何解读_斯玛特少儿美术分析:如何解读儿童的美术作品
- python 人民币兑美元汇率_人民币汇率转换(python人民币和美元转换)
- 十二星座的来历和希腊神话12主神简介
- 欧拉定理和费马小定理
- 名编辑电子杂志大师教程 | 名编辑电子杂志页面排版最佳尺寸,最佳字体,字号
- iOS开发 swift 3dTouch实现 附代码
- 在 FPGA 上快速构建 PID 算法
- python读取svg_使用Python / PIL读取SVG文件
- python基于django校园信息管理平台设计与实现(项目源码+视频录制+截图)
热门文章
- VCTransitionsLibrary –自定义iOS交互式转场动画的库
- Oracle:ORA-12560和ORA-01031
- oracle缩小表空间
- mac os 命令行下载
- 模糊测试工具Simple Fuzzer
- android谷歌补丁日期,在谷歌日历Android中添加开始日期和结束日期之间所有日期的事件...
- c java 开发android_java代码与纯C代码混编完成android应用的开发
- ubuntu mysql vi_Ubuntu16 下安装 mysql
- recyclerview 滑动到当前_Android recyclerview的滑动到指定的item
- a onclick 未响应_深大李冰石教授、港科大唐本忠院士:在多重刺激响应性材料领域取得最新进展...