]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(devtools): fix prod devtools detection + handle late devtools hook injection...
authorEvan You <yyx990803@gmail.com>
Wed, 22 Sep 2021 13:07:08 +0000 (09:07 -0400)
committerGitHub <noreply@github.com>
Wed, 22 Sep 2021 13:07:08 +0000 (09:07 -0400)
packages/runtime-core/__tests__/helpers/renderSlot.spec.ts
packages/runtime-core/src/devtools.ts
packages/runtime-core/src/renderer.ts
packages/sfc-playground/src/main.ts
packages/sfc-playground/vite.config.ts

index 9af91ce1c0398981cdef6e933cd7f8a198c66d31..4e661c406e634cfa9f298b0f88a6410f5a447c3b 100644 (file)
@@ -47,7 +47,7 @@ describe('renderSlot', () => {
         return [createVNode('div', null, 'foo', PatchFlags.TEXT)]
       },
       // mock instance
-      { type: {} } as any
+      { type: {}, appContext: {} } as any
     ) as Slot
 
     // manual invocation should not track
index 4c52388524e5248866863069bab6dfbf63351d4d..b26fae85d06fa67cde7b66725d67f6cc07dae109 100644 (file)
@@ -21,6 +21,7 @@ const enum DevtoolsHooks {
 }
 
 interface DevtoolsHook {
+  enabled?: boolean
   emit: (event: string, ...payload: any[]) => void
   on: (event: string, handler: Function) => void
   once: (event: string, handler: Function) => void
@@ -30,14 +31,33 @@ interface DevtoolsHook {
 
 export let devtools: DevtoolsHook
 
-export function setDevtoolsHook(hook: DevtoolsHook) {
+let buffer: { event: string; args: any[] }[] = []
+
+function emit(event: string, ...args: any[]) {
+  if (devtools) {
+    devtools.emit(event, ...args)
+  } else {
+    buffer.push({ event, args })
+  }
+}
+
+export function setDevtoolsHook(hook: DevtoolsHook, target: any) {
   devtools = hook
+  if (devtools) {
+    devtools.enabled = true
+    buffer.forEach(({ event, args }) => devtools.emit(event, ...args))
+    buffer = []
+  } else {
+    const replay = (target.__VUE_DEVTOOLS_HOOK_REPLAY__ =
+      target.__VUE_DEVTOOLS_HOOK_REPLAY__ || [])
+    replay.push((newHook: DevtoolsHook) => {
+      setDevtoolsHook(newHook, target)
+    })
+  }
 }
 
 export function devtoolsInitApp(app: App, version: string) {
-  // TODO queue if devtools is undefined
-  if (!devtools) return
-  devtools.emit(DevtoolsHooks.APP_INIT, app, version, {
+  emit(DevtoolsHooks.APP_INIT, app, version, {
     Fragment,
     Text,
     Comment,
@@ -46,8 +66,7 @@ export function devtoolsInitApp(app: App, version: string) {
 }
 
 export function devtoolsUnmountApp(app: App) {
-  if (!devtools) return
-  devtools.emit(DevtoolsHooks.APP_UNMOUNT, app)
+  emit(DevtoolsHooks.APP_UNMOUNT, app)
 }
 
 export const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook(
@@ -62,8 +81,7 @@ export const devtoolsComponentRemoved =
 
 function createDevtoolsComponentHook(hook: DevtoolsHooks) {
   return (component: ComponentInternalInstance) => {
-    if (!devtools) return
-    devtools.emit(
+    emit(
       hook,
       component.appContext.app,
       component.uid,
@@ -83,15 +101,7 @@ export const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook(
 
 function createDevtoolsPerformanceHook(hook: DevtoolsHooks) {
   return (component: ComponentInternalInstance, type: string, time: number) => {
-    if (!devtools) return
-    devtools.emit(
-      hook,
-      component.appContext.app,
-      component.uid,
-      component,
-      type,
-      time
-    )
+    emit(hook, component.appContext.app, component.uid, component, type, time)
   }
 }
 
@@ -100,8 +110,7 @@ export function devtoolsComponentEmit(
   event: string,
   params: any[]
 ) {
-  if (!devtools) return
-  devtools.emit(
+  emit(
     DevtoolsHooks.COMPONENT_EMIT,
     component.appContext.app,
     component,
index 76848cb52f3b0f54d98e7c187fdc73dfb8ba514b..e61e5421efc70c36db4ed2a81d1514d47c8e923b 100644 (file)
@@ -340,10 +340,10 @@ function baseCreateRenderer(
     initFeatureFlags()
   }
 
+  const target = getGlobalThis()
+  target.__VUE__ = true
   if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
-    const target = getGlobalThis()
-    target.__VUE__ = true
-    setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__)
+    setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target)
   }
 
   const {
index 1ef69e7d28fe6a5b2946eef4b8da732e64875f41..e645bb2bd0fad8e27481ffac9d14db9b68297951 100644 (file)
@@ -2,4 +2,9 @@ import { createApp } from 'vue'
 import App from './App.vue'
 import '@vue/repl/style.css'
 
+// @ts-expect-error Custom window property
+window.VUE_DEVTOOLS_CONFIG = {
+  defaultSelectedAppId: 'id:repl'
+}
+
 createApp(App).mount('#app')
index 8fdff8ee8a22ceae77332581ed2d4efe07dfd387..6e5cdc450f600523038deec13c1329fe13fd3b50 100644 (file)
@@ -9,7 +9,8 @@ const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7)
 export default defineConfig({
   plugins: [vue(), copyVuePlugin()],
   define: {
-    __COMMIT__: JSON.stringify(commit)
+    __COMMIT__: JSON.stringify(commit),
+    __VUE_PROD_DEVTOOLS__: JSON.stringify(true)
   },
   optimizeDeps: {
     exclude: ['@vue/repl']