uni-app、小程序项目分包经验之谈与天坑异常:RangeError: Maximum call stack size exceeded
小程序分包經驗之談與天坑異常:RangeError: Maximum call stack size exceeded
- 小程序分包概述
- 分包配置參數:subPackages
- 分包預載配置參數:preloadRule
- 如何使用
- 實際小程序項目分包
- 項目結構
- 配置分包
- 配置分包預載
- 天坑異常
- 場景
- 分析猜想
- 嘗試解決
- 解決分包頁面無法跳轉
小程序分包概述
分包配置參數:subPackages
pages.json文件中的subPackages參數是小程序的分包加載配置,主要作用是為了提升頁面啟動、加載速度。
分包分為主包與分包,主包只能有一個,分包多個,但總的小程序項目體積大小是有一定限制的,不同平臺小程序的總體積限制不一樣。
主包
放置默認啟動頁面/TabBar頁面,以及一些所有分包都需用到公共資源/JS腳本分包
通常根據不同功能模塊進行劃分在小程序啟動時,默認會下載主包并啟動主包內頁面,當用戶進入分包內某個頁面時,會把對應分包自動下載下來,下載完成后再進行展示。此時終端界面會有等待提示。
subPackages參數接收一個數組,數組每一項都是應用的子包,相關屬性值如下:
| root | String | 是 | 子包的根目錄 |
| pages | Array | 是 | 子包由哪些頁面組成,參數同 pages |
分包預載配置參數:preloadRule
配置preloadRule后,在進入小程序某個頁面時,由框架自動預下載可能需要的分包,提升進入后續分包頁面時的啟動速度
preloadRule參數接收一個對象,key是頁面路徑,value是進入此頁面的預下載配置,配置如下:
| packages | StringArray | 是 | 無 | 進入頁面后預下載分包的 root 或 name。APP 表示主包。 |
| network | String | 否 | wifi | 在指定網絡下預下載,可選值為:all(不限網絡)、wifi(僅wifi下預下載) |
如何使用
假設支持分包的uni-app、小程序目錄結構如下:
┌─pages │ ├─index │ │ └─index.vue │ └─login │ └─login.vue ├─pagesA │ ├─static │ └─list │ └─list.vue ├─pagesB │ ├─static │ └─detail │ └─detail.vue ├─static ├─main.js ├─App.vue ├─manifest.json └─pages.json則在pages.json中需要如下這樣配置
{"pages": [{"path": "pages/index/index","style": { ...}}, {"path": "pages/login/login","style": { ...}}],"subPackages": [{"root": "pagesA","pages": [{"path": "list/list","style": { ...}}]}, {"root": "pagesB","pages": [{"path": "detail/detail","style": { ...}}]}],"preloadRule": {"pagesA/list/list": {"network": "all","packages": ["__APP__"]},"pagesB/detail/detail": {"network": "all","packages": ["pagesA"]}} }實際小程序項目分包
實際小程序項目分包,參考相關文檔,按文檔說明進行配置即可,在初次聽說分包時還是一臉懵逼,看了文檔,配置后發現分包也就那樣。
項目結構
本項目是以cli方式開發,與使用HBuilderX生成的目錄結構有一定差異,但萬變不離其宗,配置大同小異。
本項目結構如下,由于小程序包體積過大,需要進行分包操作,這里將對process目錄,即本項目的一個功能模塊進行分包處理。
配置分包
對pages.json文件進行配置,參考相關文檔,按文檔說明進行配置即可,相對簡單
"pages": [{"path": "pages/index/login","style": {"navigationBarTitleText": "登錄"}},{"path": "pages/index/index","style": {"navigationBarTitleText": "首頁"}}],"subPackages": [{"root": "pages/process","pages": [{"path": "core/ProcessList","name": "ProcessList","style": {"navigationBarTitleText": "流程列表"}}]}]配置分包預載
"preloadRule": {"pages/index/index": {"network": "all","packages": ["pages/process"]}},當啟動項目,訪問pages/index/index地址時,就會加載分包資源,且能在控制臺看到如下內容提示
preloadSubpackages: pages/process preloadSubpackages: success天坑異常
場景
在主包某個頁面,有一個跳轉頁面的點擊事件,事件如下
methods:{click(name) {//this.$Router.push("/pages/process/core/ProcessList")uni.navigateTo({url: '/pages/process/core/ProcessList'});}}進行項目分包后,在主包某個頁面訪問分包的某個頁面,發現無法訪問,直接報錯,且還不能直觀發現問題,具體異常如下:
RangeError: Maximum call stack size exceededat RegExp.get global [as global] (<anonymous>)at RegExp.[Symbol.replace] (<anonymous>)at String.replace (<anonymous>)at l (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)at f (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)at vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494at e (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)at e (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)at Object.e [as routesForMapRoute] (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)at Object.f [as navjump] (vendor.js?t=wechat&s=1666771492607&v=0305a7a0cd1f60c216184c725a22d2c3:19494)(env: Windows,mp,1.06.2209190; lib: 2.25.4)分析猜想
就一個點擊事件怎么會造成呢,在分包前是能正常訪問的,分包后無法訪問,百思不得其解,查閱了國內外各種相關資料,沒發現類似問題。,均無解,折騰、苦惱一天,直到快下班的時候,腦殼突然靈光一閃。
異常提示:Maximum call stack size exceeded,大概意思是:超過最大調用堆棧大小
猜想:出現此問題,應該是那個地方出現了死循環,而跳轉跟路由相關,然后查看路由跳轉相關配置,配置如下:
import {RouterMount,createRouter} from 'uni-simple-router';//初始化 const router = createRouter({platform: process.env.VUE_APP_PLATFORM,routes: [...ROUTES,{path: '*', redirect:(to)=>{return {name:'404'}}},] });const whiteList = ['/pages/index/login']//全局路由前置守衛 router.beforeEach((to, from, next) => {let token=uni.getStorageSync("Token");if(token){next()}else{if (whiteList.indexOf(to.path) !== -1) {next()}else{next({ path: '/pages/index/login'})}} });// 全局路由后置守衛 router.afterEach((to, from) => {console.log('跳轉結束') })export {router,RouterMount }嘗試解決
將{path: '*', redirect:(to)=>{return {name:'404'}}},路由找不到重定向到404頁面注釋,然后再次點擊跳轉頁面,發現控制臺出現了明顯的提示
Error: /pages/process/core/ProcessList 路徑無法在路由表中找到!檢查跳轉路徑及路由表at Object.e [as routesForMapRoute] (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at Object.t.queryPageToMap (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at f (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487at Object.t.lockDetectWarn (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at Object.s [as lockNavjump] (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at Object.push (vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:19487)at VueComponent.click (IndexGrid.js:213)at vendor.js?t=wechat&s=1666830636547&v=05274921cc6e9566623954d1e3403ca3:2081at Array.forEach (<anonymous>)(env: Windows,mp,1.06.2210141; lib: 2.25.4)這個路徑肯定是存在的,并且使用分包預加載是加載了的,奇了怪了,既然找不到這個路由地址,那在沒注釋上述代碼時,應該跳轉到404頁面,居然沒跳轉,仔細看代碼,發現本項目這里使用命名路由,這個name:'404'配置被遺漏了。
原來pages.json文件:
pages": [{"path": "pages/error/404","style": {"navigationBarTitleText": "404"}}]修改后對應pages.json文件:
pages": [{"path": "pages/error/404","name": "404","style": {"navigationBarTitleText": "404"}}]如此,得出猜測結論:點擊事件跳轉某個頁面,當找不到跳轉頁面則重定向到name:'404'的頁面,由于今天對pages.json文件進行拆分,使用動態生成pages.json文件,進行了相關頁面配置拆分到不同js文件,恰好error.js中配置的404頁面中沒有配置name:'404'參數,被遺漏了,故此這里進行了死循環造成了堆棧溢出。
重啟項目,動態生成pages.json文件,再次點擊訪問跳轉分包頁面,發現重定向到了404頁面,到這里這個異常:RangeError: Maximum call stack size exceeded就得以解決。
解決分包頁面無法跳轉
在上面分析猜想得出結果:在router.js文件中將路由找不到重定向到404頁面注釋,然后再次點擊跳轉頁面,發現控制臺出現了明顯的提示,找不到相關頁面地址、路由地址。
Error: /pages/process/core/ProcessList 路徑無法在路由表中找到!檢查跳轉路徑及路由表這個路由地址能肯定是存在、正確的,并且使用分包預加載是加載了的,很奇怪,然后又看了一遍官方文檔,突然發現在分包配置參數root的值與本項目配置的有點點差異:
官方示例:
"preloadRule": {"pagesA/list/list": {"network": "all","packages": ["__APP__"]},"pagesB/detail/detail": {"network": "all","packages": ["pagesA"]}}本項目配置:
"subPackages": [{"root": "pages/process/","pages": [{"path": "core/ProcessList","name": "ProcessList","style": {"navigationBarTitleText": "流程列表"}}]}]root參數用于配置子包的根目錄,官方配置根目錄后面沒有/,期初我也覺得這個不是重點,實在無解,打算嘗試的心理一試,結果可以了,問題得以解決,一句MMP啊!
總結
以上是生活随笔為你收集整理的uni-app、小程序项目分包经验之谈与天坑异常:RangeError: Maximum call stack size exceeded的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery lightbox插件(相册
- 下一篇: android定位!每个程序员都必须掌握