fix(compiler-ssr): handle comments codegen + refactor ssr codegen transform

This commit is contained in:
Evan You
2020-05-01 17:04:36 -04:00
parent 0e730c06e4
commit 6c60ce13e0
5 changed files with 85 additions and 27 deletions

View File

@@ -19,11 +19,13 @@ export function createSSRCompilerError(
export const enum SSRErrorCodes {
X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM = DOMErrorCodes.__EXTEND_POINT__,
X_SSR_UNSAFE_ATTR_NAME,
X_SSR_NO_TELEPORT_TARGET
X_SSR_NO_TELEPORT_TARGET,
X_SSR_INVALID_AST_NODE
}
export const SSRErrorMessages: { [code: number]: string } = {
[SSRErrorCodes.X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM]: `Custom directive is missing corresponding SSR transform and will be ignored.`,
[SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME]: `Unsafe attribute name for SSR.`,
[SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET]: `No target prop on teleport element.`
[SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET]: `No target prop on teleport element.`,
[SSRErrorCodes.X_SSR_INVALID_AST_NODE]: `Invalid AST node during ssr transform`
}

View File

@@ -20,6 +20,7 @@ import { ssrProcessFor } from './transforms/ssrVFor'
import { ssrProcessSlotOutlet } from './transforms/ssrTransformSlotOutlet'
import { ssrProcessComponent } from './transforms/ssrTransformComponent'
import { ssrProcessElement } from './transforms/ssrTransformElement'
import { createSSRCompilerError, SSRErrorCodes } from './errors'
// Because SSR codegen output is completely different from client-side output
// (e.g. multiple elements can be concatenated into a single template literal
@@ -115,24 +116,70 @@ export function processChildren(
}
for (let i = 0; i < children.length; i++) {
const child = children[i]
if (child.type === NodeTypes.ELEMENT) {
if (child.tagType === ElementTypes.ELEMENT) {
ssrProcessElement(child, context)
} else if (child.tagType === ElementTypes.COMPONENT) {
ssrProcessComponent(child, context)
} else if (child.tagType === ElementTypes.SLOT) {
ssrProcessSlotOutlet(child, context)
}
} else if (child.type === NodeTypes.TEXT) {
context.pushStringPart(escapeHtml(child.content))
} else if (child.type === NodeTypes.INTERPOLATION) {
context.pushStringPart(
createCallExpression(context.helper(SSR_INTERPOLATE), [child.content])
)
} else if (child.type === NodeTypes.IF) {
ssrProcessIf(child, context)
} else if (child.type === NodeTypes.FOR) {
ssrProcessFor(child, context)
switch (child.type) {
case NodeTypes.ELEMENT:
switch (child.tagType) {
case ElementTypes.ELEMENT:
ssrProcessElement(child, context)
break
case ElementTypes.COMPONENT:
ssrProcessComponent(child, context)
break
case ElementTypes.SLOT:
ssrProcessSlotOutlet(child, context)
break
case ElementTypes.TEMPLATE:
// TODO
break
default:
context.onError(
createSSRCompilerError(
SSRErrorCodes.X_SSR_INVALID_AST_NODE,
(child as any).loc
)
)
// make sure we exhaust all possible types
const exhaustiveCheck: never = child
return exhaustiveCheck
}
break
case NodeTypes.TEXT:
context.pushStringPart(escapeHtml(child.content))
break
case NodeTypes.COMMENT:
// no need to escape comment here because the AST can only
// contain valid comments.
context.pushStringPart(`<!--${child.content}-->`)
break
case NodeTypes.INTERPOLATION:
context.pushStringPart(
createCallExpression(context.helper(SSR_INTERPOLATE), [child.content])
)
break
case NodeTypes.IF:
ssrProcessIf(child, context)
break
case NodeTypes.FOR:
ssrProcessFor(child, context)
break
case NodeTypes.IF_BRANCH:
// no-op - handled by ssrProcessIf
break
case NodeTypes.TEXT_CALL:
case NodeTypes.COMPOUND_EXPRESSION:
// no-op - these two types can never appear as template child node since
// `transformText` is not used during SSR compile.
break
default:
context.onError(
createSSRCompilerError(
SSRErrorCodes.X_SSR_INVALID_AST_NODE,
(child as any).loc
)
)
// make sure we exhaust all possible types
const exhaustiveCheck: never = child
return exhaustiveCheck
}
}
if (asFragment) {