Skip to content

feat(shared): expose rawChildrenMap in context #5082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/compiler-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export {
createStructuralDirectiveTransform,
NodeTransform,
StructuralDirectiveTransform,
DirectiveTransform
DirectiveTransform,
RawChildrenMap
} from './transform'
export { generate, CodegenContext, CodegenResult } from './codegen'
export {
Expand Down
9 changes: 9 additions & 0 deletions packages/compiler-core/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
import { isVSlot, makeBlock } from './utils'
import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic'
import { CompilerCompatOptions } from './compat/compatConfig'
import { PlainElementNode } from '@vue/compiler-dom'

// There are two types of transforms:
//
Expand Down Expand Up @@ -81,6 +82,8 @@ export interface ImportItem {
path: string
}

export type RawChildrenMap = WeakMap<PlainElementNode, TemplateLiteral['elements'][0]>

export interface TransformContext
extends Required<
Omit<TransformOptions, 'filename' | keyof CompilerCompatOptions>
Expand Down Expand Up @@ -117,6 +120,7 @@ export interface TransformContext
hoist(exp: string | JSChildNode | ArrayExpression): SimpleExpressionNode
cache<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T
constantCache: Map<TemplateChildNode, ConstantTypes>
rawChildrenMap: RawChildrenMap

// 2.x Compat only
filters?: Set<string>
Expand Down Expand Up @@ -194,6 +198,7 @@ export function createTransformContext(
currentNode: root,
childIndex: 0,
inVOnce: false,
rawChildrenMap: new WeakMap(),

// methods
helper(name) {
Expand Down Expand Up @@ -335,6 +340,10 @@ export function transform(root: RootNode, options: TransformOptions) {
if (__COMPAT__) {
root.filters = [...context.filters!]
}

return {
context
}
}

function createRootCodegen(root: RootNode, context: TransformContext) {
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler-ssr/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function compile(
// on slot vnode branches.
rawOptionsMap.set(ast, options)

transform(ast, {
const { context } = transform(ast, {
...options,
hoistStatic: false,
nodeTransforms: [
Expand Down Expand Up @@ -84,7 +84,7 @@ export function compile(

// traverse the template AST and convert into SSR codegen AST
// by replacing ast.codegenNode.
ssrCodegenTransform(ast, options)
ssrCodegenTransform(ast, options, context.rawChildrenMap)

return generate(ast, options)
}
10 changes: 7 additions & 3 deletions packages/compiler-ssr/src/ssrCodegenTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ import { ssrProcessSlotOutlet } from './transforms/ssrTransformSlotOutlet'
import { ssrProcessComponent } from './transforms/ssrTransformComponent'
import { ssrProcessElement } from './transforms/ssrTransformElement'
import { createSSRCompilerError, SSRErrorCodes } from './errors'
import { RawChildrenMap } from '@vue/compiler-core'

// Because SSR codegen output is completely different from client-side output
// (e.g. multiple elements can be concatenated into a single template literal
// instead of each getting a corresponding call), we need to apply an extra
// transform pass to convert the template AST into a fresh JS AST before
// passing it to codegen.

export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions) {
const context = createSSRTransformContext(ast, options)
export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions, rawChildrenMap: RawChildrenMap) {
const context = createSSRTransformContext(ast, options, rawChildrenMap)

// inject SFC <style> CSS variables
// we do this instead of inlining the expression to ensure the vars are
Expand Down Expand Up @@ -68,6 +69,7 @@ export type SSRTransformContext = ReturnType<typeof createSSRTransformContext>
function createSSRTransformContext(
root: RootNode,
options: CompilerOptions,
rawChildrenMap: RawChildrenMap = new WeakMap(),
helpers: Set<symbol> = new Set(),
withSlotScopeId = false
) {
Expand Down Expand Up @@ -108,7 +110,8 @@ function createSSRTransformContext(
// close current string
currentString = null
body.push(statement)
}
},
rawChildrenMap
}
}

Expand All @@ -120,6 +123,7 @@ function createChildContext(
return createSSRTransformContext(
parent.root,
parent.options,
parent.rawChildrenMap,
parent.helpers,
withSlotScopeId
)
Expand Down
13 changes: 5 additions & 8 deletions packages/compiler-ssr/src/transforms/ssrTransformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ import {
} from '../runtimeHelpers'
import { SSRTransformContext, processChildren } from '../ssrCodegenTransform'

// for directives with children overwrite (e.g. v-html & v-text), we need to
// store the raw children so that they can be added in the 2nd pass.
const rawChildrenMap = new WeakMap<
PlainElementNode,
TemplateLiteral['elements'][0]
>()

export const ssrTransformElement: NodeTransform = (node, context) => {
if (
node.type !== NodeTypes.ELEMENT ||
Expand All @@ -63,6 +56,10 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
return
}

// for directives with children overwrite (e.g. v-html & v-text), we need to
// store the raw children so that they can be added in the 2nd pass.
const { rawChildrenMap } = context

return function ssrPostTransformElement() {
// element
// generate the template literal representing the open tag.
Expand Down Expand Up @@ -385,7 +382,7 @@ export function ssrProcessElement(
// close open tag
context.pushStringPart(`>`)

const rawChildren = rawChildrenMap.get(node)
const rawChildren = context.rawChildrenMap.get(node)
if (rawChildren) {
context.pushStringPart(rawChildren)
} else if (node.children.length) {
Expand Down