From 221a8d30f292e1551d14852db559c324cf172db4 Mon Sep 17 00:00:00 2001 From: zhennann Date: Mon, 6 Jan 2025 11:06:48 +0800 Subject: [PATCH] feat: patch --- packages/compiler-sfc/package.json | 2 +- .../compiler-sfc/src/script/resolveType.ts | 2 +- packages/reactivity/package.json | 2 +- packages/reactivity/src/baseHandlers.ts | 6 +- packages/runtime-core/package.json | 2 +- .../runtime-core/src/apiAsyncComponent.ts | 14 ++++- packages/runtime-core/src/apiLifecycle.ts | 3 + packages/runtime-core/src/componentSlots.ts | 13 ++-- .../runtime-core/src/components/Teleport.ts | 4 +- packages/runtime-core/src/hmr.ts | 2 + packages/runtime-core/src/hydration.ts | 62 +++++++++++++------ packages/runtime-core/src/index.ts | 2 +- packages/runtime-core/src/renderer.ts | 49 +++++++++++++-- 13 files changed, 127 insertions(+), 36 deletions(-) diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 77a5146e52f..0a772b7de0f 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,5 +1,5 @@ { - "name": "@vue/compiler-sfc", + "name": "@cabloy/vue-compiler-sfc", "version": "3.5.13", "description": "@vue/compiler-sfc", "main": "dist/compiler-sfc.cjs.js", diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts index 6bb647f11ff..5f7f1952375 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -960,7 +960,7 @@ function importSourceToScope( function resolveExt(filename: string, fs: FS) { // #8339 ts may import .js but we should resolve to corresponding ts or d.ts - filename = filename.replace(/\.js$/, '') + filename = filename.replace(/\.jsx?$/, '') const tryResolve = (filename: string) => { if (fs.fileExists(filename)) return filename } diff --git a/packages/reactivity/package.json b/packages/reactivity/package.json index 4ef3171176f..fc60bb207e0 100644 --- a/packages/reactivity/package.json +++ b/packages/reactivity/package.json @@ -1,5 +1,5 @@ { - "name": "@vue/reactivity", + "name": "@cabloy/vue-reactivity", "version": "3.5.13", "description": "@vue/reactivity", "main": "index.js", diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index faec3012f40..8b42a760d01 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -119,7 +119,7 @@ class BaseReactiveHandler implements ProxyHandler { if (isRef(res)) { // ref unwrapping - skip unwrap for Array + integer key. - return targetIsArray && isIntegerKey(key) ? res : res.value + return targetIsArray && isIntegerKey(key) ? res : unrefNested(res) } if (isObject(res)) { @@ -133,6 +133,10 @@ class BaseReactiveHandler implements ProxyHandler { } } +function unrefNested(ref: any): any { + return isRef(ref) ? unrefNested(ref.value) : ref +} + class MutableReactiveHandler extends BaseReactiveHandler { constructor(isShallow = false) { super(false, isShallow) diff --git a/packages/runtime-core/package.json b/packages/runtime-core/package.json index db842c91614..2ef83d1d24c 100644 --- a/packages/runtime-core/package.json +++ b/packages/runtime-core/package.json @@ -1,5 +1,5 @@ { - "name": "@vue/runtime-core", + "name": "@cabloy/vue-runtime-core", "version": "3.5.13", "description": "@vue/runtime-core", "main": "index.js", diff --git a/packages/runtime-core/src/apiAsyncComponent.ts b/packages/runtime-core/src/apiAsyncComponent.ts index 199b451f66f..4295bacee4a 100644 --- a/packages/runtime-core/src/apiAsyncComponent.ts +++ b/packages/runtime-core/src/apiAsyncComponent.ts @@ -42,6 +42,13 @@ export interface AsyncComponentOptions { export const isAsyncWrapper = (i: ComponentInternalInstance | VNode): boolean => !!(i.type as ComponentOptions).__asyncLoader +function _getValidZova(instance: ComponentInternalInstance | null) { + while (instance) { + if ((instance).zova) return (instance).zova + instance = instance.parent + } +} + /*! #__NO_SIDE_EFFECTS__ */ export function defineAsyncComponent< T extends Component = { new (): ComponentPublicInstance }, @@ -134,7 +141,12 @@ export function defineAsyncComponent< if (resolvedComp) { doHydrate() } else { - load().then(() => !instance.isUnmounted && doHydrate()) + const zova = _getValidZova(instance) + zova.meta.ssr._hydratingInc() + load().then(() => { + !instance.isUnmounted && doHydrate() + zova.meta.ssr._hydratingDec() + }) } }, diff --git a/packages/runtime-core/src/apiLifecycle.ts b/packages/runtime-core/src/apiLifecycle.ts index b79a6d38a06..5744585824e 100644 --- a/packages/runtime-core/src/apiLifecycle.ts +++ b/packages/runtime-core/src/apiLifecycle.ts @@ -76,6 +76,9 @@ const createHook = ) { injectHook(lifecycle, (...args: unknown[]) => hook(...args), target) } + if (lifecycle === 'm' && target && target.isMounted) { + hook() + } } type CreateHook = ( hook: T, diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index 8f8392f1cdb..741c5cc78d6 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -99,11 +99,14 @@ const normalizeSlot = ( currentInstance && (!ctx || ctx.root === currentInstance.root) ) { - warn( - `Slot "${key}" invoked outside of the render function: ` + - `this will not track dependencies used in the slot. ` + - `Invoke the slot function inside the render function instead.`, - ) + // eslint-disable-next-line + if (typeof window !== 'undefined') { + warn( + `Slot "${key}" invoked outside of the render function: ` + + `this will not track dependencies used in the slot. ` + + `Invoke the slot function inside the render function instead.`, + ) + } } return normalizeSlotValue(rawSlot(...args)) }, ctx) as Slot diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index fe6fa36c1ca..62642072dfc 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -310,8 +310,8 @@ export const TeleportImpl = { } = vnode if (target) { - hostRemove(targetStart!) - hostRemove(targetAnchor!) + targetStart && hostRemove(targetStart!) + targetAnchor && hostRemove(targetAnchor!) } // an unmounted teleport should always unmount its children whether it's disabled or not diff --git a/packages/runtime-core/src/hmr.ts b/packages/runtime-core/src/hmr.ts index 7aedf52dd3e..df5a671993f 100644 --- a/packages/runtime-core/src/hmr.ts +++ b/packages/runtime-core/src/hmr.ts @@ -140,6 +140,8 @@ function reload(id: string, newComp: HMRComponent): void { instance.ceReload((newComp as any).styles) dirtyInstances.delete(instance) } else if (instance.parent) { + const app = instance.appContext.app + app.zova && app.zova.reloadDelay(true) // 4. Force the parent instance to re-render. This will cause all updated // components to be unmounted and re-mounted. Queue the update so that we // don't end up forcing the same parent to re-render multiple times. diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index a94ff356810..8e98381e726 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -181,16 +181,16 @@ export function createHydrationFunctions( } } else { if ((node as Text).data !== vnode.children) { - ;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) && - warn( - `Hydration text mismatch in`, - node.parentNode, - `\n - rendered on server: ${JSON.stringify( - (node as Text).data, - )}` + - `\n - expected on client: ${JSON.stringify(vnode.children)}`, - ) - logMismatchError() + // ;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) && + // warn( + // `Hydration text mismatch in`, + // node.parentNode, + // `\n - rendered on server: ${JSON.stringify( + // (node as Text).data, + // )}` + + // `\n - expected on client: ${JSON.stringify(vnode.children)}`, + // ) + // logMismatchError() ;(node as Text).data = vnode.children as string } nextNode = nextSibling(node) @@ -364,6 +364,13 @@ export function createHydrationFunctions( return nextNode } + function _getValidZova(instance: ComponentInternalInstance | null) { + while (instance) { + if ((instance).zova) return (instance).zova + instance = instance.parent + } + } + const hydrateElement = ( el: Element, vnode: VNode, @@ -485,14 +492,33 @@ export function createHydrationFunctions( const isCustomElement = el.tagName.includes('-') for (const key in props) { // check hydration mismatch - if ( - (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) && - // #11189 skip if this node has directives that have created hooks - // as it could have mutated the DOM in any possible way - !(dirs && dirs.some(d => d.dir.created)) && - propHasMismatch(el, key, props[key], vnode, parentComponent) - ) { - logMismatchError() + let ignore + let clientValue = props[key] + const zova = _getValidZova(parentComponent) + if (zova) { + const res = zova.meta.ssr._hydratePropHasMismatch( + el, + key, + clientValue, + vnode, + parentComponent, + ) + if (res.ignore) { + ignore = true + } else { + clientValue = res.clientValue + } + } + if (!ignore) { + if ( + (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) && + // #11189 skip if this node has directives that have created hooks + // as it could have mutated the DOM in any possible way + !(dirs && dirs.some(d => d.dir.created)) && + propHasMismatch(el, key, props[key], vnode, parentComponent) + ) { + logMismatchError() + } } if ( (forcePatch && diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 3871167b3ee..8ba7d1d9826 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -103,7 +103,7 @@ export { // For getting a hold of the internal instance in setup() - useful for advanced // plugins -export { getCurrentInstance } from './component' +export { getCurrentInstance, setCurrentInstance } from './component' // For raw render function users export { h } from './h' diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 90cc22f5470..bad3e3d1e62 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -1272,6 +1272,13 @@ function baseCreateRenderer( } } + function _getValidZova(instance: ComponentInternalInstance | null) { + while (instance) { + if ((instance).zova) return (instance).zova + instance = instance.parent + } + } + const setupRenderEffect: SetupRenderEffectFn = ( instance, initialVNode, @@ -1308,7 +1315,10 @@ function baseCreateRenderer( } toggleRecurse(instance, true) - if (el && hydrateNode) { + const _zova = _getValidZova(instance) + const _maybeAllowHydrate = + !_zova || _zova.meta.ssr.isRuntimeSsrPreHydration + if (el && hydrateNode && _maybeAllowHydrate) { // vnode has adopted host node - perform hydration instead of mount. const hydrateSubTree = () => { if (__DEV__) { @@ -1343,7 +1353,16 @@ function baseCreateRenderer( hydrateSubTree, ) } else { - hydrateSubTree() + const zova = (instance).zova + if (zova) { + zova.meta.ssr._hydratingInc() + zova.meta.state.inited.wait().then(() => { + !instance.isUnmounted && hydrateSubTree() + zova.meta.ssr._hydratingDec() + }) + } else { + hydrateSubTree() + } } } else { // custom element style injection @@ -1431,6 +1450,14 @@ function baseCreateRenderer( } else { let { next, bu, u, parent, vnode } = instance + const zova = (instance).zova + if (zova && zova.meta.ssr.isRuntimeSsrPreHydration) { + return + } + if (!instance.subTree) { + return + } + if (__FEATURE_SUSPENSE__) { const nonHydratedAsyncRoot = locateNonHydratedAsyncRoot(instance) // we are trying to update some async comp before hydration @@ -1557,8 +1584,22 @@ function baseCreateRenderer( const effect = (instance.effect = new ReactiveEffect(componentUpdateFn)) instance.scope.off() - const update = (instance.update = effect.run.bind(effect)) - const job: SchedulerJob = (instance.job = effect.runIfDirty.bind(effect)) + function _patchUpdate(checkDirty: boolean) { + if (!checkDirty || effect.dirty) { + const zova = _getValidZova(instance) + if ( + zova && + zova.meta.ssr.isRuntimeSsrPreHydration && + !zova.meta.ssr._hydratingInstanceRecord(instance) + ) { + return + } + effect.run() + } + } + + const update = (instance.update = () => _patchUpdate(false)) + const job: SchedulerJob = (instance.job = () => _patchUpdate(true)) job.i = instance job.id = instance.uid effect.scheduler = () => queueJob(job)