大家好,我是老纪。
书接上回《抽丝剥茧:Electron与Node.js的奇葩Bug》,没有看过的读者老爷们推荐阅读一下。
我在Electron
的GitHub
上提的issue
,现在已经关闭了。
我们再简单回顾下这个Bug
的背景与产生原因:
- Node.js自
v18.17.0
起,为fs.readdir
相关API(同步、异步回调与Promise)都新增了一个参数recursive
,但事实上,同步和异步回调的API都有Bug
,直到v18.19.0
才修复。 - Electron
v27
的多个版本内置的Node.js使用v18.17
、v18.18
,直到v29
开始使用Node.js的v20
,才没有这个Bug
。 - 由于Electron对
fs
进行了wrap
处理,v29
起虽然在大部分情况下没有问题,但是asar
模式下内置资源路径的递归没有实现,仍会引发Bug
,这也正是此次codebytere修复些问题时的标题:fix: support recursive readdir in Asar files#41582。
我们看下codebytere
的描述信息:
她其实做了两件事:
- 修复
asar
模式下使用recursive
参数的Bug - 规避
fs.promises.readdir
的性能风险。对于fs.promises.readdir
的重写,不再是原来的fs.promises.readdir = util.promisify(fs.readdir)
,而是依赖于fs.promises.readdir
的原生方法本身。原因是我上篇文章提到的,fs.readdir
使用recursive
参数的异步回调处理是同步的,可能会阻塞进程,有性能上的风险。
从她的代码提交上看,她又手写了两个同步异步的递归函数(代码是从Node.js里借鉴的):
不过我更倾向于把她的762行移到756行,这样可以在readdirRecursive
中专注处理asar
的逻辑,如果Node.js在这里再有什么Bug,可以随着版本的升级而修复,起码只会影响asar
的部分。当然,目前这种修改,对于Electron而言,也无伤大雅,真要有了问题,也就是改多改少的区别了。像这么底层的东西,如果不是这样的API变更,通常是很健壮的。
我这个issue
下还有两个开发者反馈遇到了同样的事情:
虽然这个问题关闭了,但新的版本还没有发出来。从目前的提交来看,这个修复只是针对Electron v29+
,因为它即使合并到v27
、v28
,由于对应的Node.js
版本没有升级到v18.19
,其同步和异步回调的API仍是有问题的。