uniapp分包实现

关于分包优化的说明

在对应平台的配置下添加"optimization":{"subPackages":true}开启分包优化

目前只支持mp-weixinmp-qqmp-baidump-toutiaomp-kuaishou的分包优化

分包优化具体逻辑:

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

分包内静态文件示例(官方示例)

复制代码
"subPackages": [{
	"root": "pages/sub",
	"pages": [{
		"path": "index/index"
	}]
}]

以上面的分包为例,放在每个分包root对应目录下的静态文件会被打包到此分包内。

微信小程序官方文档介绍

mp-weixin

属性 类型 说明
appid String 微信小程序的AppID,登录 https://mp.weixin.qq.com

|-------------------------|---------|---------------------------------------------------------------------------------------------------------------------------|
| 申请 |
| projectname | String | 项目名称 |
| setting | Object | 微信小程序项目设置,参考setting |
| functionalPages | Boolean | 微信小程序是否启用插件功能页,默认关闭 |
| requiredBackgroundModes | Array | 微信小程序需要在后台使用的能力,详见 |

|---------|--------|------------------------------------------------------------------------------------------------|
| plugins | Object | 使用到的插件,详见 |

|--------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------|
| resizable | Boolean | 在iPad上小程序是否支持屏幕旋转,默认关闭 |
| navigateToMiniProgramAppIdList | Array | 需要跳转的小程序列表,详见 |

|------------|--------|--------------------------------------------------------------------------------------------------------------|
| permission | Object | 微信小程序接口权限相关设置,比如申请位置权限必须填此处详见 |

|---------|--------|----------------------------------------------------------------------------------------------------|
| workers | String | Worker 代码放置的目录。 详见 |

|----------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| optimization | Object | 对微信小程序的优化配置 |
| cloudfunctionRoot | String | 配置云开发目录,参考setting |
| uniStatistics | Object | 微信小程序是否开启 uni 统计,配置方法同全局配置 |
| scopedSlotsCompiler | String | Vue2 作用域插槽编译模式,uni-app 3.1.19+ 开始支持,可选:legacy、auto、augmented,默认:auto |
| mergeVirtualHostAttributes | Boolean | 合并由 Vue 组件编译而成的小程序组件虚拟节点外层属性,目前仅支持 id(v4.42+)、style(v3.5.1+)、class(v3.5.1+)以及 v-show 指令生成的 hidden(v4.41+) 属性 |
| slotMultipleInstance | Boolean | 模拟单个作用域插槽渲染为多个实例,此配置仅限 Vue2 环境 3.7.12+,Vue3 环境已默认支持 |
| embeddedAppIdList | Array | 要半屏跳转的小程序appid。详见 |

|----------------------|-------|----------------------------------------------------------------------------------------------------------------------------|
| requiredPrivateInfos | Array | 地理位置相关接口。详见 |

|-----------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| lazyCodeLoading | String | 目前仅支持值 requiredComponents,代表开启小程序按需注入 |

特性,详见

|------------|-------|----------------------|
| nativeTags | Array | 微信小程序平台的原生组件 (4.81+) |

setting

编译到微信小程序平台下的项目设置。

属性 类型 说明
urlCheck Boolean 是否检查安全域名和 TLS 版本
es6 Boolean ES6 转 ES5
postcss Boolean 上传代码时样式是否自动补全
minified Boolean 上传代码时是否自动压缩
bigPackageSizeSupport Boolean 预览及真机调试时包体积上限是否调整为4M,默认为true(HBuilderX 3.5.5+)。

注意: 使用微信小程序手势组件会强制开启 ES6 转 ES5

optimization

对微信小程序的优化配置

属性 类型 说明
subPackages Boolean 是否开启分包优化

cloudfunctionRoot

