uniapp分包

小程序官方文档:

分包加载 | 微信开放文档​developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html

uniapp 分包文档:

uni-app官网​uniapp.dcloud.io/collocation/pages?id=subpackages

原文地址:

uniapp分包(详尽版)​copyfuture.com/blogs-details/20201128151522074lqjqh6asz92cv6c​编辑

PS:本文是笔者对基于uniapp的一小程序项目进行分包后的复盘文档,不足之处请多多指教。

一:分包相关概念

  1. 本质上是改变项目的路由以及优化项目各个模块的启动时间的一种优化技术。
  2. 主包与分包的概念

1). 主包:本项目中初始化时所必须的页面。

项目在启动时,将从主包进入,分包在用户未进入时不会加载,只有在进入分包模块时才会加载。
tabbar页面以及模块间共有的页面,如果该项目有账号限制(即非注册账号不可进入主界面),也应将登录页放置在主包内

2). 分包:除主包外的所有页面都应放置在分包内,为避免读者混淆,本文会将该分包定义为子包

二:为什么要分包

优化项目首次启动的下载时间;小程序默认就是整包(主包)下载,但这会导致整个项目只有在全部加载完毕后才会回显到用户眼前,这样虽然可以使用加载动画进行优化,但也会有部分可能导致用户流失;
防止项目超出小程序官方对小程序项目打包后的大小限制;
若不分包,整个程序最大限制不能超过2M,分包后,整个项目(包含主包+子包)最大不能超过16M,单个包不能超过2M (这样就规避了项目最大不得超过2m的限制)

三: 分包基本逻辑

  • 静态文件:分包下支持 static 等静态资源拷贝,即分包目录内放置的静态资源不会被打包到主包中,也不可在主包中使用
  • js文件:当某个 js 仅被一个分包引用时,该 js 会被打包到该分包内,否则仍打到主包(即被主包引用,或被超过 1 个分包引用)
  • 自定义组件:若某个自定义组件仅被一个分包引用时,且未放入到分包内,编译时会输出提示信息

四: 分包步骤详解

PS: 由于笔者仅做了微信小程序分包,因而以下也仅对面向微信小程序的uniapp项目有效
PS: 笔者是tabbar页作为单模块划分子包,即每个tabbar均作为一个子包模块
  1. (manifest.json ) 开启分包优化

添加相关字段
// "mp-weixin"
"optimization":{
"subPackages":true //是否启用分包优化
}
  1. (pages.json) 声明项目分包结构
  • pages:
原则:pages内只允许存放tabbar页面路由,以及各个子包所共有的页面页面,如果有登录页且不登录无法进入主页面,该登录页面路由也应放置在pages路由内
  • subPackages:
定义:单个模块内的除主包内文件的所有的文件,
比如: 假设一个tabbar模块内原本有index(tabbar页).vue,notice.vue,about.vue这三个页面,将index.vue这个页面路由放置pages.json中的pages数组内,对应的将index.vue放置在项目中的pages目录内
假设notice.vue与about.vue没有在别的tabbar模块中被使用,则应该将notice.vue和about.vue两个页面文件放置在subPackages中
若notice.vue与about.vue这两个页面中有被别的模块使用,则同样应该将其放置在pages主包内,为防止其与其他tabbar页面混淆,应该在pages目录内再单独开辟一个目录专门用于存放共有页

弄懂了以上原则,接下来便可以实践一下了

(pages.json)内新增subPackages字段,与pages同级,同样是数组格式,期内每一个对象均对应tabbar内的每一个模块,
(项目目录)每一个对象都应在项目中生成每一个目录,这个目录与pages目录同级
//pages.json
"pages":[
//这里仅存放tabbar,以及公共页
],
"subPackages":[
//subPackages数组里的每一个对象都代表了对应tabbar模块里的除tabbar中index.vue以外所有的页面,且该数组里每一个对象都在项目目录中与pages目录平级
//举个栗子 这里是首页模块,index.vue由于是tabbar页面,故而被放置在了pages.json中,剩余两个文件并没有被其他tabbar模块使用,因而被放置在了这里
{
"root":"pages_Index", //这里代表根目录的映射,表示在项目中这个模块的根目录也就是上面说的与pages目录平级的目录名
"pages":[ // 这里的pages表示分包内的页面,凡在该子包的pages目录下,均不可被其他子包模块访问
//这里指的是原本从pages页中迁移来的,仅本模块专属的页面,其格式规范遵循tabbar所在pages数组规范
{
// 网上有人说path路径必须由pages_Index根目录开始,但是在实践过程中发现不从根目录开始也可以,原因猜测是root本身已定义了根目录
// 原目录为: /pages_index/packet/notice
path":"packet/notice",
"style": {
"navigationBarTitleText": "我是子包文件"
}
},
]
}
]

