diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index 6ed7aa5b897..6a1f8b63b57 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -43,7 +43,8 @@ export { processIf } from './transforms/vIf' export { processFor, createForLoopParams } from './transforms/vFor' export { transformExpression, - processExpression + processExpression, + stringifyExpression } from './transforms/transformExpression' export { buildSlots, diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index e4311ad4f88..43c69559688 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -361,7 +361,7 @@ function canPrefix(id: Identifier) { return true } -function stringifyExpression(exp: ExpressionNode | string): string { +export function stringifyExpression(exp: ExpressionNode | string): string { if (isString(exp)) { return exp } else if (exp.type === NodeTypes.SIMPLE_EXPRESSION) { diff --git a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts index 5d5191ffb44..cd21e48cb9a 100644 --- a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts @@ -104,6 +104,11 @@ describe('ssr: components', () => { `) }) + test('empty attribute should not produce syntax error', () => { + // previously this would produce syntax error `default: _withCtx((, _push, ...)` + expect(compile(`foo`).code).not.toMatch(`(,`) + }) + test('named slots', () => { expect( compile(` diff --git a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts index df190c768a8..dc8c6a4ae4f 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformComponent.ts @@ -36,7 +36,8 @@ import { CallExpression, JSChildNode, RESOLVE_DYNAMIC_COMPONENT, - TRANSITION + TRANSITION, + stringifyExpression } from '@vue/compiler-dom' import { SSR_RENDER_COMPONENT, SSR_RENDER_VNODE } from '../runtimeHelpers' import { @@ -145,8 +146,9 @@ export const ssrTransformComponent: NodeTransform = (node, context) => { wipMap.set(node, wipEntries) const buildSSRSlotFn: SlotFnBuilder = (props, children, loc) => { + const param0 = (props && stringifyExpression(props)) || `_` const fn = createFunctionExpression( - [props || `_`, `_push`, `_parent`, `_scopeId`], + [param0, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later true, // newline true, // isSlot