如果需要使用微信小程序的云开发,需要在 mp-weixin 配置云开发目录
复制代码
"mp-weixin":{
  // ...
   "cloudfunctionRoot": "cloudfunctions/", // 配置云开发目录
  // ...
}
配置目录之后,需要在项目根目录新建 vue.config.js 配置对应的文件编译规则
复制代码
{
 plugins: [
     new CopyWebpackPlugin([
       {
         from: path.join(__dirname, '../cloudfunctions'),
         to: path.join(__dirname, 'unpackage', 'dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env.UNI_PLATFORM, 'cloudfunctions'),
       },
     ]),
   ],
}

以下是自己项目所实现的三种分包方式介绍

第一种分包发方式:

分包步骤

第一步 打开 manifest.json文件,找到 "mp-weixin",添加 "optimization": {"subPackages":true} 该代码表示程序分包,完整代码如下
复制代码
​

{
	"name": "lcdsfront",
	"appid": "__UNI__EDF7C47",
	"description": "",
	"versionName": "1.0.0",
	"versionCode": "100",
	"transformPx": false,
	/* 5+App特有相关 */
	"app-plus": {
		"usingComponents": true,
		"nvueStyleCompiler": "uni-app",
		"compilerVersion": 3,
		"splashscreen": {
			"alwaysShowBeforeRender": true,
			"waiting": true,
			"autoclose": true,
			"delay": 0
		},
		/* 模块配置 */
		"modules": {},
		/* 应用发布信息 */
		"distribute": {
			/* android打包配置 */
			"android": {
				"permissions": [
					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
					"<uses-feature android:name=\"android.hardware.camera\"/>",
					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
				]
			},
			/* ios打包配置 */
			"ios": {},
			/* SDK配置 */
			"sdkConfigs": {}
		}
	},
	/* 快应用特有相关 */
	"quickapp": {},
	/* 小程序特有相关 */
	"mp-weixin": {
		"appid": "",
		"setting": {
			"urlCheck": false
		},
		"usingComponents": true,
		"optimization": {
			"subPackages": true
		}
	},
	"mp-alipay": {
		"usingComponents": true
	},
	"mp-baidu": {
		"usingComponents": true
	},
	"mp-toutiao": {
		"usingComponents": true
	},
	"uniStatistics": {
		"enable": false
	},
	"vueVersion": "2"

	// "h5": {
	// 	"devServer": {
	// 		"port": 8083, // 端口号
	// 		"disableHostCheck": true, // 关闭主机检查
	// 		"proxy": {
	// 			"/api": { // 代理路径前缀
	// 				// "target": "https://www.longchi.xyz",
	// 				"target": "http://uat.banlu.xuexiluxian.cn/",
	// 				// "target": "http://localhost: 8866/", // 目标接口域名
	// 				"changeOrigin": true, // 是否跨域	允许跨域  
	// 				"secure": false // 设置支付https协议代理
	// 			}
	// 		}
	// 	}
	// }
}

[点击并拖拽以移动]
​
第二步,开启分包
在pages.json文件中配置分包,具体代码如下
我们将登录的内容分包出去
复制代码
{
	// 如果您是通过uni_modules形式引入uView,可以忽略此配置
	"easycom": { // u-$1 表示components下所有u-*都可以,u-$.vue 表示u-*.vue所有文件都可以,即表示全局引入ui组件所有内容
		"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
	},
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/tabs/index",
			"style": {
				"navigationBarTitleText": "推荐",
				"navigationStyle": "custom"
			}
		},
		{
			"path": "pages/tabs/list",
			"style": {
				"navigationBarTitleText": "分类"
			}
		},
		{
			"path": "pages/tabs/me",
			"style": {
				"navigationBarTitleText": "我的",
				"navigationStyle": "custom"
			}
		}
		// {
		// 	"path": "pages/login/login",
		// 	"style": {
		// 		"navigationBarTitleText": "微信一键登录"
		// 	}
		// },
		// {
		// 	"path": "pages/login/bindPhone",
		// 	"style": {
		// 		"navigationBarTitleText": "绑定手机号"
		// 	}
		// }
	],
	"subPackages": [{
		"root": "pages/login", // 根路径
		"pages": [{
			"path": "login"
		}, {
			"path": "bindPhone"
		}]
	}],
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#3cc51f",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"list": [{
			"pagePath": "pages/tabs/index",
			"iconPath": "/static/icon/recommend.png",
			"selectedIconPath": "/static/icon/recommend-hl.png",
			"text": "推荐"
		}, {
			"pagePath": "pages/tabs/list",
			"iconPath": "/static/icon/classify.png",
			"selectedIconPath": "/static/icon/classify-hl.png",
			"text": "分类"
		}, {
			"pagePath": "pages/tabs/me",
			"iconPath": "/static/icon/mine.png",
			"selectedIconPath": "/static/icon/mine-hl.png",
			"text": "我的"
		}]
	},

	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {}
}
分包以后将主包内原分包的内容删除 内容如下
复制代码
// {
// 	"path": "pages/login/login",
// 	"style": {
// 		"navigationBarTitleText": "微信一键登录"
// 	}
// },
// {
// 	"path": "pages/login/bindPhone",
// 	"style": {
// 		"navigationBarTitleText": "绑定手机号"
// 	}
// }

