uniapp分包实现

发布于:2025-09-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

关于分包优化的说明

  • 在对应平台的配置下添加"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>

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


网站公告

今日签到

点亮在社区的每一天
去签到