在我的博客A debugging issue caused by source code mapping里我介绍了在我做SAP C4C开发时遇到的一个曾经困扰我很久的问题,最后结论是这个问题由于JavaScript的source code map机制在Chrome开发者工具里起作用,其实是working as designed的一种行为。但是当时因为时间限制,没有去深入学习JavaScript source code map的更多细节。

在这篇文章里我用一个简单的UI5应用来研究该机制。这个应用的UI仅仅包含一个Button,点击之后弹出一个Message Toast。

下面是我XML view和Controller的实现。

打开Chrome开发者工具里的source code map开关:

然后浏览器里访问这个UI5应用,我们就能在Chrome开发者工具里看到这些UI5库文件的调试版本(.dbg.js)。但是在Chrome开发者工具的Network标签里,我们观察不到这些调试版本文件的加载。那么问题来了:这些.dbg.js文件从哪里来的?

当关闭Chrome开发者工具的source code map功能之后,我们在Chrome开发者工具里再也观察不到这些.dbg.js文件了。将下图和source code map打开时的截图做比较:

如何在本地找到sap-ui-core.js.map文件

单击sap-ui-core.js,在其最后一行1875行,看到该行内容:


//# sourceMappingURL=sap-ui-core.js.map

这个文件的后缀.map给了我们提示:其作用就是维护位置映射关系,将sap-ui-core.js(压缩之后的文件)里的代码位置映射到压缩之前的代码位置(来自压缩之前的文件名,代码行数,代码列数,涉及到的压缩之前的JavaScript变量名)。

但是,同样的,我在开发者工具的Network标签里也观察不到这个.map文件被加载。

在Chrome里输入url: "chrome://net-internals/#events", 结果显示确实有一个url请求去访问sap-ui-core.js.map, 只是因为本地磁盘缓存能响应该请求, 因此没有产生真正的网络请求:

在Chrome里输入"chrome://cache"能看到Chrome本地的所有缓存,从这里我成功找到了文件sap-ui-core.js.map的本地缓存。

单击该超链接能看到这条缓存的抬头信息。但是缓存的具体文件内容显示格式为HEX,没法直接分析。

因此我使用了工具Cache viewer for Google Chrome Web browser, 将该缓存导出成本地文件。

sap-ui-core.js.map文件内容一览

这篇博客Introduction to JavaScript Source Maps介绍了JavaScript source code map的基本知识。

文件sap-ui-core.js.map的内容:

  • version: 3

.map文件的各组成部分的作用和含义定义在一个叫做Source Map Revision Proposal的协议文档里,在我的例子sap-ui-core.js.map里使用了该协议的第三版。

  • sources:

这是一个数组,包含了所有用于生成压缩之后的js文件的原始文件的名称。

  • names:

这是一个数组,包含了原始js文件里出现的JavaScript变量和属性名称。

下面是一个例子,体现了原始文件之一Device-dbg.js里的变量名称和其在sap-ui-core.js.map文件里的names数组里的对应记录,方便您理解。

  • mappings:

.map文件最重要的部分,定义了原始文件内的位置和生成压缩版本文件内位置的对应关系。对应关系记录的粒度是基于压缩之后文件的每一行,用分号隔开。这样做的好处是无需再分配而外的位来维护压缩文件位置的行号信息。

回到我的例子,压缩文件sap-ui-core.js一共包含1874行,因此sap-ui-core.js.map一共出现了1874次分号,每个分号内又是一个很长的字符串,由一系列逗号隔开,这些由逗号隔开的字符串片段称为Segment。每个Segment维护了一个位置的映射关系。

如何生成.map文件

有很多开源的组件用于生成.map文件,其中之一是Google Closure compiler。假设我想基于我的测试应用里的controller实现文件App.controller.js生成一个压缩版本的文件:

Google网站下载compile.jar, 然后生成一个名为script-min.js的压缩文件和script-min.js.map:


java -jar compile.jar --js App.controller.js --create_source_map ./script-min.js.map --source_map_format=V3 --js_output_file script-min.js

生成的压缩文件script-min.js只有1行内容:

生成的script-min.js.map内容:

可以使用vlq.js将这些segment解码:

浏览器打开该html,产生如下输出:每个segment由4或5个字符组成。