目录结构如下:

pages.json如下:

这样便完成了配置的第二步

  1. 更换各个页面路由
笔者之前一直强调的分包越早越好的原因就在于此,一但项目到了微信2m限制,则会直接导致项目无法在开发者工具中运行,虽然分包可以在整个项目周期任一进度进行,但是需花费的时间是与项目进度是成正比的,即项目进度越到尾期,则分包需要花费的时间也就越长,笔者对此深有体会 (流眼泪.jpg)
如果在项目中末期才进行分包,此时需要开发者站在整个项目角度上,对每个模块,每个页面,每个网络请求都要了然于胸,可以借助于思维导图工具,将项目所有模块所有页面都列出来,剔除tabbar页面和模块间共有页面,然后将剩余页面填充至指定子包目录下,并在subPackages目录下声明该页面路径, 并且,开发者必须要重新定义路由跳转路径以及组件引入方式,这一点极为繁琐,且极易出错造成损失,因而建议开发者在走这一步前预先做好备份。
导入组件路径建议直接更换成以@开头的绝对路径来替换省略号开头的相对路径,防止以后可能再次发生的变更
跳转路由也应换成绝对路径,(路由更换后跳转失败?  请点击这里
在本过程中,可能会出现各种引用错误或者无法跳转的问题,此时需要开发者心态平缓,并一定要谨慎检查

如果在开发者工具中运行整个项目显示没有报错信息,则可以在真机调试,如果有短时弹框 “ 加载模块中 ”,则表示分包成功

那么问题来了:我不想用户看到这几个丑陋的字,该怎么做?

出现这几个字的原因是由于用户刚进入的界面必定是主包,而在用户进入分包的时候,由于分包资源还未下载,所以微信官方便贴心的提示用户正在加载分包资源
笔者:微信我谢谢你呀!(超大声哔哔)
那么接下来要说的,就是关于这类问题的解决办法: 分包预加载

  1. (pages.json)实现分包预加载
定义:在用户进入某个页面时,同时静默下载跟该页面有关的子包文件
与subPackages平级添加preloadRule对象,
该对象内部的key指的是某个页面路径,也就是当用户进入某个页面时,需要预加载的页面路径,
value
//pages.json
//以子包pages_index为例
"subPackages":[
//分包模块
{
"root" : "pages_index",
"pages" : [
{
"path" : "packet/notice",
"style" : { "navigationBarTitleText": "我是子包页面"}
}
]
}
],
"preloadRule" :{
"pages/index/index":{ //要进行预加载时用户要进入的页面路径
"network":"all", // 什么网络下支持允许预加载,默认wifi: wifi/all
"packages":["pages_Index"] // 要进行预加载的子包名
},
}
使用分包预加载功能,
如果配置成功,开发者console控制台会输出以下信息:

  1. 几点原则

  1. 主包可以引用分包内文件,分包仅可引用自身目录内的文件,分包与分包间文件无法互相引用,

  1. 要清楚的是分包是一种不得已而为之的手段,确保在分包前项目中静态资源已优化完毕,且没有大量注释或无用代码也是一种手段
     

分享一个自己的初始化配置表:

分包目录: pagesA /pagesB/pagesC/pagesD, 使用的时候把这几个名字改成符合自己项目的命名吧.

{
	"easycom": {
		"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
	},
	"pages": [
		{
			"path": "pages/index/index"
		},
		{
			"path": "pages/user/user",
			"style": {
				"navigationBarTitleText": "我的",
				"enablePullDownRefresh": false
			}
		}
	,{
			"path" : "pages/i18n/i18n",
			"style" :
			{
				"navigationBarTitleText": "",
				"enablePullDownRefresh": false
			}

		}
	,{
			"path" : "pages/test/test",
			"style" :
			{
				"navigationBarTitleText": "",
				"enablePullDownRefresh": false
			}

		}
	,{
			"path" : "pages/result/result",
			"style" :
			{
				"navigationBarTitleText": "",
				"enablePullDownRefresh": false
			}

		}
	],
	"subPackages": [{
		"root": "pagesA",
		"pages": [{
			"path": "test/test",
			"style" :
			{
				"navigationBarTitleText": "pagesA",
				"enablePullDownRefresh": false
			}
		}
		]
	}, {
		"root": "pagesB",
		"pages": [{
			"path": "test/test",
			"style" :
			{
				"navigationBarTitleText": "pagesB",
				"enablePullDownRefresh": false
			}
		}
		]
	},{
		"root": "pagesC",
		"pages": [{
			"path": "test/test",
			"style" :
			{
				"navigationBarTitleText": "pagesC",
				"enablePullDownRefresh": false
			}
		}
		]
	},{
		"root": "pagesD",
		"pages": [{
			"path": "test/test",
			"style" :
			{
				"navigationBarTitleText": "pagesD",
				"enablePullDownRefresh": false
			}
		}
		]
	}],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8",
	},
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#e97516",
		"borderStyle": "white",
		"backgroundColor": "#fff",
		"list": [{
			"pagePath": "pages/index/index",
			"iconPath": "static/tabbar/home.png",
			"selectedIconPath": "static/tabbar/home-active.png",
			"text": "首页"
		},
			{
				"pagePath": "pages/user/user",
				"iconPath": "static/tabbar/user.png",
				"selectedIconPath": "static/tabbar/user-active.png",
				"text": "个人中心"
			}
		]
	},
	"permission": {
		/* 小程序在这里设置定位没效果,必须在manifest.json中设置 */
		// "scope.userLocation": {
		//   "desc": "获取用户当前位置"
		// }
	}
}

