refactor(compiler-ssr): extract portal processing + emit errors

This commit is contained in:
Evan You 2020-02-26 15:05:11 -05:00
parent d8ed0e7fbf
commit d52ffaa202
2 changed files with 48 additions and 29 deletions

View File

@ -60,6 +60,11 @@ function createSSRTransformContext(
body, body,
helpers, helpers,
withSlotScopeId, withSlotScopeId,
onError:
options.onError ||
(e => {
throw e
}),
helper<T extends symbol>(name: T): T { helper<T extends symbol>(name: T): T {
helpers.add(name) helpers.add(name)
return name return name

View File

@ -42,6 +42,7 @@ import {
processChildrenAsStatement processChildrenAsStatement
} from '../ssrCodegenTransform' } from '../ssrCodegenTransform'
import { isSymbol, isObject, isArray } from '@vue/shared' import { isSymbol, isObject, isArray } from '@vue/shared'
import { createSSRCompilerError, SSRErrorCodes } from '../errors'
// We need to construct the slot functions in the 1st pass to ensure proper // We need to construct the slot functions in the 1st pass to ensure proper
// scope tracking, but the children of each slot cannot be processed until // scope tracking, but the children of each slot cannot be processed until
@ -136,35 +137,7 @@ export function ssrProcessComponent(
const component = componentTypeMap.get(node)! const component = componentTypeMap.get(node)!
if (component === PORTAL) { if (component === PORTAL) {
const targetProp = findProp(node, 'target') return ssrProcessPortal(node, context)
if (!targetProp) return
let target: JSChildNode
if (targetProp.type === NodeTypes.ATTRIBUTE && targetProp.value) {
target = createSimpleExpression(targetProp.value.content, true)
} else if (targetProp.type === NodeTypes.DIRECTIVE && targetProp.exp) {
target = targetProp.exp
} else {
return
}
const contentRenderFn = createFunctionExpression(
[`_push`],
undefined, // Body is added later
true, // newline
false, // isSlot
node.loc
)
contentRenderFn.body = processChildrenAsStatement(node.children, context)
context.pushStatement(
createCallExpression(context.helper(SSR_RENDER_PORTAL), [
contentRenderFn,
target,
`_parent`
])
)
return
} }
const needFragmentWrapper = const needFragmentWrapper =
@ -194,6 +167,47 @@ export function ssrProcessComponent(
} }
} }
function ssrProcessPortal(node: ComponentNode, context: SSRTransformContext) {
const targetProp = findProp(node, 'target')
if (!targetProp) {
context.onError(
createSSRCompilerError(SSRErrorCodes.X_SSR_NO_PORTAL_TARGET, node.loc)
)
return
}
let target: JSChildNode
if (targetProp.type === NodeTypes.ATTRIBUTE && targetProp.value) {
target = createSimpleExpression(targetProp.value.content, true)
} else if (targetProp.type === NodeTypes.DIRECTIVE && targetProp.exp) {
target = targetProp.exp
} else {
context.onError(
createSSRCompilerError(
SSRErrorCodes.X_SSR_NO_PORTAL_TARGET,
targetProp.loc
)
)
return
}
const contentRenderFn = createFunctionExpression(
[`_push`],
undefined, // Body is added later
true, // newline
false, // isSlot
node.loc
)
contentRenderFn.body = processChildrenAsStatement(node.children, context)
context.pushStatement(
createCallExpression(context.helper(SSR_RENDER_PORTAL), [
contentRenderFn,
target,
`_parent`
])
)
}
export const rawOptionsMap = new WeakMap<RootNode, CompilerOptions>() export const rawOptionsMap = new WeakMap<RootNode, CompilerOptions>()
const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset( const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(