diff --git a/packages/compiler-dom/src/index.ts b/packages/compiler-dom/src/index.ts index 809f3708023..a3a738a8fb1 100644 --- a/packages/compiler-dom/src/index.ts +++ b/packages/compiler-dom/src/index.ts @@ -19,14 +19,13 @@ import { transformShow } from './transforms/vShow' import { transformTransition } from './transforms/Transition' import { stringifyStatic } from './transforms/stringifyStatic' import { ignoreSideEffectTags } from './transforms/ignoreSideEffectTags' -import { validateHtmlNesting } from './transforms/validateHtmlNesting' import { extend } from '@vue/shared' export { parserOptions } export const DOMNodeTransforms: NodeTransform[] = [ transformStyle, - ...(__DEV__ ? [transformTransition, validateHtmlNesting] : []), + ...(__DEV__ ? [transformTransition] : []), ] export const DOMDirectiveTransforms: Record = { diff --git a/packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts b/packages/compiler-ssr/__tests__/validateHtmlNesting.spec.ts similarity index 73% rename from packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts rename to packages/compiler-ssr/__tests__/validateHtmlNesting.spec.ts index ad9f917137e..f5da4d36767 100644 --- a/packages/compiler-dom/__tests__/transforms/validateHtmlNesting.spec.ts +++ b/packages/compiler-ssr/__tests__/validateHtmlNesting.spec.ts @@ -1,4 +1,5 @@ -import { type CompilerError, compile } from '../../src' +import type { CompilerError } from '@vue/compiler-core' +import { compile } from '@vue/compiler-ssr' describe('validate html nesting', () => { it('should warn with p > div', () => { @@ -7,7 +8,7 @@ describe('validate html nesting', () => { onWarn: e => (err = e), }) expect(err).toBeDefined() - expect(err!.message).toMatch(`
cannot be child of

`) + expect(err!.message).toMatch(`

as a child of

`) }) it('should not warn with select > hr', () => { diff --git a/packages/compiler-dom/src/htmlNesting.ts b/packages/compiler-ssr/src/htmlNesting.ts similarity index 92% rename from packages/compiler-dom/src/htmlNesting.ts rename to packages/compiler-ssr/src/htmlNesting.ts index cb0a7626d15..cc5b9a6d622 100644 --- a/packages/compiler-dom/src/htmlNesting.ts +++ b/packages/compiler-ssr/src/htmlNesting.ts @@ -5,10 +5,17 @@ * To avoid runtime dependency on validate-html-nesting * This file should not change very often in the original repo * but we may need to keep it up-to-date from time to time. + * + * The parent-child nesting is considered valid if the Browser + * does not modify it, regardless of whether or not the HTML spec + * considers it valid or invalid. So, the library is purely for + * detecting the kind of element nesting which result in altered DOM. + * */ /** - * returns true if given parent-child nesting is valid HTML + * returns true if given parent-child nesting is not known to result + * in an altered DOM */ export function isValidHTMLNesting(parent: string, child: string): boolean { // if we know the list of children that are the only valid children for the given parent diff --git a/packages/compiler-ssr/src/index.ts b/packages/compiler-ssr/src/index.ts index f8a686555e8..a88045c689f 100644 --- a/packages/compiler-ssr/src/index.ts +++ b/packages/compiler-ssr/src/index.ts @@ -27,6 +27,7 @@ import { ssrTransformModel } from './transforms/ssrVModel' import { ssrTransformShow } from './transforms/ssrVShow' import { ssrInjectFallthroughAttrs } from './transforms/ssrInjectFallthroughAttrs' import { ssrInjectCssVars } from './transforms/ssrInjectCssVars' +import { validateHtmlNesting } from './transforms/validateHtmlNesting' export function compile( source: string | RootNode, @@ -66,6 +67,7 @@ export function compile( ssrTransformComponent, trackSlotScopes, transformStyle, + ...(__DEV__ ? [validateHtmlNesting] : []), ...(options.nodeTransforms || []), // user transforms ], directiveTransforms: { diff --git a/packages/compiler-dom/src/transforms/validateHtmlNesting.ts b/packages/compiler-ssr/src/transforms/validateHtmlNesting.ts similarity index 85% rename from packages/compiler-dom/src/transforms/validateHtmlNesting.ts rename to packages/compiler-ssr/src/transforms/validateHtmlNesting.ts index 540c0c25871..7e40e8d3753 100644 --- a/packages/compiler-dom/src/transforms/validateHtmlNesting.ts +++ b/packages/compiler-ssr/src/transforms/validateHtmlNesting.ts @@ -16,8 +16,8 @@ export const validateHtmlNesting: NodeTransform = (node, context) => { !isValidHTMLNesting(context.parent.tag, node.tag) ) { const error = new SyntaxError( - `<${node.tag}> cannot be child of <${context.parent.tag}>, ` + - 'according to HTML specifications. ' + + `<${node.tag}> as a child of <${context.parent.tag}> ` + + 'might result in the browser modifying the DOM. ' + 'This can cause hydration errors or ' + 'potentially disrupt future functionality.', ) as CompilerError diff --git a/packages/server-renderer/src/helpers/ssrCompile.ts b/packages/server-renderer/src/helpers/ssrCompile.ts index 8412a65e843..6a2e986794c 100644 --- a/packages/server-renderer/src/helpers/ssrCompile.ts +++ b/packages/server-renderer/src/helpers/ssrCompile.ts @@ -67,8 +67,8 @@ export function ssrCompile( return cached } - finalCompilerOptions.onError = (err: CompilerError) => { - if (__DEV__) { + if (__DEV__) { + const compilationErrorHandler = (err: CompilerError) => { const message = `[@vue/server-renderer] Template compilation error: ${err.message}` const codeFrame = err.loc && @@ -78,7 +78,11 @@ export function ssrCompile( err.loc.end.offset, ) warn(codeFrame ? `${message}\n${codeFrame}` : message) - } else { + } + finalCompilerOptions.onWarn = compilationErrorHandler + finalCompilerOptions.onError = compilationErrorHandler + } else { + finalCompilerOptions.onError = (err: CompilerError) => { throw err } }