fix(devtools): fix prod devtools detection + handle late devtools hook injection (#4653)

This commit is contained in:
Evan You 2021-09-22 09:07:08 -04:00 committed by GitHub
parent 64aa8e26ae
commit 2476eaad6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 24 deletions

View 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

View 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,

View File

@ -340,10 +340,10 @@ function baseCreateRenderer(
initFeatureFlags()
}
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
const target = getGlobalThis()
target.__VUE__ = true
setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__)
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target)
}
const {

View 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')

View 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']