wip: make singleton mutations affect all app instances

This commit is contained in:
Evan You
2021-05-05 17:56:09 -04:00
parent 61edb700d7
commit f2a5a3ee55
5 changed files with 107 additions and 56 deletions

View File

@@ -15,7 +15,7 @@ import { RootHydrateFunction } from './hydration'
import { devtoolsInitApp, devtoolsUnmountApp } from './devtools'
import { isFunction, NO, isObject } from '@vue/shared'
import { version } from '.'
import { installCompatMount } from './compat/global'
import { applySingletonAppMutations, installCompatMount } from './compat/global'
import { installLegacyConfigProperties } from './compat/globalConfig'
import { installGlobalFilterMethod } from './compat/filter'
@@ -331,6 +331,7 @@ export function createAppAPI<HostElement>(
installCompatMount(app, context, render, hydrate)
installGlobalFilterMethod(app, context)
if (__DEV__) installLegacyConfigProperties(app.config)
applySingletonAppMutations(app)
}
return app

View File

@@ -115,15 +115,22 @@ export type CompatVue = Pick<App, 'version' | 'component' | 'directive'> & {
export let isCopyingConfig = false
// exported only for test
export let singletonApp: App
let singletonCtor: Function
// Legacy global Vue constructor
export function createCompatVue(
createApp: CreateAppFunction<Element>
createApp: CreateAppFunction<Element>,
createSingletonApp: CreateAppFunction<Element>
): CompatVue {
const Vue: CompatVue = function Vue(options: ComponentOptions = {}) {
return createCompatApp(options, Vue)
} as any
singletonApp = createSingletonApp({})
const singletonApp = createApp({})
const Vue: CompatVue = (singletonCtor = function Vue(
options: ComponentOptions = {}
) {
return createCompatApp(options, Vue)
} as any)
function createCompatApp(options: ComponentOptions = {}, Ctor: any) {
assertCompatEnabled(DeprecationTypes.GLOBAL_MOUNT, null)
@@ -139,53 +146,8 @@ export function createCompatVue(
const app = createApp(options)
// copy over asset registries and deopt flag
;['mixins', 'components', 'directives', 'filters', 'deopt'].forEach(key => {
// @ts-ignore
app._context[key] = singletonApp._context[key]
})
// copy over global config mutations
isCopyingConfig = true
for (const key in singletonApp.config) {
if (key === 'isNativeTag') continue
if (
isRuntimeOnly() &&
(key === 'isCustomElement' || key === 'compilerOptions')
) {
continue
}
const val = singletonApp.config[key as keyof AppConfig]
// @ts-ignore
app.config[key] = val
// compat for runtime ignoredElements -> isCustomElement
if (
key === 'ignoredElements' &&
isCompatEnabled(DeprecationTypes.CONFIG_IGNORED_ELEMENTS, null) &&
!isRuntimeOnly() &&
isArray(val)
) {
app.config.compilerOptions.isCustomElement = tag => {
return val.some(v => (isString(v) ? v === tag : v.test(tag)))
}
}
}
isCopyingConfig = false
// copy prototype augmentations as config.globalProperties
if (isCompatEnabled(DeprecationTypes.GLOBAL_PROTOTYPE, null)) {
app.config.globalProperties = Ctor.prototype
}
let hasPrototypeAugmentations = false
for (const key in Ctor.prototype) {
if (key !== 'constructor') {
hasPrototypeAugmentations = true
break
}
}
if (__DEV__ && hasPrototypeAugmentations) {
warnDeprecation(DeprecationTypes.GLOBAL_PROTOTYPE, null)
if (Ctor !== Vue) {
applySingletonPrototype(app, Ctor)
}
const vm = app._createRoot!(options)
@@ -348,6 +310,66 @@ export function createCompatVue(
return Vue
}
export function applySingletonAppMutations(app: App, Ctor?: Function) {
if (!singletonApp) {
// this is the call of creating the singleton itself
return
}
// copy over asset registries and deopt flag
;['mixins', 'components', 'directives', 'filters', 'deopt'].forEach(key => {
// @ts-ignore
app._context[key] = singletonApp._context[key]
})
// copy over global config mutations
isCopyingConfig = true
for (const key in singletonApp.config) {
if (key === 'isNativeTag') continue
if (
isRuntimeOnly() &&
(key === 'isCustomElement' || key === 'compilerOptions')
) {
continue
}
const val = singletonApp.config[key as keyof AppConfig]
// @ts-ignore
app.config[key] = val
// compat for runtime ignoredElements -> isCustomElement
if (
key === 'ignoredElements' &&
isCompatEnabled(DeprecationTypes.CONFIG_IGNORED_ELEMENTS, null) &&
!isRuntimeOnly() &&
isArray(val)
) {
app.config.compilerOptions.isCustomElement = tag => {
return val.some(v => (isString(v) ? v === tag : v.test(tag)))
}
}
}
isCopyingConfig = false
applySingletonPrototype(app, singletonCtor)
}
function applySingletonPrototype(app: App, Ctor: Function) {
// copy prototype augmentations as config.globalProperties
if (isCompatEnabled(DeprecationTypes.GLOBAL_PROTOTYPE, null)) {
app.config.globalProperties = Ctor.prototype
}
let hasPrototypeAugmentations = false
for (const key in Ctor.prototype) {
if (key !== 'constructor') {
hasPrototypeAugmentations = true
break
}
}
if (__DEV__ && hasPrototypeAugmentations) {
warnDeprecation(DeprecationTypes.GLOBAL_PROTOTYPE, null)
}
}
export function installCompatMount(
app: App,
context: AppContext,