From 05a23f8ce899fcb9c9abd424cf1c28105f4adfad Mon Sep 17 00:00:00 2001 From: arlo Date: Tue, 26 Mar 2024 00:43:04 +0800 Subject: [PATCH] fix(kit): respect legacy devtools hook in nuxt app --- .../src/core/component/tree/walker.ts | 8 ++++++-- packages/devtools-kit/src/core/index.ts | 16 ++++++++++------ packages/devtools-kit/src/hook/index.ts | 2 +- packages/devtools-kit/src/plugins/component.ts | 15 ++++++++++++--- packages/shared/src/env.ts | 2 ++ 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/packages/devtools-kit/src/core/component/tree/walker.ts b/packages/devtools-kit/src/core/component/tree/walker.ts index b6cddf4e..6f0ce5de 100644 --- a/packages/devtools-kit/src/core/component/tree/walker.ts +++ b/packages/devtools-kit/src/core/component/tree/walker.ts @@ -2,7 +2,7 @@ import type { SuspenseBoundary, VNode } from 'vue' import type { VueAppInstance } from '../../../types' import type { ComponentTreeNode } from '../types' import { getAppRecord, getInstanceName, getRenderKey, getUniqueComponentId, isBeingDestroyed, isFragment } from '../utils' -import { devtoolsContext } from '../../../state' +import { devtoolsAppRecords, devtoolsContext } from '../../../state' import { getRootElementsFromComponentInstance } from './el' import type { ComponentFilter } from './filter' import { createComponentFilter } from './filter' @@ -241,8 +241,12 @@ export class ComponentWalker { */ private mark(instance: VueAppInstance, force = false) { const instanceMap = getAppRecord(instance)!.instanceMap - if (force || !instanceMap.has(instance.__VUE_DEVTOOLS_UID__)) + if (force || !instanceMap.has(instance.__VUE_DEVTOOLS_UID__)) { instanceMap.set(instance.__VUE_DEVTOOLS_UID__, instance) + + // force sync appRecord instanceMap + devtoolsAppRecords.active.instanceMap = instanceMap + } } private isKeepAlive(instance: VueAppInstance) { diff --git a/packages/devtools-kit/src/core/index.ts b/packages/devtools-kit/src/core/index.ts index fe829ddc..7e0d9323 100644 --- a/packages/devtools-kit/src/core/index.ts +++ b/packages/devtools-kit/src/core/index.ts @@ -1,4 +1,4 @@ -import { target } from '@vue/devtools-shared' +import { isNuxtApp, target } from '@vue/devtools-shared' import { createDevToolsHook, devtoolsHooks, hook, subscribeDevToolsHook } from '../hook' import { DevToolsHooks } from '../types' import { devtoolsAppRecords, devtoolsState, getDevToolsEnv } from '../state' @@ -14,12 +14,16 @@ export function initDevTools() { if (target.__VUE_DEVTOOLS_GLOBAL_HOOK__ && isDevToolsNext) return - // compatible with old devtools - if (target.__VUE_DEVTOOLS_GLOBAL_HOOK__) - Object.assign(__VUE_DEVTOOLS_GLOBAL_HOOK__, createDevToolsHook()) - - else + if (!target.__VUE_DEVTOOLS_GLOBAL_HOOK__) { target.__VUE_DEVTOOLS_GLOBAL_HOOK__ = createDevToolsHook() + } + else { + // respect old devtools hook in nuxt application + if (!isNuxtApp) { + // override devtools hook directly + Object.assign(__VUE_DEVTOOLS_GLOBAL_HOOK__, createDevToolsHook()) + } + } // setup old devtools plugin (compatible with pinia, router, etc) hook.on.setupDevtoolsPlugin((pluginDescriptor, setupFn) => { diff --git a/packages/devtools-kit/src/hook/index.ts b/packages/devtools-kit/src/hook/index.ts index c42f113d..a9079589 100644 --- a/packages/devtools-kit/src/hook/index.ts +++ b/packages/devtools-kit/src/hook/index.ts @@ -33,7 +33,7 @@ export function createDevToolsHook(): DevToolsHook { id: 'vue-devtools-next', enabled: false, appRecords: [], - apps: {}, + apps: [], events: new Map(), on(event, fn) { if (!this.events.has(event)) diff --git a/packages/devtools-kit/src/plugins/component.ts b/packages/devtools-kit/src/plugins/component.ts index 6f7f4057..901decc9 100644 --- a/packages/devtools-kit/src/plugins/component.ts +++ b/packages/devtools-kit/src/plugins/component.ts @@ -1,7 +1,7 @@ import { debounce } from 'perfect-debounce' import { VueAppInstance } from '../types' import { DevToolsEvents, apiHooks, setupDevToolsPlugin } from '../api' -import { devtoolsContext, devtoolsState } from '../state' +import { devtoolsAppRecords, devtoolsContext, devtoolsState } from '../state' import { hook } from '../hook' import { getAppRecord, getComponentId, getComponentInstance } from '../core/component/utils' import { getComponentBoundingRect } from '../core/component/state/bounding-rect' @@ -116,8 +116,11 @@ export function registerComponentDevToolsPlugin(app: VueAppInstance) { if (component.__VUE_DEVTOOLS_UID__ == null) component.__VUE_DEVTOOLS_UID__ = id - if (!appRecord?.instanceMap.has(id)) + if (!appRecord?.instanceMap.has(id)) { appRecord?.instanceMap.set(id, component) + // force sync appRecord instanceMap + devtoolsAppRecords.active.instanceMap = appRecord!.instanceMap + } } if (!appRecord) @@ -147,8 +150,11 @@ export function registerComponentDevToolsPlugin(app: VueAppInstance) { if (component.__VUE_DEVTOOLS_UID__ == null) component.__VUE_DEVTOOLS_UID__ = id - if (!appRecord?.instanceMap.has(id)) + if (!appRecord?.instanceMap.has(id)) { + // force sync appRecord instanceMap appRecord?.instanceMap.set(id, component) + devtoolsAppRecords.active.instanceMap = appRecord!.instanceMap + } } if (!appRecord) @@ -177,7 +183,10 @@ export function registerComponentDevToolsPlugin(app: VueAppInstance) { uid, instance: component, }) as string + appRecord?.instanceMap.delete(id) + // force sync appRecord instanceMap + devtoolsAppRecords.active.instanceMap = appRecord.instanceMap debounceSendInspectorTree() }) diff --git a/packages/shared/src/env.ts b/packages/shared/src/env.ts index 7a01ea1c..62dae47d 100644 --- a/packages/shared/src/env.ts +++ b/packages/shared/src/env.ts @@ -12,3 +12,5 @@ export const target = (typeof globalThis !== 'undefined' export const isInChromePanel = typeof target.chrome !== 'undefined' && !!target.chrome.devtools export const isInIframe = isBrowser && target.self !== target.top export const isInElectron = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().includes('electron') +// @ts-expect-error skip type check +export const isNuxtApp = typeof window !== 'undefined' && !!window.__NUXT__