补充说明:

所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据pages.json的配置进行划分。

在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。

App默认为整包。从uni-app 2.7.12+ 开始,也兼容了小程序的分包配置。其目的不用于下载提速,而用于首页是vue时的启动提速。App下开启分包,除在pages.json中配置分包规则外,还需要在manifest中设置在app端开启分包设置,详见:https://uniapp.dcloud.io/collocation/manifest?id=app-vue-optimization

上面文档出处:

pages.json 页面路由 | uni-app官网​uniapp.dcloud.net.cn/collocation/pages.html#subpackages​编辑

分包后,小程序项目由 1 个主包 + 多个分包组成:

  • 主包:一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
  • 分包:只包含和当前分包有关的页面和私有资源

普通分包以及主包之间引用原则

主包里的资源(js, template, wxss, components, 图片)都是全局的,可以被公用;而每个分包相当于有自己的“作用域”,自己的资源,只能用自己的或者使用主包的,但不能使用其他子包的资源

① 主包无法引用分包内的私有资源

② 分包之间不能相互引用私有资源

③ 分包可以引用主包内的公共资源

这里的出处参考:

https://www.yii666.com/blog/376774.html​www.yii666.com/blog/376774.html

微信小程序分包和主包

https://www.yii666.com/blog/376774.html​www.yii666.com/blog/376774.html

二、主包和分包

主包:即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;

分包:是根据pages.json的配置进行划分。

加载小程序的时候先加载主包,当需要访问分包的页面时候才加载分包内容

分包的页面可以访问主包的文件,数据,图片等资源

在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,会把对应分包自动下载下来,下载完成后再进行展示。此时终端界面会有等待提示。

三、配置pages.json

在pages.json中新建数组"subPackages",数组中包含两个参数:1.root:为子包的根目录,2.pages:子包由哪些页面组成,参数同pages;

注意:主包和分包是不能再同一目录下,在构建uniapp项目时,可以考虑一下目录结构,以便后期进行分包;

四、 注意事项:

整个小程序所有分包大小不超过 20M

单个分包/主包大小不能超过 2M

1、合理规划分包,开始时就细分分包,尽量少在主包放大文件

2、减少项目的层级,合理归分层级,同时可以提高项目的运行速度

3、静态资源全部cdn加载

4、公共组件库

5、公共CSS库,尽量做到一次代码多次使用,避免重复多余的CSS

6、使用稳定全面的UI库,可以大幅度减少CSS的用量

7、外部较大的js文件,尽量减少使用,非用不可的话全部放到分包里去加载使用

8、主包不可以引用分包内文件,分包仅可引用自身目录内的文件,分包与分包间文件无法互相引用

9、要清楚的是分包是一种不得已而为之的手段,确保在分包前项目中静态资源已优化完毕,且没有大量注释或无用代码也是一种手段

10、静态资源尽量放到服务器上 和公司后端人员沟通 将图片地址尽量放到服务器上 就不占用本地资源空间

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值