小程序 分包

某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。

在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。
所谓的主包,即放置默认启动页面/TabBar页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。

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

目前小程序分包大小有以下限制:
    整个小程序所有分包大小不超过 20M
    单个分包/主包大小不能超过 2M

对小程序进行分包,可以优化小程序首次启动的下载时间,以及在多团队共同开发时可以更好的解耦协作。

小程序 分包_第1张图片

(1)声明分包
	在app.json的subpackages字段声明项目分包结构:
	{
	  "pages":[			主包
	    "pages/index",
	    "pages/logs"
	  ],
	  "subpackages": [	分包	
	    {
	      "root": "packageA",	
	      "pages": [
	        "pages/cat",	相对于root分包的路径
	        "pages/dog"
	      ]
	    }, {
	      "root": "packageB",
	      "name": "pack2",
	      "pages": [
	        "pages/apple",
	        "pages/banana"
	      ]
	    },
	    {
	    	root:分包根目录
			name:分包别名,分包预下载时可以使用
			pages:分包页面路径数组,相对与分包根目录
			independent:true|false分包是否是独立分包
	    }
	  ]
	}
	
	其中:
		声明subpackages后,将按subpackages配置路径进行打包,subpackages配置路径外的目录将被打包到主包中
		subpackage的根目录不能是另外一个subpackage内的子目录
		tabBar页面必须在主包内
	
	引用原则:
		对于js、template、资源
		packageA无法require packageB的,但可以require app、自己package内的(对于js文件:使用分包异步化时不受此条限制)

(2)独立分包
	独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。
	从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。
	{
	  "pages": [
	    "pages/index",
	    "pages/logs"
	  ],
	  "subpackages": [ {
	      "root": "moduleB",
	      "pages": [
	        "pages/pear",
	        "pages/pineapple"
	      ],
	      "independent": true
	    }
	  ]
	}
	其中:
		.普通分包的所有限制都对独立分包有效
		.独立分包中不能依赖主包和其他分包中的内容,包括js文件、template、wxss、自定义组件、插件等(使用分包异步化时js文件、自定义组件、插件不受此条限制)
		.主包中的app.wxss对独立分包无效,应避免在独立分包页面中使用app.wxss中的样式;
		.App只能在主包内定义,独立分包中不能定义App,会造成无法预期的行为;
		.独立分包中暂时不支持使用插件。
	
	1、独立分包中全局变量共享
	与普通分包不同,独立分包运行时,App并不一定被注册,因此getApp()也不一定可以获得App对象
		当用户从独立分包页面启动小程序时,主包不存在,App也不存在,此时调用getApp()获取到的是undefined。
		当用户进入普通分包或主包内页面时,主包才会被下载,App才会被注册。
		当用户是从普通分包或主包内页面跳转到独立分包页面时,主包已经存在,此时调用getApp()可以获取到真正的App。
		独立分包中
			const app = getApp({allowDefault: true})
			app.data = 456
			app.global = {}
		app.js中
			App({
			  data: 123,
			  other: 'hello'
			})
			console.log(getApp())	可以获得独立分包中设置的全局数据,会覆盖掉当前文件中设置的相同变量

	2、独立分包的生命周期
		当从独立分包启动小程序时,主包中App的onLaunch和首次onShow会在从独立分包页面首次进入主包或其他普通分包页面时调用。
		由于独立分包中无法定义App,小程序生命周期的监听可以使用wx.onAppShow,wx.onAppHide完成。
		App上的其他事件可以使用wx.onError,wx.onPageNotFound监听

(3)分包预下载
	在进入小程序某个页面时,由框架自动预下载可能需要的分包,对于独立分包,也可以预下载主包。
	{
	 "pages": ["pages/index"],
	  "subpackages": [
	    {
	      "root": "important",
	      "pages": ["index"],
	    },
	    {
	      "root": "sub1",
	      "pages": ["index"],
	    },
	    {
	      "name": "hello",
	      "root": "path/to",
	      "pages": ["index"]
	    },
	    {
	      "root": "sub3",
	      "pages": ["index"]
	    },
	    {
	      "root": "indep",
	      "pages": ["index"],
	      "independent": true
	    }
	  ],
	  "preloadRule": {		进行预下载
	    "pages/index": {	进入页面的路径
	      "network": "all",			all不限网络、wifi:仅wifi下预下载
	      "packages": ["important"]	可以是分包的root或name
	    },
	    "sub1/index": {
	      "packages": ["hello", "sub3"]
	    },
	    "sub3/index": {
	      "packages": ["path/to"]	
	    },
	    "indep/index": {
	      "packages": ["__APP__"]		__APP__ 表示主包。
	    }
	  }
	}
		其中:
			同一个分包中的页面享有共同的预下载大小限额2M,限额会在工具中打包时校验。
			页面A和B都在同一个分包中,A中预下载总大小0.5M的分包,B中最多只能预下载总大小1.5M的分包。

(4)分包异步化
	在小程序中,不同的分包对应不同的下载单元;因此,除了非独立分包可以依赖主包外,分包之间不能互相使用自定义组件或进行require。
   「分包异步化」特性将允许通过一些配置和新的接口,使部分跨分包的内容可以等待下载后异步使用,从而一定程度上解决这个限制。
   	
   	1、组件共享
   		一个分包使用其他分包的自定义组件时,由于其他分包还未下载或注入,其他分包的组件处于不可用的状态。
   		通过为其他分包的自定义组件设置占位组件,我们可以先渲染占位组件作为替代,在分包下载完成后再进行替换。
   		
   		subPackageA/pages/index.json
		{
		  "usingComponents": {
		    "button": "../../commonPackage/components/button",	跨分包引用组件
		    "list": "../../subPackageB/components/full-list",	跨分包引用组件
		    "simple-list": "../components/simple-list"			自身包组件
		  },
		  "componentPlaceholder": {
		    "button": "view",			占位组件
		    "list": "simple-list"		占位组件,在分包下载完成后,占位组件就会被替换为对应的跨分包组件。

		  }
		}

   	2、js共享
   		require('../subPackageB/utils.js', utils => {
		  console.log(utils.whoami) // Wechat MiniProgram
		})
		或者使用 Promise 风格的调用
		require.async('../commonPackage/index.js').then(pkg => {
		  pkg.getPackageName() // 'common'
		})
		
		其他分包的插件中暴露的接口
		requirePlugin('live-player-plugin', livePlayer => {
		  console.log(livePlayer.getPluginVersion())
		})
		或者使用 Promise 风格的调用
		requirePlugin.async('live-player-plugin').then(livePlayer => {
		  console.log(livePlayer.getPluginVersion())
		})

你可能感兴趣的:(微信小程序,小程序)