每一位的对应含义:

  • 第一位,表示这个位置在转换后的压缩文件的第几列。

  • 第二位,sources数组中的索引,表示这个位置来自哪一个原始文件。

  • 第三位,表示这个位置属于原始文件的第几行。

  • 第四位,表示这个位置属于原始文件的第几列。

  • 第五位,names数组中的索引,表示这个位置属于源文件中的哪一个变量。

关于VLQ编码的更多细节,可以阅读这篇博客Source Maps under the hood – VLQ, Base64 and Yoda

要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

UI5 Source code map机制的细节介绍的更多相关文章

  1. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用 ...

  2. C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案

    C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案: 1.首先试最常规的方法:Cle ...

  3. How to Build MySQL from Source Code on Windows & compile MySQL on win7+vs2010

    Not counting obtaining the source code, and once you have the prerequisites satisfied, [Windows] use ...

  4. Android进程间通信(IPC)机制Binder简要介绍和学习计划【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用程序都是由一些Activity和Ser ...

  5. HashMap source code view(1)

    前言 HashMap source code view 类注释 Hash table based implementation of the Map interface. This implement ...

  6. Tree - AdaBoost with sklearn source code

    In the previous post we addressed some issue of decision tree, including instability, lack of smooth ...

  7. 程序员必备字体Source Code Pro

    最近捕获一枚,程序员专用字体,很不错. 介绍如下: Source Code Pro 是由大名鼎鼎的 Adobe 公司发布的一款开源免费的等宽编程字体,它非常适合用于显示代码,支持 Linux.Mac ...

  8. Website's Game source code

    A Darkroom by doublespeakgames <!DOCTYPE html> <html itemscope itemtype="https://schem ...

  9. android activity 启动过程分析(source code 4.4)

    说实话,android source code从2.3到4.4变化是蛮多的,尤其是media部分,虽然总的框架是没有多大变化,但是找起代码来看还是挺麻烦的.在android里面最受伤的是使用了java ...

随机推荐

  1. HDU 4507 求指定范围内与7不沾边的所有数的平方和 (数位DP)

    题意:求区间[l,r]内所有与7无关的数的平方和(取模)定义与7无关的数:                                      1.数字的数位上不能有7              ...

  2. Realm数据库的使用

    https://github.com/lipanquan/Realm/tree/master

  3. 如何使用java代码进行视频格式的转换(FLV)

    如何使用java代码进行视频格式的转换(FLV) 一,前言 在给网页添加视频播放功能后,发现上传的视频有各种格式,那么就需要将他么转换成FLV,以很好的支持在线视频播放. 公司一直在使用中,配合使用, ...

  4. oracle wm_concat函数 列转行 分组函数

    (1)select mark, wm_concat(status) from DISSENT_INFO t GROUP BY mark; 查出来的数据 mark     status 222      ...

  5. @AutoConfigureAfter不生效 @Configration bean的创建顺序

    https://gooroo.io/GoorooTHINK/Article/17466/Lessons-Learned-Writing-Spring-Boot-Auto-Configurations/ ...

  6. js随机生成[n,m)的数字(不包括m)

    Math.random();//随机生成0到1的数字 Math.floor();//取小整 Math.floor(Math.random()*(最大值 - 最小值) + 最小值) 生成2到8的数:Ma ...

  7. Invalid prop: type check failed for prop "XXX". Expected String, got Object.

    项目是Vue的,基于elementUI的后台管理系统. Invalid prop: type check failed for prop "total". Expected Str ...

  8. 转 Comparison of Red Hat and Oracle Linux kernel versions and release strings

    Originally derived from Red Hat Enterprise Linux (RHEL), Oracle Linux (OL) contains minor difference ...

  9. 谨慎使用多线程中的fork 学习!!!!

    前言 在单核时代,大家所编写的程序都是单进程/单线程程序.随着计算机硬件技术的发展,进入了多核时代后,为了降低响应时间,重复充分利用多核cpu的资源,使用多进程编程的手段逐渐被人们接受和掌握.然而因为 ...

  10. 数据结构---Java---HashSet

    1.概述 1.1 HashSet不是线程安全的: 1.2 当向HashSet存入元素时,调用该对象的hashCode()值,根据hashCode()值来决定元素的存储位置: 如果hashCode()值 ...