51ZionLin
51ZionLin
  • 发布:2024-07-12 00:12
  • 更新:2024-12-11 21:54
  • 阅读:3840

uniapp微信小程序实现跨包加载js与异步组件,支持vue2和vue3,从此和主包超限说拜拜。

分类:uni-app

前言

最近在接到一个二开项目,发现一个普通的小项目居然主包超过了1.5MB,并且甲方还在持续加码功能,一看就是一个屎山项目。为了更好的进行开发,我打算重新规划一下整个小程序,并且进行分包,而当我打算在清理一堆屎的时候我才发现,这堆屎有毒!原项目经过多个作者反复拉屎,完美的实现了主包拉屎,分包也拉屎的操作,导致整体已经很难优化了,因此我就想到是否可以使用异步组件和跨包加载js,从而剥离一部分的文件出来,实现主包体积优化。

上姿势点

在这里,我们需要先引入来自微信小程序官方的文档:分包异步化
微信小程序在2.11.2之后就已经支持分包异步化了,因此引入了俩个特性,支持 跨分包自定义组件引用跨分包 JS 代码引用,应用这俩个特性我们可以去优化主包体积。

1. 跨分包自定义组件引用

跨分包自定义组件引用,需要搭配占位组件的配置才可以实现,根据微信小程序官方文档描述如下。


而在uniapp中,对应的我们需要在pages.json中进行如下配置


配置之后,我们就可以在页面中正常使用了,对应的slots、props、events的传递在分包加载进来之后便可以正常响应。

但是这一切看似美好,实际上还是存在部分问题的,主要如下

  • (1) 在分包未加载完成之前,该组件为占位组件,如果是view,text等基础组件,则slots的内容会直接显示出来,影响用户体验
  • (2) 该方案只支持直接在页面使用分包组件,页面内的子组件引入均无效
  • (3) 该方案在遇到分包比较大的时候容易造成过长的加载时间等待

虽然存在着部分问题,但是我们依然可以将部分业务组件分离到分包中,然后使用跨包组件,从而减少主包的体积,在我这个项目中我对接的腾讯云IM就是通过这种形式,将消息列表对接到tabbar中,否则按照以往的经验这一部分肯定占据主包大量的空间。

2. 跨分包js调用

跨分包js调用,需要到require,而对于uniapp而言,直接使用require会导致报错,无法通过编译。因此我开发了一个插件,可以简单直接的实现调用分包js。
对应的插件地址:zion-uniapp-mp-load-package
对应的github demo地址: zionLZH/zion-uniapp-mp-load-package

  • 1.首先我们需要先安装依赖

    npm install zion-uniapp-mp-load-package -D  
    或  
    yarn add zion-uniapp-mp-load-package -D
  • 2.修改配置文件,因为vue2和vue3的配置文件不一样因此需要分别处理
    这是vue2的,新增/修改vue.config.js

const { zionUniMpLoadPackagePlugin } = require('zionUniMpLoadPackagePlugin/webpack')  
module.exports = {  
  configureWebpack: {  
    plugins: [  
      new zionUniMpLoadPackagePlugin()  
    ],  
    optimization: {  
      moduleIds: 'named',  
    }  
  },  
}

这是vue3的,新增/修改vite.config.js

import { defineConfig } from 'vite';  
import uni from '@dcloudio/vite-plugin-uni';  
import { zionUniMpLoadPackagePlugin } from './script/zionUniMpLoadPackagePlugin/vite'  

export default defineConfig({  
  plugins: [  
    uni(),  
    zionUniMpLoadPackagePlugin()  
  ],  
});
  • 3.直接调用跨包js
// 这里的packageA对应的就是分包目录  
loadMpPackage("packageA", () => {  
    // ...  
    console.log('加载成功')  
    // 这里就可以直接引入分包中对应位置的js,调用其方法  
    console.log(loadMpPackageModule('/packageA/sdk/index.js'))  
    console.log(loadMpPackageModule('/packageA/sdk/index.js').a())  
}, ({mod, errMsg}) => {  
    // ...  
    console.log('加载出错', mod, errMsg)  
})

在使用我的插件之后,基本上很多第三方的js,或者比较占体积的js可以直接转移到一个独立的分包中,从而极大的减少主包的占用,我通过这个方式把高德,省市区,im,音视频等插件都进行了转移,终于把主包减少到了1M左右。

对了,如果有大佬不吝啬的话,也可以帮我点个star哦:https://github.com/zionLZH/zion-uniapp-mp-load-package

2024年7月26日:已经确定有的bug,仅存在vue2版本,引入插件之后导致主包体积反而增大,这仅在vue2/webpack版本存在,原因是因为webpack打包模块的时候moduleId被插件接管之后计算出来的moduleId有问题(因为分包里面需要进行重定向,导致分包的Id有问题,目前暂时没有一个完美的结局方案)。建议开发者自行根据项目实际跑起来的情况确定是否采用本方案(可以先引入插件,空跑一下看看前后主包体积),感谢评论区大佬提出与配合调试。

6 关注 分享
mrZhan 套马杆的套子 BFC DCloud_UNI_yuhe 笔袋App bug开发工程师

要回复文章请先登录注册

8***@qq.com

8***@qq.com

回复 23423423423 :
你这个问题解决了吗?
2024-12-11 21:54
绯红彼岸

绯红彼岸

感谢大佬,使用这个方案主包减少了1.2M
2024-11-18 11:22
51ZionLin

51ZionLin (作者)

回复 3***@qq.com :
仔细看git和对应的描述,用npm,和直接git源码跑,是俩个配置
2024-10-08 16:42
3***@qq.com

3***@qq.com

vue3版本,引用插件为啥会报错,而且,插件名字不对吧
2024-09-29 15:28
51ZionLin

51ZionLin (作者)

回复 8***@qq.com :
腾讯的IM是jssdk,写一个组件去引入腾讯的IM sdk,然后页面异步载入这个组件就行了
2024-09-25 11:38
8***@qq.com

8***@qq.com

对接的腾讯云IM就是通过这种形式,将消息列表对接到tabbar中,否则按照以往的经验这一部分肯定占据主包大量的空间
你好,我想知道你是怎么做的呢?我现在也在集成 IM
2024-09-23 14:11
1***@qq.com

1***@qq.com

回复 1***@qq.com :
子组件
2024-09-14 17:02
1***@qq.com

1***@qq.com

这样也可以自组件引用分包js了吗
2024-09-14 17:01
三里清风

三里清风

回复 51ZionLin :
官方文档没找到,请问在哪里列
2024-08-28 10:08
51ZionLin

51ZionLin (作者)

回复 三里清风 :
写呗,uni官方不有提供宏么
2024-08-27 18:06