From 07444b3266764cc4d5f7d2378069dfc91135835c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Fri, 21 Jun 2024 14:03:11 +0800 Subject: [PATCH] feat(runtime-vapor): try to support devtools --- .../runtime-vapor/src/apiCreateVaporApp.ts | 34 ++++++++++++++++--- packages/runtime-vapor/src/apiRender.ts | 7 +++- packages/runtime-vapor/src/component.ts | 7 ++-- packages/runtime-vapor/src/componentAttrs.ts | 4 +-- .../src/helpers/resolveAssets.ts | 2 +- packages/runtime-vapor/src/index.ts | 14 ++++++++ packages/runtime-vapor/src/profiling.ts | 2 +- packages/runtime-vapor/src/warning.ts | 8 ++--- 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/packages/runtime-vapor/src/apiCreateVaporApp.ts b/packages/runtime-vapor/src/apiCreateVaporApp.ts index f89ca4641..c4d547de2 100644 --- a/packages/runtime-vapor/src/apiCreateVaporApp.ts +++ b/packages/runtime-vapor/src/apiCreateVaporApp.ts @@ -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(key: string | InjectionKey, value: T): App runWithContext(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 /** diff --git a/packages/runtime-vapor/src/apiRender.ts b/packages/runtime-vapor/src/apiRender.ts index 702d3490b..086f18d63 100644 --- a/packages/runtime-vapor/src/apiRender.ts +++ b/packages/runtime-vapor/src/apiRender.ts @@ -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') } diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 799c11ca2..4c4b02a52 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -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 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) diff --git a/packages/runtime-vapor/src/componentAttrs.ts b/packages/runtime-vapor/src/componentAttrs.ts index a4c3202d2..7e82c1df7 100644 --- a/packages/runtime-vapor/src/componentAttrs.ts +++ b/packages/runtime-vapor/src/componentAttrs.ts @@ -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 diff --git a/packages/runtime-vapor/src/helpers/resolveAssets.ts b/packages/runtime-vapor/src/helpers/resolveAssets.ts index 5454de687..32c0dbb94 100644 --- a/packages/runtime-vapor/src/helpers/resolveAssets.ts +++ b/packages/runtime-vapor/src/helpers/resolveAssets.ts @@ -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) { diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index 60810713e..96f189b03 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -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 diff --git a/packages/runtime-vapor/src/profiling.ts b/packages/runtime-vapor/src/profiling.ts index 3caae0a67..f87b7f472 100644 --- a/packages/runtime-vapor/src/profiling.ts +++ b/packages/runtime-vapor/src/profiling.ts @@ -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, ) diff --git a/packages/runtime-vapor/src/warning.ts b/packages/runtime-vapor/src/warning.ts index 63ee30fed..d122da38b 100644 --- a/packages/runtime-vapor/src/warning.ts +++ b/packages/runtime-vapor/src/warning.ts @@ -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]