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)] return [createVNode('div', null, 'foo', PatchFlags.TEXT)]
}, },
// mock instance // mock instance
{ type: {} } as any { type: {}, appContext: {} } as any
) as Slot ) as Slot
// manual invocation should not track // manual invocation should not track

View File

@ -21,6 +21,7 @@ const enum DevtoolsHooks {
} }
interface DevtoolsHook { interface DevtoolsHook {
enabled?: boolean
emit: (event: string, ...payload: any[]) => void emit: (event: string, ...payload: any[]) => void
on: (event: string, handler: Function) => void on: (event: string, handler: Function) => void
once: (event: string, handler: Function) => void once: (event: string, handler: Function) => void
@ -30,14 +31,33 @@ interface DevtoolsHook {
export let devtools: 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 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) { export function devtoolsInitApp(app: App, version: string) {
// TODO queue if devtools is undefined emit(DevtoolsHooks.APP_INIT, app, version, {
if (!devtools) return
devtools.emit(DevtoolsHooks.APP_INIT, app, version, {
Fragment, Fragment,
Text, Text,
Comment, Comment,
@ -46,8 +66,7 @@ export function devtoolsInitApp(app: App, version: string) {
} }
export function devtoolsUnmountApp(app: App) { export function devtoolsUnmountApp(app: App) {
if (!devtools) return emit(DevtoolsHooks.APP_UNMOUNT, app)
devtools.emit(DevtoolsHooks.APP_UNMOUNT, app)
} }
export const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook( export const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook(
@ -62,8 +81,7 @@ export const devtoolsComponentRemoved =
function createDevtoolsComponentHook(hook: DevtoolsHooks) { function createDevtoolsComponentHook(hook: DevtoolsHooks) {
return (component: ComponentInternalInstance) => { return (component: ComponentInternalInstance) => {
if (!devtools) return emit(
devtools.emit(
hook, hook,
component.appContext.app, component.appContext.app,
component.uid, component.uid,
@ -83,15 +101,7 @@ export const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook(
function createDevtoolsPerformanceHook(hook: DevtoolsHooks) { function createDevtoolsPerformanceHook(hook: DevtoolsHooks) {
return (component: ComponentInternalInstance, type: string, time: number) => { return (component: ComponentInternalInstance, type: string, time: number) => {
if (!devtools) return emit(hook, component.appContext.app, component.uid, component, type, time)
devtools.emit(
hook,
component.appContext.app,
component.uid,
component,
type,
time
)
} }
} }
@ -100,8 +110,7 @@ export function devtoolsComponentEmit(
event: string, event: string,
params: any[] params: any[]
) { ) {
if (!devtools) return emit(
devtools.emit(
DevtoolsHooks.COMPONENT_EMIT, DevtoolsHooks.COMPONENT_EMIT,
component.appContext.app, component.appContext.app,
component, component,

View File

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

View File

@ -2,4 +2,9 @@ import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import '@vue/repl/style.css' import '@vue/repl/style.css'
// @ts-expect-error Custom window property
window.VUE_DEVTOOLS_CONFIG = {
defaultSelectedAppId: 'id:repl'
}
createApp(App).mount('#app') 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({ export default defineConfig({
plugins: [vue(), copyVuePlugin()], plugins: [vue(), copyVuePlugin()],
define: { define: {
__COMMIT__: JSON.stringify(commit) __COMMIT__: JSON.stringify(commit),
__VUE_PROD_DEVTOOLS__: JSON.stringify(true)
}, },
optimizeDeps: { optimizeDeps: {
exclude: ['@vue/repl'] exclude: ['@vue/repl']