feat(runtime-core): implement debug hook (#183)

This commit is contained in:
GaoNeng 2024-04-21 20:30:47 +08:00 committed by GitHub
parent d490bf2ed7
commit d6c5bcf833
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 77 additions and 5 deletions

View File

@ -6,6 +6,8 @@ import {
getCurrentInstance, getCurrentInstance,
inject, inject,
nextTick, nextTick,
onRenderTracked,
onRenderTriggered,
onUpdated, onUpdated,
provide, provide,
ref, ref,
@ -112,4 +114,47 @@ describe('apiLifecycle', () => {
expect(handleUpdated).toHaveBeenCalledTimes(1) expect(handleUpdated).toHaveBeenCalledTimes(1)
expect(handleUpdatedChild).toHaveBeenCalledTimes(1) expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
}) })
test('onRenderTracked', async () => {
const onTrackedFn = vi.fn()
const count = ref(0)
const { host, render } = define({
setup() {
onRenderTracked(onTrackedFn)
return (() => {
const n0 = createTextNode()
renderEffect(() => {
setText(n0, count.value)
})
return n0
})()
},
})
render()
await nextTick()
expect(onTrackedFn).toBeCalled()
expect(host.innerHTML).toBe('0')
})
test('onRenderTrigger', async () => {
const onRenderTriggerFn = vi.fn()
const count = ref(0)
const { host, render } = define({
setup() {
onRenderTriggered(onRenderTriggerFn)
return (() => {
const n0 = createTextNode()
renderEffect(() => {
setText(n0, count.value)
})
return n0
})()
},
})
render()
count.value++
await nextTick()
expect(onRenderTriggerFn).toBeCalled()
expect(onRenderTriggerFn).toHaveBeenCalledOnce()
expect(host.innerHTML).toBe('1')
})
}) })

View File

@ -4,7 +4,11 @@ import {
setCurrentInstance, setCurrentInstance,
} from './component' } from './component'
import { warn } from './warning' import { warn } from './warning'
import { pauseTracking, resetTracking } from '@vue/reactivity' import {
type DebuggerEvent,
pauseTracking,
resetTracking,
} from '@vue/reactivity'
import { ErrorTypeStrings, callWithAsyncErrorHandling } from './errorHandling' import { ErrorTypeStrings, callWithAsyncErrorHandling } from './errorHandling'
import { toHandlerKey } from '@vue/shared' import { toHandlerKey } from '@vue/shared'
@ -77,6 +81,14 @@ export const onUpdated = createHook(VaporLifecycleHooks.UPDATED)
export const onBeforeUnmount = createHook(VaporLifecycleHooks.BEFORE_UNMOUNT) export const onBeforeUnmount = createHook(VaporLifecycleHooks.BEFORE_UNMOUNT)
export const onUnmounted = createHook(VaporLifecycleHooks.UNMOUNTED) export const onUnmounted = createHook(VaporLifecycleHooks.UNMOUNTED)
export type DebuggerHook = (e: DebuggerEvent) => void
export const onRenderTriggered = createHook<DebuggerHook>(
VaporLifecycleHooks.RENDER_TRIGGERED,
)
export const onRenderTracked = createHook<DebuggerHook>(
VaporLifecycleHooks.RENDER_TRACKED,
)
export type ErrorCapturedHook<TError = unknown> = ( export type ErrorCapturedHook<TError = unknown> = (
err: TError, err: TError,
instance: ComponentInternalInstance | null, instance: ComponentInternalInstance | null,

View File

@ -106,8 +106,8 @@ export {
onUnmounted, onUnmounted,
// onActivated, // onActivated,
// onDeactivated, // onDeactivated,
// onRenderTracked, onRenderTracked,
// onRenderTriggered, onRenderTriggered,
onErrorCaptured, onErrorCaptured,
// onServerPrefetch, // onServerPrefetch,
} from './apiLifecycle' } from './apiLifecycle'

View File

@ -18,7 +18,6 @@ import { invokeDirectiveHook } from './directives'
export function renderEffect(cb: () => void) { export function renderEffect(cb: () => void) {
const instance = getCurrentInstance() const instance = getCurrentInstance()
const scope = getCurrentScope() const scope = getCurrentScope()
let effect: ReactiveEffect let effect: ReactiveEffect
const job: SchedulerJob = () => { const job: SchedulerJob = () => {
@ -77,7 +76,14 @@ export function renderEffect(cb: () => void) {
if (instance) job.id = instance.uid if (instance) job.id = instance.uid
queueJob(job) queueJob(job)
} }
if (__DEV__) {
effect.onTrack = instance?.rtc
? e => invokeArrayFns(instance.rtc!, e)
: void 0
effect.onTrigger = instance?.rtg
? e => invokeArrayFns(instance.rtg!, e)
: void 0
}
effect.run() effect.run()
} }

View File

@ -7,6 +7,8 @@ import {
getCurrentInstance, getCurrentInstance,
onBeforeUpdate, onBeforeUpdate,
onUpdated, onUpdated,
onRenderTracked,
onRenderTriggered,
} from 'vue/vapor' } from 'vue/vapor'
const instance = getCurrentInstance()! const instance = getCurrentInstance()!
@ -36,6 +38,13 @@ onUpdated(() => {
console.log('updated') console.log('updated')
}) })
onRenderTracked(e => {
console.log(`Render Tracked:`, e.target)
})
onRenderTriggered(e => {
console.log(`Render trigger:`, e.target)
})
const log = (arg: any) => { const log = (arg: any) => {
console.log('callback in render effect') console.log('callback in render effect')
return arg return arg