From d6c5bcf833bed68c5afef31a1e7aa406ee5143bf Mon Sep 17 00:00:00 2001 From: GaoNeng <31283122+GaoNeng-wWw@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:30:47 +0800 Subject: [PATCH] feat(runtime-core): implement debug hook (#183) --- .../__tests__/apiLifecycle.spec.ts | 45 +++++++++++++++++++ packages/runtime-vapor/src/apiLifecycle.ts | 14 +++++- packages/runtime-vapor/src/index.ts | 4 +- packages/runtime-vapor/src/renderEffect.ts | 10 ++++- playground/src/App.vue | 9 ++++ 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts b/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts index 535416fde..c4de0cc67 100644 --- a/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts +++ b/packages/runtime-vapor/__tests__/apiLifecycle.spec.ts @@ -6,6 +6,8 @@ import { getCurrentInstance, inject, nextTick, + onRenderTracked, + onRenderTriggered, onUpdated, provide, ref, @@ -112,4 +114,47 @@ describe('apiLifecycle', () => { expect(handleUpdated).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') + }) }) diff --git a/packages/runtime-vapor/src/apiLifecycle.ts b/packages/runtime-vapor/src/apiLifecycle.ts index 104841586..215eeb344 100644 --- a/packages/runtime-vapor/src/apiLifecycle.ts +++ b/packages/runtime-vapor/src/apiLifecycle.ts @@ -4,7 +4,11 @@ import { setCurrentInstance, } from './component' import { warn } from './warning' -import { pauseTracking, resetTracking } from '@vue/reactivity' +import { + type DebuggerEvent, + pauseTracking, + resetTracking, +} from '@vue/reactivity' import { ErrorTypeStrings, callWithAsyncErrorHandling } from './errorHandling' import { toHandlerKey } from '@vue/shared' @@ -77,6 +81,14 @@ export const onUpdated = createHook(VaporLifecycleHooks.UPDATED) export const onBeforeUnmount = createHook(VaporLifecycleHooks.BEFORE_UNMOUNT) export const onUnmounted = createHook(VaporLifecycleHooks.UNMOUNTED) +export type DebuggerHook = (e: DebuggerEvent) => void +export const onRenderTriggered = createHook( + VaporLifecycleHooks.RENDER_TRIGGERED, +) +export const onRenderTracked = createHook( + VaporLifecycleHooks.RENDER_TRACKED, +) + export type ErrorCapturedHook = ( err: TError, instance: ComponentInternalInstance | null, diff --git a/packages/runtime-vapor/src/index.ts b/packages/runtime-vapor/src/index.ts index 919e0c2c6..eba38d47e 100644 --- a/packages/runtime-vapor/src/index.ts +++ b/packages/runtime-vapor/src/index.ts @@ -106,8 +106,8 @@ export { onUnmounted, // onActivated, // onDeactivated, - // onRenderTracked, - // onRenderTriggered, + onRenderTracked, + onRenderTriggered, onErrorCaptured, // onServerPrefetch, } from './apiLifecycle' diff --git a/packages/runtime-vapor/src/renderEffect.ts b/packages/runtime-vapor/src/renderEffect.ts index 97cf5f73e..d4da8a63c 100644 --- a/packages/runtime-vapor/src/renderEffect.ts +++ b/packages/runtime-vapor/src/renderEffect.ts @@ -18,7 +18,6 @@ import { invokeDirectiveHook } from './directives' export function renderEffect(cb: () => void) { const instance = getCurrentInstance() const scope = getCurrentScope() - let effect: ReactiveEffect const job: SchedulerJob = () => { @@ -77,7 +76,14 @@ export function renderEffect(cb: () => void) { if (instance) job.id = instance.uid 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() } diff --git a/playground/src/App.vue b/playground/src/App.vue index c301688e3..a2cabc18b 100644 --- a/playground/src/App.vue +++ b/playground/src/App.vue @@ -7,6 +7,8 @@ import { getCurrentInstance, onBeforeUpdate, onUpdated, + onRenderTracked, + onRenderTriggered, } from 'vue/vapor' const instance = getCurrentInstance()! @@ -36,6 +38,13 @@ onUpdated(() => { console.log('updated') }) +onRenderTracked(e => { + console.log(`Render Tracked:`, e.target) +}) +onRenderTriggered(e => { + console.log(`Render trigger:`, e.target) +}) + const log = (arg: any) => { console.log('callback in render effect') return arg