一、app.json配置屬性之subpackages和preloadRule
1.subpackages
分包的功能主要是實作小程式按需加載,進入分包頁面才會進行分包的加載。
在建構小程式分包項目時,建構會輸出一個或多個分包。每個使用分包小程式必定含有一個主包。所謂的主包,即放置預設啟動頁面/TabBar 頁面,以及一些所有分包都需用到公共資源/JS 腳本;而分包則是根據開發者的配置進行劃分。
在小程式啟動時,預設會下載下傳主包并啟動主包内頁面,當使用者進入分包内某個頁面時,用戶端會把對應分包下載下傳下來,下載下傳完成後再進行展示。
目前小程式分包大小有以下限制:
- 整個小程式所有分包大小不超過 20M
- 單個分包/主包大小不能超過 2M
對小程式進行分包,可以優化小程式首次啟動的下載下傳時間,以及在多團隊共同開發時可以更好的解耦協作。
2.preloadRule
當分包預加載以後,我們進入這個包所在的頁面後就會流暢運作了,因為資源已經事先加載
。
二、小程式普通分包配置
字段 | 類型 | 說明 |
---|---|---|
root | String | 分包根目錄 |
name | String | 分包别名,分包預下載下傳時可以使用 |
pages | StringArray | 分包頁面路徑,相對與分包根目錄 |
independent | Boolean | 分包是否是獨立分包 |
{
"entryPagePath": "pages/index/index",
"pages": [
"pages/index/index",
"pages/getOpenId/index",
"pages/getMiniProgramCode/index",
"pages/deployService/index",
"pages/createCollection/index",
"pages/uploadFile/index",
"pages/selectRecord/index",
"pages/updateRecord/index",
"pages/updateRecordResult/index",
"pages/updateRecordSuccess/index",
"pages/sumRecord/index",
"pages/sumRecordResult/index"
],
"subPackages": [
{
"root": "packageA",
"pages": [
"pages/cat/cat",
"pages/dog/dog"
]
}, {
"root": "packageB",
"pages": [
"pages/apple/apple",
"pages/banana/banana"
]
}
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "雲開發 QuickStart",
"navigationBarTextStyle": "black"
},
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首頁"
},
{
"pagePath": "pages/getOpenId/index",
"text": "看資訊"
},
{
"pagePath": "pages/getMiniProgramCode/index",
"text": "我的"
}
],
"backgroundColor": "#fff",
"color": "#000",
"selectedColor": "#0286f1"
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000,
"connectSocket": 10000,
"uploadFile": 10000
},
"sitemapLocation": "sitemap.json",
"style": "v2",
"debug":true
}
1.打包原則
-
聲明 subpackages 後,将按 subpackages 配置路徑進行打包,subpackages 配置路徑外的目錄将被打包到
app(主包) 中
- app(主包)也可以有自己的 pages(即最外層的 pages 字段)
- subpackage 的根目錄不能是另外一個 subpackage 内的子目錄
- tabBar 頁面必須在 app(主包)内
2.引用原則
-
packageA 無法 require packageB JS 檔案,但可以 require app、自己 package 内的 JS
檔案;使用 分包異步化 時不受此條限制
-
packageA 無法 import packageB 的 template,但可以 require app、自己 package 内的
template
- packageA 無法使用 packageB 的資源,但可以使用 app、自己 package 内的資源
三、小程式獨立分包配置
獨立分包屬于分包的一種。普通分包的所有限制都對獨立分包有效。獨立分包中插件、自定義元件的處理方式同普通分包。
此外,使用獨立分包時要注意:
-
獨立分包中不能依賴主包和其他分包中的内容,包括 js 檔案、template、wxss、自定義元件、插件等(使用 分包異步化 時 js
檔案、自定義元件、插件不受此條限制)
- 主包中的 app.wxss 對獨立分包無效,應避免在獨立分包頁面中使用 app.wxss 中的樣式;
- App 隻能在主包内定義,獨立分包中不能定義 App,會造成無法預期的行為;
- 獨立分包中暫時不支援使用插件。
const app = getApp({allowDefault: true}) // 分包中預設定義進入主包App會重新覆寫
app.data = 456
app.global = {}
App({
data: 123,
other: 'hello'
})
console.log(getApp()) // {global: {}, data: 456, other: 'hello'}
四、小程式分包預加載配置
{
"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",
"packages": ["important"]
},
"sub1/index": {
"packages": ["hello", "sub3"]
},
"sub3/index": {
"packages": ["path/to"]
},
"indep/index": {
"packages": ["__APP__"]
}
}
}
字段 | 類型 | 必填 | 預設值 | 說明 |
---|---|---|---|---|
packages | StringArray | 是 | 無 | 進入頁面後預下載下傳分包的 root 或 name。APP 表示主包。 |
network | String | 否 | wifi | 在指定網絡下預下載下傳,可選值為:all: 不限網絡 ,wifi: 僅wifi下預下載下傳 |
五、分包異步化
在小程式中,不同的分包對應不同的下載下傳單元;是以,除了非獨立分包可以依賴主包外,分包之間不能互相使用自定義元件或進行 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 代碼引用
// subPackageA/index.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())
})