评论

微信开发者工具下载的 sourcemaps 怎么用。

微信开发者工具下载的 source map 文件怎么用

什么是 Sourcemaps

uglifyjs、bable 等工具会对 源代码 进行编译处理生成编译后的代码(下称目标代码),而 sourcemaps 就是保留了目标代码在源代码中的 位置信息

--------- 大神分割线 ---------

如何解读 Sourcemaps

Sourcemaps 是一个 json

{
  "version": 3,  
  "sources": ["a.js", "b.js"], // 源文件列表,这个表示是由 a.js 和 b.js 合并生成
  "names": ["myFn", "test"], // 如果开启了变量名混淆,这里会保留变量名在源文件中名字信息
  "sourcesContent: [], // 可选项,保存源码信息,顺序与 sources 字段对应,chrome 的 sources 面板中源码使用了这个字段的内容进行展示
  "sourceRoot": "", // 源文件所在的目录信息
  "file": "dist.js", // 可选,编译后的文件名
  "mappings": "" // 这个是重点,是目标代码和源文件的位置的映射关系
}

mappings

目标文件"行"的信息

mappings 是使用 ; 分隔的,每个部分对应目标代码的行

如: “;AAAA;AAAA,BBBB;;”

本例子目标文件有 4 行
第 0 行和第 3 行没有源文件对应信息,所以这两行是编译过程中加入的代码

目标文件的"列"信息

如: “AAAA,CAEA,CAEA;”

‘,’ 表示行内的位置信息分隔符
本例表示目标文件的这一行有三个有效的位置信息。

