QQ小程序 分包加載

2020-07-02 15:08 更新

某些情況下,開(kāi)發(fā)者需要將小程序劃分成不同的子包,在構(gòu)建時(shí)打包成不同的分包,用戶在使用時(shí)按需進(jìn)行加載。 在構(gòu)建小程序分包項(xiàng)目時(shí),構(gòu)建會(huì)輸出一個(gè)或多個(gè)分包。每個(gè)使用分包小程序必定含有一個(gè)主包。所謂的主包,即放置默認(rèn)啟動(dòng)頁(yè)面/TabBar 頁(yè)面,以及一些所有分包都需用到公共資源/JS 腳本;而分包則是根據(jù)開(kāi)發(fā)者的配置進(jìn)行劃分。 在小程序啟動(dòng)時(shí),默認(rèn)會(huì)下載主包并啟動(dòng)主包內(nèi)頁(yè)面,當(dāng)用戶用戶進(jìn)入分包內(nèi)某個(gè)頁(yè)面時(shí),客戶端會(huì)把對(duì)應(yīng)分包下載下來(lái),下載完成后再進(jìn)行展示。 目前小程序分包大小有以下限制:

  • 整個(gè)小程序所有分包大小不超過(guò) 24M
  • 單個(gè)分包/主包大小不能超過(guò) 2M 對(duì)小程序進(jìn)行分包,可以優(yōu)化小程序首次啟動(dòng)的下載時(shí)間,以及在多團(tuán)隊(duì)共同開(kāi)發(fā)時(shí)可以更好的解耦協(xié)作。

使用分包

假設(shè)支持分包的小程序目錄結(jié)構(gòu)如下:

├── app.js
├── app.json
├── app.qss
├── packageA
│   └── pages
│       ├── cat
│       └── dog
├── packageB
│   └── pages
│       ├── apple
│       └── banana
├── pages
│   ├── index
│   └── logs
└── utils

開(kāi)發(fā)者通過(guò)在 app.json subpackages 字段聲明項(xiàng)目分包結(jié)構(gòu):

寫成 subPackages 也支持。

{
  "pages": ["pages/index", "pages/logs"],
  "subpackages": [
    {
      "root": "packageA",
      "pages": ["pages/cat", "pages/dog"]
    },
    {
      "root": "packageB",
      "name": "pack2",
      "pages": ["pages/apple", "pages/banana"]
    }
  ]
}

subpackages 中,每個(gè)分包的配置有以下幾項(xiàng):

字段 類型 說(shuō)明
root String 分包根目錄
name String 分包別名,分包預(yù)下載時(shí)使用,如將分包配置到preloadRule中,則必須指定
pages StringArray 分包頁(yè)面路徑,相對(duì)與分包根目錄
independent Boolean 分包是否是獨(dú)立分包

打包原則

  • 聲明 subpackages 后,將按 subpackages 配置路徑進(jìn)行打包,subpackages 配置路徑外的目錄將被打包到 app(主包) 中
  • app(主包)也可以有自己的 pages(即最外層的 pages 字段)
  • subpackage 的根目錄不能是另外一個(gè) subpackage 內(nèi)的子目錄
  • tabBar 頁(yè)面必須在 app(主包)內(nèi)

引用原則

  • packageA 無(wú)法 require packageB JS 文件,但可以 require app、自己 package 內(nèi)的 JS 文件
  • packageA 無(wú)法 import packageB 的 template,但可以 require app、自己 package 內(nèi)的 template
  • packageA 無(wú)法使用 packageB 的資源,但可以使用 app、自己 package 內(nèi)的資源

低版本兼容

由QQ后臺(tái)編譯來(lái)處理舊版本客戶端的兼容,后臺(tái)會(huì)編譯兩份代碼包,一份是分包后代碼,另外一份是整包的兼容代碼。 新客戶端用分包,老客戶端還是用的整包,完整包會(huì)把各個(gè) subpackage 里面的路徑放到 pages 中。

獨(dú)立分包

獨(dú)立分包是小程序中一種特殊類型的分包,可以獨(dú)立于主包和其他分包運(yùn)行。從獨(dú)立分包中頁(yè)面進(jìn)入小程序時(shí),不需要下載主包。當(dāng)用戶進(jìn)入普通分包或主包內(nèi)頁(yè)面時(shí),主包才會(huì)被下載。 開(kāi)發(fā)者可以按需將某些具有一定功能獨(dú)立性的頁(yè)面配置到獨(dú)立分包中。當(dāng)小程序從普通的分包頁(yè)面啟動(dòng)時(shí),需要首先下載主包;而獨(dú)立分包不依賴主包即可運(yùn)行,可以很大程度上提升分包頁(yè)面的啟動(dòng)速度。 一個(gè)小程序中可以有多個(gè)獨(dú)立分包。

小游戲不支持獨(dú)立分包。

配置方法

假設(shè)小程序目錄結(jié)構(gòu)如下:

├── app.js
├── app.json
├── app.qss
├── moduleA
│   └── pages
│       ├── rabbit
│       └── squirrel
├── moduleB
│   └── pages
│       ├── pear
│       └── pineapple
├── pages
│   ├── index
│   └── logs
└── utils

開(kāi)發(fā)者通過(guò)在app.json的subpackages字段中對(duì)應(yīng)的分包配置項(xiàng)中定義independent字段聲明對(duì)應(yīng)分包為獨(dú)立分包。

