南锋

南奔万里空,脱死锋镝余

cocosCreator导出后的代码和源码进行对比

接很久之前的一篇文章cocosCreator全局错误监听及错误的解决方法;

应用场景

我们导出了一个cocos Creartor工程,在运行导出后的工程时遇到了报错,很多时候,我们时无法直接找到错误,只能通过错误日志来定位问题。但是错误日志看起来不是特别的方便。

解决方案

查看上面的报错日志,这里以下面日志为例:

1
2
3
4
5
6
7
8
9
10
11
{"message":"Cannot read properties of null (reading 'length')","stack":"TypeError: Cannot read properties of null (reading 'length')\n    
at e.getChildByName (https://lengmo714.top/test/cocos-js/cc.7297c.js:1:383931)\n
at n.watchTheGame (https://lengmo714.top/test/assets/main/index.fef9f.js:317:57103)\n
at s.<anonymous> (https://lengmo714.top/test/assets/main/index.fef9f.js:221:6210)\n
at s (https://lengmo714.top/test/src/chunks/bundle.846d5.js:110:641)\n
at Generator.<anonymous> (https://lengmo714.top/test/src/chunks/bundle.846d5.js:110:1982)\n
at Generator.next (https://lengmo714.top/test/src/chunks/bundle.846d5.js:110:1004)\n
at e (https://lengmo714.top/test/src/chunks/bundle.846d5.js:108:166)\n
at u (https://lengmo714.top/test/src/chunks/bundle.846d5.js:108:3450)\n
at https://lengmo714.top/test/src/chunks/bundle.846d5.js:108:3509\n
at new Promise (<anonymous>)"}

上面的日志说明在调用 getChildByName 返回了 null,然后代码里尝试读取它的 length 属性,导致空指针异常。

解决方法

解决方法有很多,比如直接全局搜索wathcTheGame方法,看具体时哪里出错了,但是如果这个方法用的地方比较多,可能也判断不出具体的问题。
再或者打包时关闭代码混淆,本地测试可以用,但是上传到正式服不建议这么做。
推荐方法,利用SourceMap
在打包的时候,勾选择SourceMap,这样打包的时候给每个.js文件生成一个和源码映射的.map文件。如果是线上环境,不建议上传相关的.map文件。后面我们在排查错误的时候,可以通过这个.map文件来找我们出问题的源代码。

使用方法:

  1. 打包时勾选SourceMap
  2. 安装source-map
    使用下面命令行进行全局安装:
    1
    npm install source-map
  3. 创建一个 JS 脚本,比如叫 lookupSourceMap.js,内容如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    const fs = require('fs');
    const sourceMap = require('source-map');

    async function lookup(mapFile, line, column) {
    const rawSourceMap = JSON.parse(fs.readFileSync(mapFile, 'utf-8'));
    const consumer = await new sourceMap.SourceMapConsumer(rawSourceMap);

    const pos = consumer.originalPositionFor({ line: line, column: column });
    console.log('原始源码位置:', pos);

    consumer.destroy();
    }

    const [,, mapFile, line, column] = process.argv;
    if (!mapFile || !line || !column) {
    console.error('用法: node lookupSourceMap.js path/to/file.js.map 行 列');
    process.exit(1);
    }

    lookup(mapFile, Number(line), Number(column));
    运行示例:
    1
    node lookupSourceMap.js ./cc.js.map 1 383931  // 后面分别是行号和列号
    输出示例:
    1
    2
    3
    4
    5
    6
    原始源码位置: {
    source: 'src/game/watchTheGame.ts',
    line: 120,
    column: 15,
    name: 'watchTheGame'
    }

源码映射文件的生成

我们在导出项目时可以勾选”Source Map”,这样导出的代码就会生成对应的源码映射文件,这样我们可以通过错误日志来定位问题。如下图:
勾选"Source Map"

集成小工具

我这里为了图方便,集成了一个小工具,方便使用,每次去执行命令行啥的,说实话我觉得很麻烦。工具截图:
运行前运行后

使用方法也很简单,在工具中填入相应的参数,点查询即可。
演示动画:
演示动画

工具下载链接

下载链接1
下载链接2

+