第二种分包发方式:

直接在根目率创建分别 比如:如下图所示三个分包,pagesA,pagesB,pagesC

一个主包pages

分别内容配置如下

复制代码
"subPackages": [{
	"root": "pagesA",
	"pages": [{
		"path": "login/login",
		"style": {
			"navigationBarTitleText":"登录"
		}
	},{
		"path": "login/bindPhone",
		"style": {
			"navigationBarTitleText":"绑定手机号"
		}
	}],
	"root": "pagesB",
	"pages": [{...}],
	"root": "pagesC",
	"pages": [{...}]
}]

路径
root/pagesA/**/*.vue
root/pagesB/**/*.vue
root/pagesC/**/*.vue

第三种分包方式

1, 将 login文件夹整体放在根目录下

将个人中心的页面里面登录跳转路径改为 pages/tabs/me.vue

复制代码
登录页面的跳转路径由 
uni.navigateTo({
	url: "/pages/login/login"
});

改为
uni.navigateTo({
    url: '/login/login'
})

完整代码如下:
<template>
	<view class="me">
		<view class="me-bg" @click="login">
			<image src="/static/image/banlu.png" class="me-img"></image>
			<view class="me-nick">眼仔仔</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// 绑定用户对象数据
				// globalUser: {}
			}
		},
		// 实现页面数据动态显示
		onShow() {
			// var me = this;
			// // 定义全局用户对象
			// var globalUser = me.getGlobalUser("globalUser");
			// me.globalUser = globalUser;
		},
		methods: {
			// 微信一键登录
			login() {
				uni.navigateTo({
					url: "/login/login"
				});
			}
			// 性别 自定义点击事件 
			// modifySex() {
			// 	// 跳转页面
			// 	uni.navigateTo({
			// 		url: "/pages/Sex/Sex"
			// 	});
			// },
			// 生日 自定义点击事件 
			// modifyBirthday() {
			// 	// 跳转页面
			// 	uni.navigateTo({
			// 		url: "/pages/meBirthday/meBirthday"
			// 	});
			// },
			// 昵称 自定义点击事件 
			// modifyNickname() {
			// 	// 跳转页面
			// 	uni.navigateTo({
			// 		url: "/pages/meNickname/meNickname"
			// 	});
			// }
		}
	}
</script>

<style scoped="scss">
	.me {
		width: 750rpx;
		height: 281rpx;
		background: #FFFFFF;
		/* border-radius: 0px 0px 0px 0px; */
		/* opacity: 0.65; */
		/* border: 1px solid #707070; */
	}

	.me-bg {
		display: flex;
		justify-content: flex-start;
		align-items: center;
		width: 100%;
		height: 281rpx;
		background: url('https://luxian-ai.oss-cn-beijing.aliyuncs.com/luxian-ai/avatar/2024-07-28/1722173053591686.jpg') no-repeat;
		background-size: 100% 100%;
	}

	.me-img {
		width: 141rpx;
		height: 141rpx;
		border-radius: 50%;
		background-color: #FFFFFF;
		opacity: 1;
	}

	.me-nick {}
</style>

2, 将文件pages.json中分包的内容 "root": "pages/login", 改为 "root": "login",就可以实现分包

复制代码
{
	// 如果您是通过uni_modules形式引入uView,可以忽略此配置
	"easycom": { // u-$1 表示components下所有u-*都可以,u-$.vue 表示u-*.vue所有文件都可以,即表示全局引入ui组件所有内容
		"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
	},
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/tabs/index",
			"style": {
				"navigationBarTitleText": "推荐",
				"navigationStyle": "custom"
			}
		},
		{
			"path": "pages/tabs/list",
			"style": {
				"navigationBarTitleText": "分类"
			}
		},
		{
			"path": "pages/tabs/me",
			"style": {
				"navigationBarTitleText": "我的",
				"navigationStyle": "custom"
			}
		}
	],
	"subPackages": [{
		"root": "login", // 根路径
		"pages": [{
			"path": "login",
			"style": {
				"navigationBarTitleText": "登录"
			}
		}, {
			"path": "bindPhone",
			"style": {
				"navigationBarTitleText": "绑定手机号"
			}
		}]
	}],
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#3cc51f",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"list": [{
			"pagePath": "pages/tabs/index",
			"iconPath": "/static/icon/recommend.png",
			"selectedIconPath": "/static/icon/recommend-hl.png",
			"text": "推荐"
		}, {
			"pagePath": "pages/tabs/list",
			"iconPath": "/static/icon/classify.png",
			"selectedIconPath": "/static/icon/classify-hl.png",
			"text": "分类"
		}, {
			"pagePath": "pages/tabs/me",
			"iconPath": "/static/icon/mine.png",
			"selectedIconPath": "/static/icon/mine-hl.png",
			"text": "我的"
		}]
	},

	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {}
}