{
  "pages": ["pages/index", "pages/logs"],
  "subpackages": [
    {
      "root": "moduleA",
      "pages": ["pages/rabbit", "pages/squirrel"]
    },
    {
      "root": "moduleB",
      "pages": ["pages/pear", "pages/pineapple"],
      "independent": true
    }
  ]
}

限制

獨(dú)立分包屬于分包的一種。普通分包的所有限制都對(duì)獨(dú)立分包有效。獨(dú)立分包中插件、自定義組件的處理方式同普通分包。 此外,使用獨(dú)立分包時(shí)要注意:

  • 獨(dú)立分包中不能依賴主包和其他分包中的內(nèi)容,包括js文件、template、qss、自定義組件、插件等。主包中的app.qss對(duì)獨(dú)立分包無(wú)效,應(yīng)避免在獨(dú)立分包頁(yè)面中使用 app.qss 中的樣式;
  • App 只能在主包內(nèi)定義,獨(dú)立分包中不能定義 App,會(huì)造成無(wú)法預(yù)期的行為;
  • 獨(dú)立分包中暫時(shí)不支持使用插件。

注意事項(xiàng)

(1)關(guān)于 getApp()

與普通分包不同,獨(dú)立分包運(yùn)行時(shí),App 并不一定被注冊(cè),因此 - getApp() 也不一定可以獲得 App 對(duì)象:

  • 當(dāng)用戶從獨(dú)立分包頁(yè)面啟動(dòng)小程序時(shí),主包不存在,App也不存在,此時(shí)調(diào)用 getApp() 獲取到的是 undefined。 當(dāng)用戶進(jìn)入普通分包或主包內(nèi)頁(yè)面時(shí),主包才會(huì)被下載,App 才會(huì)被注冊(cè)。
  • 當(dāng)用戶是從普通分包或主包內(nèi)頁(yè)面跳轉(zhuǎn)到獨(dú)立分包頁(yè)面時(shí),主包已經(jīng)存在,此時(shí)調(diào)用 getApp() 可以獲取到真正的 App。 由于這一限制,開(kāi)發(fā)者無(wú)法通過(guò) App 對(duì)象實(shí)現(xiàn)獨(dú)立分包和小程序其他部分的全局變量共享。 getApp支持 allowDefault參數(shù),在 App 未定義時(shí)返回一個(gè)默認(rèn)實(shí)現(xiàn)。當(dāng)主包加載,App被注冊(cè)時(shí),默認(rèn)實(shí)現(xiàn)中定義的屬性會(huì)被覆蓋合并到真正的 App 中。

示例代碼: 獨(dú)立分包中

const app = getApp({allowDefault: true}) // {}
app.data = 456
app.global = {}

app.js 中

App({
  data: 123,
  other: 'hello'
})


console.log(getApp()) // {global: {}, data: 456, other: 'hello'}

(2)關(guān)于 App 生命周期 當(dāng)從獨(dú)立分包啟動(dòng)小程序時(shí),主包中 ApponLaunch 和首次 onShow 會(huì)在從獨(dú)立分包頁(yè)面首次進(jìn)入主包或其他普通分包頁(yè)面時(shí)調(diào)用。 由于獨(dú)立分包中無(wú)法定義 App,小程序生命周期的監(jiān)聽(tīng)可以使用 qq.onAppShowqq.onAppHide 完成。App 上的其他事件可以使用 qq.onErrorqq.onPageNotFound 監(jiān)聽(tīng)。

低版本兼容

注意:在兼容模式下,主包中的 app.qss 可能會(huì)對(duì)獨(dú)立分包中的頁(yè)面產(chǎn)生影響,因此應(yīng)避免在獨(dú)立分包頁(yè)面中使用 app.qss 中的樣式。

分包預(yù)下載

開(kāi)發(fā)者可以通過(guò)配置,在進(jìn)入小程序某個(gè)頁(yè)面時(shí),由框架自動(dòng)預(yù)下載可能需要的分包,提升進(jìn)入后續(xù)分包頁(yè)面時(shí)的啟動(dòng)速度。對(duì)于獨(dú)立分包,也可以預(yù)下載主包。 分包預(yù)下載目前只支持通過(guò)配置方式使用,暫不支持通過(guò)調(diào)用API完成。

vConsole 里有preloadSubpackages開(kāi)頭的日志信息,可以用來(lái)驗(yàn)證預(yù)下載的情況。

配置方法

預(yù)下載分包行為在進(jìn)入某個(gè)頁(yè)面時(shí)觸發(fā),通過(guò)在 app.json 增加 preloadRule 配置來(lái)控制。

{
  "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__"]
    }
  }
}

preloadRule 中,key 是頁(yè)面路徑,value 是進(jìn)入此頁(yè)面的預(yù)下載配置,每個(gè)配置有以下幾項(xiàng):

字段 類型 必填 默認(rèn)值 說(shuō)明
packages StringArray 無(wú) 進(jìn)入頁(yè)面后預(yù)下載分包的 root 或 name。APP 表示主包。
network String wifi 在指定網(wǎng)絡(luò)下預(yù)下載,可選值為:all: 不限網(wǎng)絡(luò) wifi: 僅wifi下預(yù)下載

限制

同一個(gè)分包中的頁(yè)面享有共同的預(yù)下載大小限額 2M,限額會(huì)在工具中打包時(shí)校驗(yàn)。 如,頁(yè)面 A 和 B 都在同一個(gè)分包中,A 中預(yù)下載總大小 0.5M 的分包,B中最多只能預(yù)下載總大小 1.5M 的分包。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)