这篇文章上次修改于 260 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

我在公司维护的 Felo Search 项目近期收到了大量投诉,部分页面会出现白屏现象。我负责去重点排查,有位同事用自己的手机测试后,发现在 iOS 16 系统下会稳定出现,这大概率就是 JS 执行出错导致了。我的分析过程大致如下:

首先在 Mac 上安装 iOS 16 较低版本的模拟器(我选择安装了 15.2,因为有用户反馈使用 15 系统),通过 Mac 上的 Safari 调试在 iOS 模拟器内的 Safari,并通过控制台定位错误。

SyntaxError: Invalid regular expression: invalid group specifier name

错误信息表明存在一个不受支持的正则表达式规则(我想起来之前写过一篇文章,也是正则的问题),但由于 JS 代码被压缩无法定位到具体行数,我将该文件复制出来并格式化,通过另外一个网站去加载该存在异常的 JS 文件。

初步定位到具体的出错代码属于外部依赖库,只能通过检查近期依赖项的变动进一步确认,大概率是某个依赖升级后导致。检查 Git 提交记录发现 package.json 文件并没有明显改动,只好继续检查 pnpm-lock.yaml 文件,发现存在锁文件版本被降级的情况(pnpm 9x 版本,后续有人用了低于 9x 的版本安装了依赖,就会导致依赖锁被破坏)

最终发现有一个叫 mdast-util-gfm-autolink-literal 的库被升级了,比较此前发布的版本后发现从 2.0.0 升级到了 2.0.1,通过 why 命令可查出为什么它被安装。

pnpm why mdast-util-gfm-autolink-literal

dependencies:
@tryfabric/martian 1.2.4
└─┬ remark-gfm 1.0.0
  └─┬ mdast-util-gfm 0.1.2
    └── mdast-util-gfm-autolink-literal 0.1.3
remark-gfm 4.0.0
└─┬ mdast-util-gfm 3.0.0
  └── mdast-util-gfm-autolink-literal 2.0.1

我去找了下该库关于 2.0.1 版本的一些改动和发布信息,他的确使用到了一个不受支持的正则表达式规则,还有人对此提了 Issues,结果作者明确拒绝向下兼容,坚持要用。很明显这对于一个商业化项目来说是绝对不允许的,相当于是直接就砍掉这大半用户了...

这个正则表达式的规则叫“反向断言”,我早在 2021 年就写过文章 《JS 正则使用反向断言及踩坑》,结果没想到它的兼容性居然在今天都还能差的这么离谱。

我最终的解决方案就是对比旧版本的 pnpm-lock.yaml 内容,直接修改了对应的版本号和签名,亲测可用。