一、问题描述
前段时间有个前端小伙伴反馈在打包发布正式环境后
调用VantUI的<van-popup>
组件显示时,显示空白,并且在控制台看到一个Maximum call stacksize exceeded(超出最大调用堆栈大小),而本地开发环境正常
:
vconsole.min.js:10 Uncaught (in promise) RangeError: Maximum call stack size exceededat Array.slice (<anonymous>)at l.printLog (vconsole.min.js:10:53111)at n.map.window.console.<computed> (vconsole.min.js:10:52378)at l.printOriginLog (vconsole.min.js:10:53006)at l.printLog (vconsole.min.js:10:54051)at n.map.window.console.<computed> [as warn] (vconsole.min.js:10:52378)at warn$1 (vue.global.js:1598:15)at PublicInstanceProxyHandlers.ownKeys (vue.global.js:4689:7)at E (vconsole.min.js:10:36950)at Module._ (vconsole.min.js:10:36007)
二、问题排查
最初通过代码逐段注释排查发现,<van-popup>
中的<van-uploader :multiple="multiple">
里的multiple
没有定义,在定义了multiple
变量后就正常了。但这个为何会引起Maximum call stacksize exceeded
?于是搭建了一个很简单的vite+vant的工程进行问题还原,结果发现即使<van-uploader :multiple="multiple">
里的multiple
没有定义,也不会引发Maximum call stacksize exceeded
。
于是,展开错误栈信息,看到了比较有“规律”的调用:
看上去,前端小伙伴用了前端调试经常使用的一个vconsole
插件。从上面规律的栈输入来看,应该是vconsole在特定情况下引发的控制台输出异常,而这个特定情况恰好与<van-uploader :multiple="multiple">
里的multiple
没有定义有关。
由于问题只发生在打包后的生产环境,为了能在本地调试,需要搭建一个简易的生产环境来尽可能的还原问题:
(1)安装vscode的Live Server
插件
(2)执行项目打包命令,构建产物位于dist
目录
(3)用vscode打开dist
目录
(4)点击vscode右下方的Go Live
功能启动live Server
,其启动的默认端口号为5500
(5)访问http://localhost:5500/
运行调试之后也看到了跟之前一样的规律调用:
看样子循环调用路径是:
Vue的warn$1
--> vconsole的E
--> Vue的PublicInstanceProxyHandlers.ownKeys
--> Vue的warn$1
那么根据调用栈往回查找根源:
可以看到最终的根源是因为multiple
没有定义,Vue想在控制台打印Property multiple was accessed during render but is not defined on instance.
信息而因为vconsole陷入了循环调用,最终这条信息根本没有来得及输出就引发了Maximum call stacksize exceeded(超出最大调用堆栈大小)错误而结束。
如果移除vconsole,就能够看到控制台输出的警告信息:
所以如果使用vconsole遇到Maximum call stack size exceeded异常问题,记得考虑有可能是因为Vue的控制台输出(警告信息)导致与vconsole产生循环调用引起。