feat(runtime-vapor): try to support devtools

This commit is contained in:
三咲智子 Kevin Deng 2024-06-21 14:03:11 +08:00
parent 7d90c887c0
commit 07444b3266
No known key found for this signature in database
8 changed files with 60 additions and 18 deletions

View File

@ -1,4 +1,4 @@
import { NO, isFunction, isObject } from '@vue/shared'
import { NO, getGlobalThis, isFunction, isObject } from '@vue/shared'
import {
type Component,
type ComponentInternalInstance,
@ -16,7 +16,9 @@ import {
import type { InjectionKey } from './apiInject'
import type { RawProps } from './componentProps'
import { validateDirectiveName } from './directives'
import { devtoolsInitApp, setDevtoolsHook } from './devtools'
let uid = 0
export function createVaporApp(
rootComponent: Component,
rootProps: RawProps | null = null,
@ -27,14 +29,24 @@ export function createVaporApp(
rootProps = null
}
const target = getGlobalThis()
target.__VUE__ = true
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target)
}
const context = createAppContext()
const installedPlugins = new WeakSet()
let instance: ComponentInternalInstance
const app: App = {
_context: context,
const app: App = (context.app = {
_uid: uid++,
_component: rootComponent,
_props: rootProps,
_container: null,
_context: context,
_instance: null,
version,
@ -122,6 +134,11 @@ export function createVaporApp(
// for devtools and telemetry
;(rootContainer as any).__vue_app__ = app
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
app._instance = instance
devtoolsInitApp(app, version)
}
return instance
} else if (__DEV__) {
warn(
@ -161,7 +178,7 @@ export function createVaporApp(
currentApp = lastApp
}
},
}
})
return app
}
@ -169,6 +186,7 @@ export function createVaporApp(
export function createAppContext(): AppContext {
return {
app: null as any,
mixins: [],
config: {
isNativeTag: NO,
performance: false,
@ -219,8 +237,13 @@ export interface App {
provide<T>(key: string | InjectionKey<T>, value: T): App
runWithContext<T>(fn: () => T): T
_context: AppContext
// internal, but we need to expose these for the server-renderer and devtools
_uid: number
_component: Component
_props: RawProps | null
_container: ParentNode | null
_context: AppContext
_instance: ComponentInternalInstance | null
}
export interface AppConfig {
@ -244,6 +267,7 @@ export interface AppConfig {
export interface AppContext {
app: App // for devtools
config: AppConfig
mixins: never[] // for devtools, but no longer supported
provides: Record<string | symbol, any>
/**

View File

@ -19,6 +19,7 @@ import { isArray, isFunction, isObject } from '@vue/shared'
import { fallThroughAttrs } from './componentAttrs'
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
import { endMeasure, startMeasure } from './profiling'
import { devtoolsComponentAdded } from './devtools'
export const fragmentKey = Symbol(__DEV__ ? `fragmentKey` : ``)
@ -38,7 +39,7 @@ export function setupComponent(
}
const reset = setCurrentInstance(instance)
instance.scope.run(() => {
const { component, props } = instance
const { type: component, props } = instance
if (__DEV__) {
if (component.name) {
@ -140,6 +141,10 @@ function mountComponent(
true,
)
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
devtoolsComponentAdded(instance)
}
if (__DEV__) {
endMeasure(instance, 'mount')
}

View File

@ -154,13 +154,14 @@ export interface ComponentInternalInstance {
vapor: true
appContext: AppContext
type: Component
block: Block | null
container: ParentNode
parent: ComponentInternalInstance | null
root: ComponentInternalInstance
provides: Data
scope: BlockEffectScope
component: Component
comps: Set<ComponentInternalInstance>
rawProps: NormalizedRawProps
@ -280,10 +281,11 @@ export function createComponentInstance(
container: null!,
parent,
root: null!, // set later
scope: null!,
provides: parent ? parent.provides : Object.create(_appContext.provides),
component,
type: component,
comps: new Set(),
// resolved props and emits options
@ -355,6 +357,7 @@ export function createComponentInstance(
*/
// [VaporLifecycleHooks.SERVER_PREFETCH]: null,
}
instance.root = parent ? parent.root : instance
instance.scope = new BlockEffectScope(instance, parent && parent.scope)
initProps(instance, rawProps, !isFunction(component), once)
initSlots(instance, slots)

View File

@ -55,7 +55,7 @@ export function patchAttrs(instance: ComponentInternalInstance) {
export function withAttrs(props: RawProps): RawProps {
const instance = currentInstance!
if (instance.component.inheritAttrs === false) return props
if (instance.type.inheritAttrs === false) return props
const attrsGetter = () => instance.attrs
if (!props) return [attrsGetter]
if (isArray(props)) {
@ -67,7 +67,7 @@ export function withAttrs(props: RawProps): RawProps {
export function fallThroughAttrs(instance: ComponentInternalInstance) {
const {
block,
component: { inheritAttrs },
type: { inheritAttrs },
} = instance
if (inheritAttrs === false) return

View File

@ -40,7 +40,7 @@ function resolveAsset(
) {
const instance = currentInstance
if (instance) {
const Component = instance.component
const Component = instance.type
// explicit self name has highest priority
if (type === COMPONENTS) {

View File

@ -146,3 +146,17 @@ export {
vModelDynamic,
} from './directives/vModel'
export { vShow } from './directives/vShow'
// For devtools
import {
type DevtoolsHook,
devtools as _devtools,
setDevtoolsHook as _setDevtoolsHook,
} from './devtools'
export const devtools = (
__DEV__ || __ESM_BUNDLER__ ? _devtools : undefined
) as DevtoolsHook
export const setDevtoolsHook = (
__DEV__ || __ESM_BUNDLER__ ? _setDevtoolsHook : NOOP
) as typeof _setDevtoolsHook

View File

@ -27,7 +27,7 @@ export function endMeasure(instance: ComponentInternalInstance, type: string) {
const endTag = startTag + `:end`
perf.mark(endTag)
perf.measure(
`<${formatComponentName(instance, instance.component)}> ${type}`,
`<${formatComponentName(instance, instance.type)}> ${type}`,
startTag,
endTag,
)

View File

@ -38,7 +38,7 @@ export function warn(msg: string, ...args: any[]) {
trace
.map(
({ instance }) =>
`at <${formatComponentName(instance, instance.component)}>`,
`at <${formatComponentName(instance, instance.type)}>`,
)
.join('\n'),
trace,
@ -97,11 +97,7 @@ function formatTraceEntry({ instance, recurseCount }: TraceEntry): any[] {
const postfix =
recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``
const isRoot = instance ? instance.parent == null : false
const open = ` at <${formatComponentName(
instance,
instance.component,
isRoot,
)}`
const open = ` at <${formatComponentName(instance, instance.type, isRoot)}`
const close = `>` + postfix
return instance.rawProps.length
? [open, ...formatProps(instance.rawProps), close]