From 980ff4e8943129cd7a3828e14ef9f947f0328ace Mon Sep 17 00:00:00 2001 From: xuegan Date: Fri, 3 Jan 2025 13:59:53 +0800 Subject: [PATCH 1/8] =?UTF-8?q?observer=20=E8=BD=AC=E4=B8=BA=20multi=20wat?= =?UTF-8?q?ch=E6=97=B6=E5=9B=9E=E8=B0=83=E5=87=BD=E6=95=B0=E4=B8=AD?= =?UTF-8?q?=E6=97=A0=E9=9C=80=E8=BF=9B=E8=A1=8C=E8=A7=A3=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/core/mergeOptions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/core/mergeOptions.js b/packages/core/src/core/mergeOptions.js index e89414a01a..da1d95665c 100644 --- a/packages/core/src/core/mergeOptions.js +++ b/packages/core/src/core/mergeOptions.js @@ -172,7 +172,7 @@ function extractObservers (options) { val = [val] old = [old] } - cb.call(this, ...val, ...old) + cb.call(this, val, old) } }, deep, From 96d926a3531be04a9d53abd3bcddc79eea3df49d Mon Sep 17 00:00:00 2001 From: xuegan Date: Fri, 3 Jan 2025 17:03:22 +0800 Subject: [PATCH 2/8] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9observers=20?= =?UTF-8?q?=E5=9B=9E=E6=8E=89=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/core/mergeOptions.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/core/src/core/mergeOptions.js b/packages/core/src/core/mergeOptions.js index da1d95665c..517c7c41cb 100644 --- a/packages/core/src/core/mergeOptions.js +++ b/packages/core/src/core/mergeOptions.js @@ -168,11 +168,7 @@ function extractObservers (options) { cb = this[cb] } if (typeof cb === 'function') { - if (keyPathArr.length < 2) { - val = [val] - old = [old] - } - cb.call(this, val, old) + Array.isArray(val) ? cb.call(this, ...val) : cb.call(this, val) } }, deep, From dc61a2174b647882175b3701bb788e7c9bbbca68 Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Tue, 7 Jan 2025 19:24:49 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DscrollToLower?= =?UTF-8?q?=EF=BC=8CscrollToTop=E6=97=A0=E6=B3=95=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-scroll-view.tsx | 44 +++++++------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx index b058e622dc..d8a88cd881 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx @@ -160,8 +160,6 @@ const _ScrollView = forwardRef, S }) const scrollEventThrottle = 50 - const hasCallScrollToUpper = useRef(true) - const hasCallScrollToLower = useRef(false) const initialTimeout = useRef | null>(null) const intersectionObservers = useContext(IntersectionObserverContext) @@ -254,19 +252,14 @@ const _ScrollView = forwardRef, S const { bindscrolltoupper } = props const { offset } = scrollOptions.current if (bindscrolltoupper && (offset <= upperThreshold)) { - if (!hasCallScrollToUpper.current) { - bindscrolltoupper( - getCustomEvent('scrolltoupper', e, { - detail: { - direction: scrollX ? 'left' : 'top' - }, - layoutRef - }, props) - ) - hasCallScrollToUpper.current = true - } - } else { - hasCallScrollToUpper.current = false + bindscrolltoupper( + getCustomEvent('scrolltoupper', e, { + detail: { + direction: scrollX ? 'left' : 'top' + }, + layoutRef + }, props) + ) } } @@ -275,19 +268,14 @@ const _ScrollView = forwardRef, S const { contentLength, visibleLength, offset } = scrollOptions.current const distanceFromEnd = contentLength - visibleLength - offset if (bindscrolltolower && (distanceFromEnd < lowerThreshold)) { - if (!hasCallScrollToLower.current) { - hasCallScrollToLower.current = true - bindscrolltolower( - getCustomEvent('scrolltolower', e, { - detail: { - direction: scrollX ? 'right' : 'botttom' - }, - layoutRef - }, props) - ) - } - } else { - hasCallScrollToLower.current = false + bindscrolltolower( + getCustomEvent('scrolltolower', e, { + detail: { + direction: scrollX ? 'right' : 'botttom' + }, + layoutRef + }, props) + ) } } From b8dee70155ab4ff34976e6cc09f546fd6031c223 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 16:48:00 +0800 Subject: [PATCH 4/8] support hot launch in rn --- .../src/platform/api/system/index.web.js | 2 +- .../src/platform/api/system/rnSystem.js | 11 +--- packages/core/src/platform/createApp.ios.js | 59 ++++++++----------- packages/core/src/platform/createApp.js | 47 +++++++-------- packages/core/src/platform/export/inject.js | 5 +- .../platform/patch/getDefaultOptions.ios.js | 6 +- 6 files changed, 51 insertions(+), 79 deletions(-) diff --git a/packages/api-proxy/src/platform/api/system/index.web.js b/packages/api-proxy/src/platform/api/system/index.web.js index 2614aa2562..0e756b73d9 100644 --- a/packages/api-proxy/src/platform/api/system/index.web.js +++ b/packages/api-proxy/src/platform/api/system/index.web.js @@ -139,7 +139,7 @@ const getLaunchOptionsSync = function () { throwSSRWarning('getLaunchOptionsSync API is running in non browser environments') return } - return global.__mpxEnterOptions || {} + return global.__mpxLaunchOptions || {} } export { diff --git a/packages/api-proxy/src/platform/api/system/rnSystem.js b/packages/api-proxy/src/platform/api/system/rnSystem.js index acf3965ed9..abc0501466 100644 --- a/packages/api-proxy/src/platform/api/system/rnSystem.js +++ b/packages/api-proxy/src/platform/api/system/rnSystem.js @@ -41,18 +41,11 @@ const getWindowInfo = function () { } const getLaunchOptionsSync = function () { - const options = global.__mpxEnterOptions || {} - const { path, scene, query } = options - return { - path, - scene, - query - } + return global.__mpxLaunchOptions || {} } const getEnterOptionsSync = function () { - const result = getLaunchOptionsSync() - return result + return global.__mpxEnterOptions || {} } export { diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index b3ef722394..64123508ec 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -1,13 +1,12 @@ import transferOptions from '../core/transferOptions' import builtInKeysMap from './patch/builtInKeysMap' -import { makeMap, spreadProp, getFocusedNavigation, hasOwn, extend } from '@mpxjs/utils' +import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils' import { mergeLifecycle } from '../convertor/mergeLifecycle' import { LIFECYCLE } from '../platform/patch/lifecycle/index' import Mpx from '../index' import { createElement, memo, useRef, useEffect } from 'react' import * as ReactNative from 'react-native' import { Image } from 'react-native' -import { ref } from '../observer/ref' const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app) @@ -30,22 +29,24 @@ function filterOptions (options, appData) { return newOptions } -function createAppInstance (appData) { - return extend({}, Mpx.prototype, appData) -} - -export default function createApp (option, config = {}) { +export default function createApp (options) { const appData = {} const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper // app选项目前不需要进行转换 - const { rawOptions, currentInject } = transferOptions(option, 'app', false) + const { rawOptions, currentInject } = transferOptions(options, 'app', false) const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData) - defaultOptions.onAppInit && defaultOptions.onAppInit() // 在页面script执行前填充getApp() global.getApp = function () { return appData } + + defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData)) + defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData)) + defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData)) + defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData)) + defaultOptions.onAppInit && defaultOptions.onAppInit() + const pages = currentInject.getPages() || {} const firstPage = currentInject.firstPage const Stack = createStackNavigator() @@ -82,55 +83,43 @@ export default function createApp (option, config = {}) { } global.__mpxAppLaunched = false - - global.__mpxAppFocusedState = ref('show') + global.__mpxAppHotLaunched = false global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => { - const instanceRef = useRef(null) - if (!instanceRef.current) { - instanceRef.current = createAppInstance(appData) - } - const instance = instanceRef.current const initialRouteRef = useRef({ initialRouteName: firstPage, initialParams: {} }) - if (!global.__mpxAppLaunched) { + if (!global.__mpxAppHotLaunched) { const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {} initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams global.__mpxAppOnLaunch = (navigation) => { - global.__mpxAppLaunched = true const state = navigation.getState() Mpx.config.rnConfig.onStateChange?.(state) const current = state.routes[state.index] - global.__mpxEnterOptions = { + const options = { path: current.name, query: current.params, scene: 0, shareTicket: '', referrerInfo: {} } - defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, global.__mpxEnterOptions) - defaultOptions.onShow && defaultOptions.onShow.call(instance, global.__mpxEnterOptions) + global.__mpxEnterOptions = options + if (!global.__mpxAppLaunched) { + global.__mpxLaunchOptions = options + defaultOptions.onLaunch && defaultOptions.onLaunch.call(appData, options) + } + global.__mpxAppCbs.show.forEach((cb) => { + cb(options) + }) + global.__mpxAppLaunched = true + global.__mpxAppHotLaunched = true } } useEffect(() => { - if (defaultOptions.onShow) { - global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance)) - } - if (defaultOptions.onHide) { - global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance)) - } - if (defaultOptions.onError) { - global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance)) - } - if (defaultOptions.onUnhandledRejection) { - global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance)) - } - const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => { if (currentState === 'active') { let options = global.__mpxEnterOptions @@ -177,6 +166,8 @@ export default function createApp (option, config = {}) { return () => { changeSubscription && changeSubscription.remove() resizeSubScription && resizeSubScription.remove() + // 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行 + global.__mpxAppHotLaunched = false } }, []) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index 0f35cf97e5..e953d40b86 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -24,19 +24,19 @@ function filterOptions (options, appData) { return newOptions } -export default function createApp (option, config = {}) { - // 在App中挂载mpx对象供周边工具访问,如e2e测试 +export default function createApp (options, config = {}) { + const appData = {} + // app选项目前不需要进行转换 + const { rawOptions, currentInject } = transferOptions(options, 'app', false) const builtInMixins = [{ + // 在App中挂载mpx对象供周边工具访问,如e2e测试 getMpx () { return Mpx } }] - const appData = {} if (__mpx_mode__ === 'web') { builtInMixins.push({ created () { - Object.assign(this, Mpx.prototype) - Object.assign(this, appData) const current = this.$root.$options?.router?.currentRoute || {} const options = { path: current.path && current.path.replace(/^\//, ''), @@ -45,48 +45,41 @@ export default function createApp (option, config = {}) { shareTicket: '', referrerInfo: {} } + // web不分冷启动和热启动 global.__mpxEnterOptions = options - this.$options.onLaunch && this.$options.onLaunch.call(this, options) - if (isBrowser) { - if (this.$options.onShow) { - this.$options.onShow.call(this, options) - global.__mpxAppCbs.show.push(this.$options.onShow.bind(this)) - } - if (this.$options.onHide) { - global.__mpxAppCbs.hide.push(this.$options.onHide.bind(this)) - } - if (this.$options.onError) { - global.__mpxAppCbs.error.push(this.$options.onError.bind(this)) - } - if (this.$options.onUnhandledRejection) { - global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this)) - } - } + global.__mpxLaunchOptions = options + rawOptions.onLaunch && rawOptions.onLaunch.call(appData, options) + global.__mpxAppCbs.show.forEach((cb) => { + cb(options) + }) } }) } else { builtInMixins.push({ onLaunch () { - Object.assign(this, Mpx.prototype) + initAppProvides(rawOptions.provide, this) } }) } - // app选项目前不需要进行转换 - const { rawOptions, currentInject } = transferOptions(option, 'app', false) rawOptions.mixins = builtInMixins const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData) if (__mpx_mode__ === 'web') { - global.__mpxOptionsMap = global.__mpxOptionsMap || {} - global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions global.getApp = function () { if (!isBrowser) { console.error('[Mpx runtime error]: Dangerous API! global.getApp method is running in non browser environments') } return appData } + if (isBrowser) { + defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appData)) + defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appData)) + defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appData)) + defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appData)) + } + global.__mpxOptionsMap = global.__mpxOptionsMap || {} + global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions } else { - initAppProvides(rawOptions) defaultOptions.onAppInit && defaultOptions.onAppInit() const ctor = config.customCtor || global.currentCtor || App ctor(defaultOptions) diff --git a/packages/core/src/platform/export/inject.js b/packages/core/src/platform/export/inject.js index ea73092074..bc387994d0 100644 --- a/packages/core/src/platform/export/inject.js +++ b/packages/core/src/platform/export/inject.js @@ -11,11 +11,10 @@ const providesMap = { global.__mpxProvidesMap = providesMap /** @internal createApp() 初始化应用层 scope provide */ -export function initAppProvides (appOptions) { - const provideOpt = appOptions.provide +export function initAppProvides (provideOpt, instance) { if (provideOpt) { const provided = isFunction(provideOpt) - ? callWithErrorHandling(provideOpt.bind(appOptions), appOptions, 'createApp provide function') + ? callWithErrorHandling(provideOpt.bind(instance), instance, 'createApp provide function') : provideOpt if (isObject(provided)) { providesMap.__app = provided diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index ac4c5c7561..0189823b53 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -365,14 +365,10 @@ function usePageStatus (navigation, pageId) { const blurSubscription = navigation.addListener('blur', () => { pageStatusMap[pageId] = 'hide' }) - const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => { - pageStatusMap[pageId] = value - }) return () => { focusSubscription() blurSubscription() - unWatchAppFocusedState() del(pageStatusMap, pageId) } }, [navigation]) @@ -442,7 +438,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { useEffect(() => { if (type === 'page') { - if (!global.__mpxAppLaunched && global.__mpxAppOnLaunch) { + if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) { global.__mpxAppOnLaunch(props.navigation) } proxy.callHook(ONLOAD, [props.route.params || {}]) From 53b8e0850298f5f5e7b69d69785eca2196743a78 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Wed, 8 Jan 2025 17:16:19 +0800 Subject: [PATCH 5/8] fix web app provide --- packages/core/src/platform/createApp.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index e953d40b86..f3e847cb61 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -36,6 +36,10 @@ export default function createApp (options, config = {}) { }] if (__mpx_mode__ === 'web') { builtInMixins.push({ + beforeCreate () { + // for vue provide vm access + Object.assign(this, appData) + }, created () { const current = this.$root.$options?.router?.currentRoute || {} const options = { From dc7c45e72c214a3fb1959d58d0848617d9fbcf7c Mon Sep 17 00:00:00 2001 From: lareinayanyu Date: Wed, 8 Jan 2025 18:42:06 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/react/mpx-scroll-view.tsx | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx b/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx index d8a88cd881..918a0cfb59 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx +++ b/packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx @@ -160,6 +160,8 @@ const _ScrollView = forwardRef, S }) const scrollEventThrottle = 50 + const hasCallScrollToUpper = useRef(true) + const hasCallScrollToLower = useRef(false) const initialTimeout = useRef | null>(null) const intersectionObservers = useContext(IntersectionObserverContext) @@ -252,14 +254,19 @@ const _ScrollView = forwardRef, S const { bindscrolltoupper } = props const { offset } = scrollOptions.current if (bindscrolltoupper && (offset <= upperThreshold)) { - bindscrolltoupper( - getCustomEvent('scrolltoupper', e, { - detail: { - direction: scrollX ? 'left' : 'top' - }, - layoutRef - }, props) - ) + if (!hasCallScrollToUpper.current) { + bindscrolltoupper( + getCustomEvent('scrolltoupper', e, { + detail: { + direction: scrollX ? 'left' : 'top' + }, + layoutRef + }, props) + ) + hasCallScrollToUpper.current = true + } + } else { + hasCallScrollToUpper.current = false } } @@ -268,14 +275,19 @@ const _ScrollView = forwardRef, S const { contentLength, visibleLength, offset } = scrollOptions.current const distanceFromEnd = contentLength - visibleLength - offset if (bindscrolltolower && (distanceFromEnd < lowerThreshold)) { - bindscrolltolower( - getCustomEvent('scrolltolower', e, { - detail: { - direction: scrollX ? 'right' : 'botttom' - }, - layoutRef - }, props) - ) + if (!hasCallScrollToLower.current) { + hasCallScrollToLower.current = true + bindscrolltolower( + getCustomEvent('scrolltolower', e, { + detail: { + direction: scrollX ? 'right' : 'botttom' + }, + layoutRef + }, props) + ) + } + } else { + hasCallScrollToLower.current = false } } @@ -320,6 +332,8 @@ const _ScrollView = forwardRef, S }, props) ) updateScrollOptions(e, { scrollLeft, scrollTop }) + onStartReached(e) + onEndReached(e) if (enableTriggerIntersectionObserver && intersectionObservers) { for (const key in intersectionObservers) { intersectionObservers[key].throttleMeasure() From 82958d9129d07aabaab3a864bb78913860f6a828 Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Thu, 9 Jan 2025 11:53:25 +0800 Subject: [PATCH 7/8] fix rn mpxAppHotLaunched --- packages/core/src/platform/createApp.ios.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index 64123508ec..2f67b58c17 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -85,11 +85,16 @@ export default function createApp (options) { global.__mpxAppLaunched = false global.__mpxAppHotLaunched = false global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => { + const firstRef = useRef(true) const initialRouteRef = useRef({ initialRouteName: firstPage, initialParams: {} }) - + if (firstRef.current) { + // 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行 + global.__mpxAppHotLaunched = false + firstRef.current = false + } if (!global.__mpxAppHotLaunched) { const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {} initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName From ae09262fa6b38caa288821e6698b17897a2289bf Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Thu, 9 Jan 2025 12:08:58 +0800 Subject: [PATCH 8/8] rn fix global.__mpxAppHotLaunched2 --- packages/core/src/platform/createApp.ios.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index 2f67b58c17..0ff35e24b5 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -171,8 +171,6 @@ export default function createApp (options) { return () => { changeSubscription && changeSubscription.remove() resizeSubScription && resizeSubScription.remove() - // 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行 - global.__mpxAppHotLaunched = false } }, [])