-
背景
需求中需要广泛使用到echarts进行绘图,但是小程序本身对于分包使用是有大小限制的。
参考了echarts在小程序中的实践发现
echarts.js及时在最精简的情况下仍然有1m,那留给分包的的空间就太小了。
实践也推荐使用异步分包,那就需要探索小程序的异步分包能力究竟改怎么使用了。先看文档
-
官网 分包异步化指南
官网地址:developers.weixin.qq.com/miniprogram…
支持版本: 需要基础库版本 2.11.2 或以上
组件的跨分包引用
list来自subPackageB
在分包内容未拉取成功的情况下可以使用
button
和 list
两个自定义组件是跨分包引用组件,其中 button
在渲染时会使用内置组件 view
作为替代,list
会使用当前分包内的自定义组件 simple-list
作为替代进行渲染;在这两个分包下载完成后,占位组件就会被替换为对应的跨分包组件。
加载成功的回调
在基础库 2.24.3
之后,可以使用 wx.onLazyLoadError
监听加载事件。
js的跨分包引用
通过 require 的异步加载对应地址即可加载成功
异步加载非常熟悉,只要使用require或者require就能异步的加载amd,cmd文件,但事情往往没有这么简单
2.异步加载函数分析
import().then
不可用, 小程序异步加载只能使用commonjs require规范
require.ensure
webpack require语法并不支持
require.ensure是一个在Webpack中用于代码分割的方法。它允许将模块按需加载,而不是一次性加载所有模块。这样可以提高应用程序的性能,因为只有在需要时才会加载所需的模块。
require.async require 回调方法
使用require方法
require([‘../../../packageEcharts/ec-canvas/echarts’], function (chart) {}
会产生对应报错
进入报错源码看看
可以看出webpack使用require的时候会在webpack缓存中判断需要加载key是不是存在
如果不存在就创建script去加载对应的url。但是小程序中是没有原生创建标签能力的。此处第一版的做法是不停的重试,直到使用小程序通过预加载能力把echarts.js加载到本地,webpack在读取到文件后会清空对应key后就不会进入引入标签流程,而直接使用对应的require文件
你就说能不能用吧?
能用,但是非常不优雅,不停的重试会引入不可知问题。这种方式完全没有使用到小程序提供的require本身的能力
3.异步分包的最佳实践
1.webpack的require
Webpack在打包过程中会对模块的加载进行处理,将require语句替换为__webpack_require__函数调用。使用自己的模块加载系统来管理模块的依赖关系和加载顺序。
__webpack_require__函数是Webpack提供的模块加载函数,它会根据模块的ID进行模块的加载和执行。在Webpack打包过程中,会将每个模块分配一个唯一的ID,并且将模块的代码包装在一个函数中,该函数接受__webpack_require__函数作为参数。Webpack会将其替换为__webpack_require__函数的调用,并传递模块的ID作为参数。通过这种方式,Webpack可以在运行时根据模块的依赖关系和加载顺序来动态加载和执行模块。
所以当使用require方法时,Webpack会将其转换为__webpack_require__.e函数的调用,以实现按需加载模块的功能。webpack_require.e函数会根据传入的模块ID异步加载对应的模块,并返回一个Promise对象,可以通过该Promise对象来处理模块加载完成后的逻辑。
2.不使用webpack require
可以明显发现在webpack环境下,require被改造了,我们需要通知webpack不改造对应的require,才能符合微信官方的能力所以使用,经过阅读webpack文档,需要给require加上标志前缀就能避免webpack对require进行改造
__non_webpack_require__(ECHARTS_SRC, (chart) => {
通过打包后的源码分析可以发现已经从webpack_require.e
变更为
符合预期,但查看加载结果发现,echarts实例并未加载到
2.未能加载的对应文件
未获取文件往往是因为文件地址不对或者文件没有正确导出echarts导致的
查看打包后的文件地址
可以看出echarts文件因为splitchunk的存在被打包进了分包的主文件内了。因为我们使用的是原生的require,使用的是相对路径’
../../../packageEcharts/ec-canvas/echarts’
然而,echarts.js本身却被打包进了index.js。
确实是没有对应文件。所以无法加载到对应文件。
因此需要让webpack忽略掉队echarts.js文件的操作,使其是一个完整干净的js.所以必须把文件内容从webpack的构建过程中拿掉
3.忽略对文件的操作
loader忽略对js文件的编译
从编译生命周期中去除文件,此处使用ignorePlugin,忽略对应文件夹
别忘记,原文件是还是需要打包进代码的,使用CopyWebpackPlugin将开发目录打包进构建目录
4.分析对应文件
查看构建后packageEcharts目录
可以看到和开发目录完全一致
验证require效果
为什么还是none呢
进入details源码
可以看出因为splictChunk的规则存在
details文件被打包进了components.js内。
这样文件目录路径就不对了,因为没有使用webpack能力,没有处理引用路径问题。此处需要写死引用路径
查看对应效果,可以看出
echarts内容最后被正确加载了
完结,撒花