Skip to content

Commit

Permalink
Merge branch 'master' into feat-mp-parent-reference
Browse files Browse the repository at this point in the history
  • Loading branch information
wangshunnn committed Jan 8, 2025
2 parents c042a1e + 53b8e08 commit 46f0ca0
Show file tree
Hide file tree
Showing 32 changed files with 433 additions and 344 deletions.
15 changes: 9 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ module.exports = {
sourceType: 'module'
},
extends: 'standard',
plugins: [
'html',
'jest'
],
plugins: ['html', 'jest'],
globals: {
wx: 'readonly',
my: 'readonly',
Expand Down Expand Up @@ -45,7 +42,7 @@ module.exports = {
extends: [
'standard',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended'
],
plugins: ['@typescript-eslint'],
rules: {
Expand All @@ -56,7 +53,13 @@ module.exports = {
'@typescript-eslint/no-empty-interface': 0,
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/no-non-null-assertion': 0,
camelcase: 0,
camelcase: 0
}
}, {
files: ['packages/webpack-plugin/lib/runtime/components/react/**/*.{js,jsx,ts,tsx}'],
plugins: ['react-hooks'],
rules: {
'react-hooks/rules-of-hooks': 'error'
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "2.9.69"
"version": "2.9.70"
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"eslint-plugin-jest": "^27.0.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-react-hooks": "^5.1.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^27.2.0",
"lerna": "^8.1.8",
Expand Down
4 changes: 2 additions & 2 deletions packages/api-proxy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mpxjs/api-proxy",
"version": "2.9.69",
"version": "2.9.70",
"description": "convert miniprogram API at each end",
"module": "src/index.js",
"types": "@types/index.d.ts",
Expand Down Expand Up @@ -37,7 +37,7 @@
},
"homepage": "https://github.com/didi/mpx#readme",
"dependencies": {
"@mpxjs/utils": "^2.9.69",
"@mpxjs/utils": "^2.9.70",
"axios": "^1.7.3"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/api-proxy/src/platform/api/system/index.web.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const getLaunchOptionsSync = function () {
throwSSRWarning('getLaunchOptionsSync API is running in non browser environments')
return
}
return global.__mpxEnterOptions || {}
return global.__mpxLaunchOptions || {}
}

export {
Expand Down
11 changes: 2 additions & 9 deletions packages/api-proxy/src/platform/api/system/rnSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mpxjs/core",
"version": "2.9.69",
"version": "2.9.70",
"description": "mpx runtime core",
"keywords": [
"miniprogram",
Expand All @@ -19,7 +19,7 @@
],
"main": "src/index.js",
"dependencies": {
"@mpxjs/utils": "^2.9.69",
"@mpxjs/utils": "^2.9.70",
"lodash": "^4.1.1",
"miniprogram-api-typings": "^3.10.0"
},
Expand All @@ -30,9 +30,9 @@
"@mpxjs/store": "^2.9.0",
"@react-navigation/native": "^7.0.3",
"@react-navigation/stack": "^7.0.4",
"promise": "^8.3.0",
"react": "*",
"react-native": "*",
"promise": "^8.3.0",
"react-native-gesture-handler": "^2.19.0",
"react-native-linear-gradient": "^2.8.3",
"react-native-safe-area-context": "^4.14.0",
Expand Down Expand Up @@ -110,4 +110,4 @@
},
"sideEffects": false,
"gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export default function styleHelperMixin () {
} else if (appClassMap[className]) {
// todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
Object.assign(result, appClassMap[className])
} else if (this.__props[className] && isObject(this.__props[className])) {
} else if (isObject(this.__props[className])) {
// externalClasses必定以对象形式传递下来
Object.assign(result, this.__props[className])
}
Expand Down
60 changes: 25 additions & 35 deletions packages/core/src/platform/createApp.ios.js
Original file line number Diff line number Diff line change
@@ -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)

Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -177,13 +166,14 @@ export default function createApp (option, config = {}) {
return () => {
changeSubscription && changeSubscription.remove()
resizeSubScription && resizeSubScription.remove()
// 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行
global.__mpxAppHotLaunched = false
}
}, [])

const { initialRouteName, initialParams } = initialRouteRef.current
const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null
const navScreenOpts = {
gestureEnabled: true,
// 7.x替换headerBackTitleVisible
// headerBackButtonDisplayMode: 'minimal',
headerBackTitleVisible: false,
Expand Down
51 changes: 24 additions & 27 deletions packages/core/src/platform/createApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ 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)
beforeCreate () {
// for vue provide vm access
Object.assign(this, appData)
},
created () {
const current = this.$root.$options?.router?.currentRoute || {}
const options = {
path: current.path && current.path.replace(/^\//, ''),
Expand All @@ -45,48 +49,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)
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/platform/export/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { currentInstance } from '../../core/proxy'
let appProvides = Object.create(null)

/** @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)) {
appProvides = provided
Expand Down
Loading

0 comments on commit 46f0ca0

Please sign in to comment.