1. 问题
qq小程序(基于uni-app)使用JS分发和组件分发插件后,有些页面会白屏,打开调试器,会看到下面的报错:
意思是找不到这个页面,然后列举了一系列的有效的组件。
这个问题只在qq小程序的真机上出现,在qq小程序开发者工具、微信小程序都没有。
2. 原因
找了一圈原因,最后发现是执行顺序不同导致的原因。qq小程序真机上,并不是先运行Page
页面,而是先执行每个组件,或者说校验每个合理的组件,而其他环境,都是先执行Page
下的js
。
Page
下的js
会加载此分包下的vendor.js
,也就是每个页面下的js
第一句都是下面的代码:
js
require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push()
这会加载分包中的module
,注册一些moduleId
。而qq
小程序真机环境先执行了组件,此时如果某些moduleId
还没注册的话,就会报错。
3. 实验
我们检验一下这个结论,在组件和页面对应的JS中分别打印一句话,看看执行顺序。
在qq小程序真机下:
在qq小程序开发者工具下:
上面的create page
对应页面,press switch
对应组件,可以看到qq
小程序真机与开发者工具,对组件和页面的加载顺序确实不同。
4. 解决
如何解决这个问题呢?既然组件需要这个moduleId
,那就提前加载好就可以了。这里写了个插件,自动引入分包所在的vendor
。
会不会有副作用呢?不会的,这里要了解下webpack
运行时原理。vendor.js
只是往global["webpackJsonp"]
中push
了一些module
,push
方法被hook
了,本质是会缓存一些moduleId
。
另外,那些并非插件移动的组件为什么没问题呢,因为它们和Page
下的js
一样,第一句都引用了分包中的vendor.js
。
5. 后记
虽然是个小问题,定位却花了不少时间,因为微信小程序没问题,所以没往执行顺序不同那方面想,期间猜想问题原因可能是moduleId
找错了之类的。