3, 将文件login.vue中 登录跳转路径

复制代码
修改登录跳转路径
uni.navigateTo({
    url: '/pages/login/bindPhone'
})

改为
uni.navigateTo({
    url: '/login/bindPhone'
})

完整代码如下
<template>
	<view>
		<button @click="login">微信登录</button>
	</view>
</template>

<script>
	// import {
	// 	params
	// } from 'jquery'
	import {
		loginByWechat,
		wechatRegister
	} from '@/utils/api/login.js'
	export default {
		data() {
			return {

			}
		},
		methods: {
			// 点击登录
			login() {
				// 解决闭包问题
				let that = this;
				uni.getUserProfile({ // 获取用户信息  这是一个闭包函数 有两个success()函数,称之为闭包函数
					desc: '登录后同步数据',
					success(ures) {
						// console.log('getUserProfile', ures);
						uni.login({ //获取用户code码,前端把code码传递给后端才能判断用户是否绑定手机号。
							// 通过这个code来判断这个用户在这个小程序有没有注册过[之前有没有登录过]
							success(lres) {
								// 通过这个code来判断,这个用户有没有绑定手机号
								let params = {
									code: lres.code
								}
								loginByWechat(params).then(res => {
									// console.log('后端接口返回', res);
									// 如果返回'60003'表示这个用户之前没有注册过
									if (res.code == '60003') {
										// 注册微信用户
										let params = ({
											unionId: res.data.unionId ? res.data.unionId :
												res.data.openid,
											openId: res.data.openid,
											sessionKey: res.data.sessionKey,
											signature: ures.signature,
											rawData: ures.rawData,
											encryptedData: ures.encryptedData,
											iv: ures.iv
										});
										// 这是一个闭包函数 有两个success()函数,称之为闭包函数
										that.register(params);
									} else if (res.code == '200') {
										// 微信注册过账户(之前登录过),查看有没有绑定手机号
										that.isMobile(res.data);
									}
								})
							}
						});
					}
				});
			},
			// 注册微信用户
			register(params) {
				wechatRegister(params).then(res => {
					if (res.code == '200') {
						this.isMobile(res.data);
					}
					// console.log(res);
				})
			},
			isMobile(data) {
				// 用户信息包含 token
				// console.log(data);

				// 存储 token
				uni.setStorage({
					key: 'token',
					data: data.token
				})

				// 判断用户有没有绑定手机号
				if (!data.member.mobile) { // 取反表示没有绑定手机号
					// this.isMobile(res.data.member.mobile);
					uni.showModal({
						title: '提示信息',
						confirmText: '去完善',
						content: '根据国家规定,需要绑定手机号',
						success(res) {
							if (res.confirm) {
								uni.navigateTo({
									url: '/login/bindPhone'
								})
							}
							// else if (res.cancel) {
							// 	console.log('用户点击取消');
							// }
						}
					})
				}
			}
		}
	}
</script>

<style>

</style>

以上就是简单实现分别介绍与实践

相关推荐
2501_916007472 小时前
苹果上架全流程详解,iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传与审核要点完整指南
android·ios·小程序·https·uni-app·iphone·webview
wordbaby2 小时前
Hooks的革命:让React的非UI逻辑也能像UI组件一样自由复用和组合
前端·react.js
flower_tomb2 小时前
对浏览器事件机制的理解
前端·javascript·vue.js
用户458203153172 小时前
使用Trae做一个简单的天狗食日动画效果试试
前端·trae
普通码农2 小时前
Vue Element Plus X 部署后资源加载失败问题
前端
超人不会飛2 小时前
仿豆包 H5应用核心模板:用Vue快速复刻大模型对话体验
前端·javascript·vue.js
程序张2 小时前
Vue3+Vite 现代化前端框架👊打破 Chrome 83 内核限制
前端·javascript·vue.js
拜无忧2 小时前
【教程】Vue中级转React终极指南-理解Vue和React的差异
前端·vue.js·react.js
web前端1232 小时前
Android开发四大组件详解
前端