全文閱讀時長6分鐘,案例爲真實事件改編,小程序名稱、人名僅爲代號,如有雷同……那我就改。
典型案例
在一個夜黑風高的夜晚,“xx飯很多”百度智能小程序悄然上線,目錄結構如下:
├── pages
│ └── home
│ ├── index.js
│ ├── index.json
│ ├── index.css
│ └── index.swan
│ └── eat // 大口喫
│ ├── index.js
│ ...
│ └── meat // 肉
│ ├── index.js
│ ...
│ └── drink // 大碗喝
│ ├── index.js
│ ...
│ └── wine // 酒
│ ├── index.js
│ ...
│ ...
├── app.json
├── app.css
├── app.js
其中,app.json
的 pages
包含了小程序的所有頁面地址:
{
...
pages: [
"pages/home/index",
"pages/eat/index",
"pages/meat/index",
"pages/drink/index",
"pages/wine/index",
...
]
}
爲了能讓自家小程序接入搜索流量,前端小明,第一時間在開發者平臺提交了自然搜索資源:
功夫不負有心人,“xx飯很多”小程序終於被搜索引擎收錄,可以搜到了。
……
數月後,在老闆的英(zi
)明(ben
)指(bi
)揮(po
)下,“xx飯很多”小程序,功能不斷迭,實現了滿漢全席;而公司,爲了提升流量傍大腿、砸銀子,衆多小程序頁面都被投放了廣告渠道。
與此同時,小程序體積變得愈發龐大,性能體驗也遭到了嚴峻考驗……
優秀如小明,怎會被難倒,他當即選擇了分包加載,進行性能優化:
// 分包A
├── packageA
│ └── eat
│ ├── index.js
│ ├── index.json
│ ├── index.css
│ └── index.swan
│ └── meat
│ ├── index.js
│ ...
│ └── ...
│ // 分包B
├── packageB
│ └── drink
│ ├── index.js
│ ...
│ └── wine
│ ├── index.js
│ ...
│ └── ...
├── pages
│ └── home
│ ├── index.js
│ ...
├── app.js
├── app.json
├── app.css
app.json
則變成了這個樣子:
{
// 主包配置
"pages": [
"pages/home/index",
...
],
// 分包入口及配置
"subPackages": [
{
"root": "packageA",
"pages": [
"eat/index",
"meat/index",
...
]
},
{
"root": "packageB",
"pages": [
"drink/index",
"wine/index",
...
]
}
]
}
然而,包體積雖然小了——之前投放的地址,卻失效了!
由於搜索引擎收錄的是失效死鏈,“xx飯很多”小程序被降級了!
因爲被降級,資源提交的配額減少了!
不僅如此,之前投放過的所有渠道,都需要協調資源從新替換,渠道的上線時間不可控……白花花的銀子付諸流水!
老闆龍顏大怒,小明束手無策……
求問:小明距離被開還有幾天??
如何解決
其實,如果配置了小程序的自定義路由映射規則,小明的悲劇便不會發生。
當 app.json
中存在 routes
字段,框架則認爲該小程序啓用了自定義路由,將根據 routes 中的映射規則獲取路徑。
// 主包配置
"pages": [
"pages/home/index",
...
],
// 分包入口及配置
"subPackages": [
{
"root": "packageA",
"pages": [
"eat/index",
"meat/index",
...
]
},
{
"root": "packageB",
"pages": [
"drink/index",
"wine/index",
...
]
}
],
// 自定義路由
routes: [
{
"path": "home", // 投放入口,scheme中的path
"page": "pages/home/index" // 真實的物理存儲路徑
}, {
"path": "eat",
"page": "packageA/eat/index"
}, {
"path": "drink",
"page": "packageB/drink/index"
}, {
"path": "wine",
"page": "packageB/wine/index"
}, {
"path": "meat",
"page": "packageA/meat/index"
},
...
]
}
通過配置自定義路由,可以使源碼結構與配置路徑解耦,組織目錄變得更加靈活,方便代碼重構。
接下來,我們用一張圖,簡單說明下自定義路由的具體映射規則:
映射規則
規則還在哪裏生效
使用自定義路由後,小程序框架相關的 api、組件、事件等也會採用新的路由規則:
包含path/url參數的api
swan.navigateTo、swan.switchTab、swan.navigateToSmartProgram、swan.openShare等 api 中的path、url
參數;
// 以navigateTo爲例,home爲自定義路由的path,對應的真實物理地址是'pages/home/index'
swan.navigateTo({
url: '/home'
});
導航組件
navigator組件的url
屬性;
// home爲自定義路由的path,對應的真實物理地址是'pages/home/index'
<navigator url="/home" />
分享、轉發事件
頁面的事件處理函數onShareAppMessage,返回對象的path
字段;
Page({
data: {
title: 'xx飯很多信息列表'
},
onShareAppMessage() {
return {
title: this.data.title,
content: 'xx飯很多信息列表',
imageUrl: '',
// home爲自定義路由的path,對應的真實物理地址是'pages/home/index'
path: '/home',
success(res) {
// 分享成功
},
fail(err) {
// 分享失敗
}
};
}
});
打開小程序的方法
調起小程序的相關sdk,其中的path
字段
// 該方法使用前,需要引入調起sdk的文件
window.swanInvoke({
appKey: '4fecoAqgCIUtzIyA4FAPgoyrc4oUc25c',
// home爲自定義路由的path,對應的真實物理地址是'pages/home/index'
path: '/home',
query: {
id: 1,
type: 'a'
}
});
routes的框架原理
前置名詞解釋:Swanjs
是百度智能小程序的前端框架,NAFramework
代表小程序框架客戶端層,server
爲小程序服務端。
以調起小程序
和使用swan.navigateTo
爲例,簡單說下框架層對於自定義路由都做了啥:
結尾
總之,簡單的routes配置只需幾分鐘
,未雨綢繆千秋萬代
——願小明們不再哭泣~😜