最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 绝了,没想到一个 source map 居然涉及到那么多知识盲区

    正文概述 掘金(yck)   2021-05-17   434

    Source map 想必大家都不陌生。线上的代码多是压缩后的,如果线上有报错却只能调试那个代码多半是个噩梦。因此我们需要有一个桥梁帮助我们搭建起源代码及压缩后代码的联系,source map 就是起了这个作用。

    以下是 MDN 对于 source map 的解释:

    但是不知道各位读者有没有对 source map 的原理产生过疑问?笔者列出了四个疑问,不知道各位是不是也存在过这样的问题:

    绝了,没想到一个 source map 居然涉及到那么多知识盲区

    接下来的内容会逐步为读者解答这四问。

    source map 文件是否影响网页性能

    这个答案肯定是不会影响,否则构建相关的优化就肯定会涉及到对于 source map 的处理了,毕竟 source map 文件也不小。

    其实 source map 只有在打开 dev tools 的情况下才会开始下载,相信大部分用户都不会去打开这个面板,所以这也就不是问题了。

    这时可能会有读者想说:哎,但是我好像从来没有在 Network 里看到 source map 文件的加载呀?其实这只是浏览器隐藏了而已,如果大家使用抓包工具的话就能发现在打开 dev tools 的时候开始下载 source map 了。

    source map 存在标准嘛?

    source map 是存在一个标准的,为 Google 及 Mozilla 的工程师制定,文档地址。正是因为存在这份标准,各个打包器及浏览器才能生成及使用 source map,否则就乱套了。

    各个打包器基本都基于该库来生成 source map,当然也存在一些魔改的方案,但是标准都是统一的。

    通过上面的库生成出来的 source map 格式大致如下,大家也可以对比各个打包器的产物,格式及内容大部分都是一致的:

    {
      version: 3,
      file: "min.js",
      names: ["bar", "baz", "n"],
      sources: ["one.js", "two.js"],
      sourceRoot: "http://example.com/www/js/",
      mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA"
    }
    

    接下来笔者介绍下重要字段的作用:

    • version:顾名思义,指代了版本号,目前 source map 标准的版本为 3,也就是说这份 source map 使用的是第三版标准产出的
    • file:编译后的文件名
    • names:一个优化用的字段,后续会在 mappings 中用到
    • sources:多个源文件名
    • mappings:这是最重要的内容,表示了源代码及编译后代码的关系,但是先略过这块,下文中会详细解释

    另外大部分应用都是由 webpack 来打包的,可能有些读者会发现 webpack 的 source map 产出的字段于上面的略微有些不一致。

    这是因为 webpack 魔改了一些东西,但是底下还是基于这个库实现的,只是变动了一些不涉及核心的字段,具体代码。

    浏览器怎么知道源文件和 source map 的关系?

    这里我们以 webpack 做个实验,通过 webpack5 对于以下代码进行打包:

    // index.js
    const a = 1
    console.log(a);
    

    当我们开启 source map 选项以后,产物应该为两个文件,分别为 bundle.js 以及 bundle.js.map

    查看 bundle.js 文件以后我们会发现代码中存在这一一段注释:

    console.log(1);
    //# sourceMappingURL=bundle.js.map
    

    sourceMappingURL 就是标记了该文件的 source map 地址。

    当然除此之外还有别的方式,通过查阅 MDN 文档 发现还可以通过 response header 的 SourceMap: <url> 字段来表明。

    source map 是如何对应到源代码的?

    这是 source map 最核心的功能,也是最涉及知识盲区的一块内容。

    大家应该还记得上文中没介绍的 mapping 字段吧,接下来我们就来详细了解这个字段的用处。

    我们还是以刚才打包的文件为例,来看看产出的 source map 长啥样(去掉了无关紧要的):

    {
      sources:["webpack://webpack-source-demo/./src/index.js"],
      names: ['console', 'log'],
      mappings: 'AACAA,QAAQC,IADE',
    }
    

    首先 mappings 的内容其实是 Base64 VLQ 的编码表示。

    内容由三部分组成,分别为:

    • 英文,表示源码及压缩代码的位置关联
    • 逗号,分隔一行代码中的内容。比如说 console.log(a) 就由 consoleloga 三部分组成,所以存在两个逗号。
    • 分号,代表换行

    逗号和分号想必大家没啥疑问,但是对于这几个英文内容应该会很困惑。

    其实这就是一种压缩数字内容的编码方式,毕竟源代码可能很庞大,用数字表示行数及列数的话 source map 文件将也会很庞大,因此选用 Base 64 来代表数字用以减少文件体积。

    比如说 A 代表了数字 0,C 代表了数字 1 等等,有兴趣的读者可以通过该网站了解映射关系。

    了解了这层编码的映射关系,我们再来聊聊这一串串英文到底代表了什么。

    其实这每串英文中的字母都代表了一个位置:

    1. 压缩代码的第几列
    2. 哪个源代码文件,毕竟可以多个文件打包成一个,对应 sources 字段
    3. 源代码第几行
    4. 源代码第几列
    5. names 字段里的索引

    这时读者可能有个疑惑,为啥没有压缩代码的第几行表示?这是因为压缩后的代码就一行,所以只需要表示第几列就行了。

    了解完以上知识以后,我们就来根据上文的内容解析下 AACAA 的具体含义吧,通过该网站我们可以知道 AACAA 对应了 [0,0,1,0,0],这里需要注意的是数字都从 0 开始,笔者表述的时候会自动加一,毕竟代码第零行听起来怪怪的。

    1. 压缩代码的第一列
    2. 第一个源代码文件,也就是 index.js 文件了
    3. 源代码第二行了
    4. 源代码的第一列
    5. names 数组中的第一个索引,也就是 console

    通过以上的解析,我们就能知道 console 在源代码及压缩文件中的具体位置了。

    但是为什么 source map 会知道编译后的代码具体在什么位置呢?这里就要用到 AST 了。让我们打开网站输入 console.log(a) 后观察右边的内容,你应该会发现如图所示的数据:

    绝了,没想到一个 source map 居然涉及到那么多知识盲区

    因为 source map 是由 AST 产出的,所以我们能用上 AST 中的这个数据。

    source map 的应用

    一般来说 source map 的应用都是在监控系统中,开发者构建完应用后,通过插件将源代码及 source map 上传至平台中。一旦客户端上报错误后,我们就可以通过该库来还原源代码的报错位置(具体 API 看文档即可),方便开发者快速定位线上问题。

    最后

    source map 是我们日常中经常用到的东西,但是直到学习这块内容的时候才知道居然涉及到了那么多的知识盲区。

    大家如果有什么疑问欢迎在评论区交流。

    绝了,没想到一个 source map 居然涉及到那么多知识盲区


    起源地下载网 » 绝了,没想到一个 source map 居然涉及到那么多知识盲区

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元