位置信息的第一位表示目标文件的列的 偏移 信息
本例中,表示列的信息是 ‘A’、‘C’、‘C’,对应的数字为 0、+1、+1,(vlq 编码在线编解码工具
注意,这个是偏移信息;
列数从 0 开始,依次累加偏移值可以算出当前的位置信息对应的真正的列
所以本例中表示的是目标文件的第 n 行中的第 0 列,第 1 列,第 2 列(没错是第 2 列)

源文件的信息

如:‘AAAA;ACAA;ADAA;’

位置信息的第二位表示源文件的信息,本例子中是 ‘A’、‘C’、‘D’,对应数字是 0、+1、-1
如果 sourcemaps 中的 sources 字段只有一个文件的话,那么位置信息中第二位一直是 A(不需要偏移)
假设 sourcemaps 中 sources: [‘a.js’, ‘b.js’] 本例的意思是

AAAA: 目标文件第 0 行第 0 列 对应 第 0 个文件 a.js
ACAA; 目标文件第 1 行第 0 列 对应 第 1 个文件 b.js
ADAA; 目标文件第 2 行第 0 列 对了 第 0 个文件 a.js (偏移是 -1 又回到了 a.js)

源文件的行信息

位置信息的第三位表示源文件中的行的信息, 理解了位置偏移的概念,我们很容易理解

如:‘AACA,CACA;AACA;‘
那么
AACA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 1 行
CACA: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 1+1 行
AACA:目标文件的第 1 行第 0 列 对应 第 0 个文件的第 1 行 (注意:’;’ 后的行列偏移信息归 0)

源文件中的列信息

位置信息的第四位表示源文件中的列的信息

如:'AAAA,CAAC;'
那么
AAAA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 0 行第 0 列
CAAC: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 0 行第 0+1 列

位置信息的第五位

第五位表示变量的偏移,对应 sourcemaps 中的 names 字段,表示目标文件中的变量名对应域源文件中的变量
如:’AAAA,CAACC;AAAAD;'
sourcemaps 中 names 字段是 [‘a’, ‘b’]
那么
AAAA: 目标文件的第 0 行第 0 列 对应 第 0 个文件的第 0 行第 0 列,没有变量的信息
CAACC: 目标文件的第 0 行第 0+1 列 对应 第 0 个文件的第 0 行第 0+1 列,有变量信息,变量在源文件中是 ‘b’ (0+1=1)
AAAAD: 目标文件的第 1 行第 0 列 对应 第 0 个文件的第 0 行第 0 列,有变量信息,变量在源文件中是 ‘a’ (1-1=0)

--------- 大神分割线 ---------

怎么使用 Sourcemaps

Q: 线上小程序报错,我怎么通过 sourcemaps 还原到源代码中?
A: 如报错 appservice.js 1:15000, 表示目标文件第一行 第 15000 列位置报错。根据上文介绍的,通过 mappings 字段算。

Q: 不会。
A: 如果你会写代码的话,参考下边

import fs = require('fs')
import {SourceMapConsumer} from 'source-map'


async function originalPositionFor(line, column) {
  const sourceMapFilePath = '如果你不真的替换的成 sourcemaps 在硬盘中的位置,那你还是放弃自己写代码吧。 '
  const sourceMapConsumer = await new SourceMapConsumer(JSON.parse(fs.readFileSync(sourceMapFilePath, 'utf8')))

  return  sourceMapConsumer.originalPositionFor({
      line,
      column,
   })
}

originalPositionFor(出错的行,出错的列)

Q: 不会写代码
A: 下载最新版的开发者工具,菜单-设置-拓展设置-调试器插件

Q: 为啥都是 null?
A: 每个小程序版本都应该对应一个sourcemap文件。 运营中心那里下载的 sourcemap 是对应线上最新的小程序版本。但运营中心的报错集合了多个小程序版本。拿旧小程序版本的报错信息,和最新版本的 sourcemap,是匹配不出的。开发者工具和ci 上传的时候,会提示下载对应版本的 sourcemap 信息,可以自助保存。

Q: 怎么确定有没有版本对应上
A: 下载的 sourcemap 中有个 wx 字段,标明了该 sourcemap 文件对应小程序版本号。

最后一次编辑于  05-19  
点赞 16
收藏
评论

46 个评论

  • Stephen
    Stephen
    2020-07-01

    大佬,可以提供一个用 sourcemaps 还原线上小程序代码的教程吗,我有个朋友想学学

    2020-07-01
    赞同 1
    回复 7
    • 工号 019743
      工号 019743
      2020-07-01
      如果 sourcemaps 文件中有 sourcesContent 的话,这个就是源码。
      没有的话,那就复杂了。
      2020-07-01
      1
      回复
    • Stephen
      Stephen
      2020-07-01回复工号 019743
      已经有了压缩代码,有sourcemaps也不能还原回原始代码吗?
      2020-07-01
      回复
    • 鲤子
      鲤子
      2020-07-01
      无中生友
      2020-07-01
      回复
    • Lee
      Lee
      2020-09-01回复Stephen
      ???
      2020-09-01
      回复
    • 张宁
      张宁
      2020-11-24
      你源码不应该在你本地吗,还原源码做什么。你的 sourceMap 哪来的
      2020-11-24
      回复
    查看更多(2)
  • 呆猫
    呆猫
    10-26

    官方真垃圾,造出个调试的东西结果根本不是让人用的,出了这么多问题也没真正给解决下,真的垃圾

    10-26
    赞同
    回复
  • 立先
    立先
    10-18

    没用,不靠谱

    10-18
    赞同
    回复
  • Maybe
    Maybe
    10-14

    点击匹配后一点反应都没有... 有没有官方人员来解决下这个问题?

    10-14
    赞同
    回复 1
    • Maybe
      Maybe
      10-14
      用小程序的sourcemap插件毫无反应,但用这个开源项目时有报错:
      Error: Error parsing mappings (code 1): the mappings contained a negative line, column, source index, or name index
      不知道哪里出现了问题...
      10-14
      回复
  • windliang
    windliang
    09-22

    确认了版本是对的,写的 node 代码,返回的是 null,还有什么办法吗?Full 和 App 里的 app-service.map.map 都试过了

    const fs = require("fs");
    const { SourceMapConsumer } = require("source-map");
    
    
    async function originalPositionFor(line, column) {
      const sourceMapFilePath = "./sourcemap/__APP__/app-service.map.map";
      const sourceMapConsumer = await new SourceMapConsumer(
        JSON.parse(fs.readFileSync(sourceMapFilePath, "utf8"))
      );
    
    
      return sourceMapConsumer.originalPositionFor({
        line,
        column,
      });
    }
    
    
    originalPositionFor(16879, 11266).then((res) => {
      console.log(res);
    });
    

    ➜  sourcemap node index.js

    { source: null, line: null, column: null, name: null }

    09-22
    赞同
    回复 1
  • .
    .
    08-04

    大佬,我开启了sourcemap之后,在后台有些可以反解析出来,有些不能。 我从小程序后台下载了soucemap(确保版本号一致的),通过小程序soucemap插件解析,有些分包的报错就可以通过插件解析出来,大部分usr/app-service.js 下的搜索__APP__里的app-service.map.map 都解析不出来,这是为什么?

    08-04
    赞同
    回复 2
    • 工号 019743
      工号 019743
      08-10
      试下 FULL 下的 .map 文件
      08-10
      回复
    • .
      .
      08-11回复工号 019743
      已经试过了,报的和上面的截图一样,为匹配到结果
      08-11
      回复
  • 帅仔Ramey
    帅仔Ramey
    07-28

    把map文件的所有换行符\n替换成实际换行,然后看着行数列数就知道了。

    07-28
    赞同
    回复
  • Lewis
    Lewis
    07-21

    当发布新版时,报错的版本号有问题,匹配不上当前版本 sourcemap

    07-21
    赞同
    回复
  • 🐹 🍎[OK]
    🐹 🍎[OK]
    07-19

    为啥我下载下来,全是;;;;;;没得ABCD啥的

    07-19
    赞同
    回复 2
  • 逍遥行
    逍遥行
    07-17

    文档不是解惑的,是用来制造迷惑的

    07-17
    赞同
    回复

正在加载...

登录 后发表内容