UI5 Source code map机制的细节介绍
在我的博客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机制的细节介绍的更多相关文章
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用 ...
- C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案
C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案: 1.首先试最常规的方法:Cle ...
- 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 ...
- Android进程间通信(IPC)机制Binder简要介绍和学习计划【转】
本文转载自:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用程序都是由一些Activity和Ser ...
- HashMap source code view(1)
前言 HashMap source code view 类注释 Hash table based implementation of the Map interface. This implement ...
- Tree - AdaBoost with sklearn source code
In the previous post we addressed some issue of decision tree, including instability, lack of smooth ...
- 程序员必备字体Source Code Pro
最近捕获一枚,程序员专用字体,很不错. 介绍如下: Source Code Pro 是由大名鼎鼎的 Adobe 公司发布的一款开源免费的等宽编程字体,它非常适合用于显示代码,支持 Linux.Mac ...
- Website's Game source code
A Darkroom by doublespeakgames <!DOCTYPE html> <html itemscope itemtype="https://schem ...
- android activity 启动过程分析(source code 4.4)
说实话,android source code从2.3到4.4变化是蛮多的,尤其是media部分,虽然总的框架是没有多大变化,但是找起代码来看还是挺麻烦的.在android里面最受伤的是使用了java ...
随机推荐
- 求范围内【l,r] , 内二进制的零比一多的数
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> # ...
- python进制转换或数据格式转换
以下是部分进制转换的,都是python内置函数 int(x [,base ]) 将x转换为一个整数 long(x [,base ]) 将x转换为一个长整数 f ...
- Java 实践
/** *宠物就是一个标准,包含多类宠物 *定义宠物标准接口Pet *定义Cat和Dog两个Pet接口的子类 *使用链表结构动态存储宠物信息 *定义商店类(工厂类),负责宠物的上架(链表添加).下架( ...
- android studio NDK配置
向您的项目添加 C 和 C++ 代码 本文内容 下载 NDK 和构建工具 创建支持 C/C++ 的新项目 构建和运行示例应用 向现有项目添加 C/C++ 代码 创建新的原生源文件 创建 CMake 构 ...
- keil版本控制
keil5.15才有对git svn的支持,之前的有其它的svcs; http://www.keil.com/appnotes/files/apnt_279.pdf http://stdbit.c ...
- webpack安装与配置(window)
最近几天也是刚刚学习webpack工具,所以就要从安装开始我的学习的第一步.在网上搜索了找到webpack官网,在下载webpack就要先安装nodejs,在nodejs里用集成的npm下载webpa ...
- React.js 小书 Lesson4 - 前端组件化(三):抽象出公共组件类
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson4 转载请注明出处,保留原文链接和作者信息. 为了让代码更灵活,可以写更多的组件,我们把这种模 ...
- POJ 3164——Command Network——————【最小树形图、固定根】
Command Network Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 15080 Accepted: 4331 ...
- css内容整理1
1.css引入的四种方式1.行内2.内嵌3.链接 <link href="1.css" rel="stylesheet">4.导入@import u ...
- java.lang.ArrayIndexOutOfBoundsException: 160
项目突然出现这个问题java.lang.ArrayIndexOutOfBoundsException: 160,找了好大半天没有找出来哪里的问题,最后发现时fastjson.jar 版本太低了造成的, ...