@vue/compiler-ssr 3.2.33 → 3.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler-ssr.cjs.js +187 -75
- package/package.json +3 -3
package/dist/compiler-ssr.cjs.js
CHANGED
|
@@ -9,6 +9,7 @@ const SSR_INTERPOLATE = Symbol(`ssrInterpolate`);
|
|
|
9
9
|
const SSR_RENDER_VNODE = Symbol(`ssrRenderVNode`);
|
|
10
10
|
const SSR_RENDER_COMPONENT = Symbol(`ssrRenderComponent`);
|
|
11
11
|
const SSR_RENDER_SLOT = Symbol(`ssrRenderSlot`);
|
|
12
|
+
const SSR_RENDER_SLOT_INNER = Symbol(`ssrRenderSlotInner`);
|
|
12
13
|
const SSR_RENDER_CLASS = Symbol(`ssrRenderClass`);
|
|
13
14
|
const SSR_RENDER_STYLE = Symbol(`ssrRenderStyle`);
|
|
14
15
|
const SSR_RENDER_ATTRS = Symbol(`ssrRenderAttrs`);
|
|
@@ -28,6 +29,7 @@ const ssrHelpers = {
|
|
|
28
29
|
[SSR_RENDER_VNODE]: `ssrRenderVNode`,
|
|
29
30
|
[SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
|
|
30
31
|
[SSR_RENDER_SLOT]: `ssrRenderSlot`,
|
|
32
|
+
[SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
|
|
31
33
|
[SSR_RENDER_CLASS]: `ssrRenderClass`,
|
|
32
34
|
[SSR_RENDER_STYLE]: `ssrRenderStyle`,
|
|
33
35
|
[SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
|
|
@@ -80,7 +82,7 @@ function processIfBranch(branch, context, disableNestedFragments = false) {
|
|
|
80
82
|
(children.length !== 1 || children[0].type !== 1 /* ELEMENT */) &&
|
|
81
83
|
// optimize away nested fragments when the only child is a ForNode
|
|
82
84
|
!(children.length === 1 && children[0].type === 11 /* FOR */);
|
|
83
|
-
return processChildrenAsStatement(
|
|
85
|
+
return processChildrenAsStatement(branch, context, needFragmentWrapper);
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
// Plugin for the first transform pass, which simply constructs the AST node
|
|
@@ -91,7 +93,7 @@ function ssrProcessFor(node, context, disableNestedFragments = false) {
|
|
|
91
93
|
const needFragmentWrapper = !disableNestedFragments &&
|
|
92
94
|
(node.children.length !== 1 || node.children[0].type !== 1 /* ELEMENT */);
|
|
93
95
|
const renderLoop = compilerDom.createFunctionExpression(compilerDom.createForLoopParams(node.parseResult));
|
|
94
|
-
renderLoop.body = processChildrenAsStatement(node
|
|
96
|
+
renderLoop.body = processChildrenAsStatement(node, context, needFragmentWrapper);
|
|
95
97
|
// v-for always renders a fragment unless explicitly disabled
|
|
96
98
|
if (!disableNestedFragments) {
|
|
97
99
|
context.pushStringPart(`<!--[-->`);
|
|
@@ -121,7 +123,20 @@ const ssrTransformSlotOutlet = (node, context) => {
|
|
|
121
123
|
if (context.scopeId && context.slotted !== false) {
|
|
122
124
|
args.push(`"${context.scopeId}-s"`);
|
|
123
125
|
}
|
|
124
|
-
|
|
126
|
+
let method = SSR_RENDER_SLOT;
|
|
127
|
+
// #3989
|
|
128
|
+
// check if this is a single slot inside a transition wrapper - since
|
|
129
|
+
// transition will unwrap the slot fragment into a single vnode at runtime,
|
|
130
|
+
// we need to avoid rendering the slot as a fragment.
|
|
131
|
+
const parent = context.parent;
|
|
132
|
+
if (parent &&
|
|
133
|
+
parent.type === 1 /* ELEMENT */ &&
|
|
134
|
+
parent.tagType === 1 /* COMPONENT */ &&
|
|
135
|
+
compilerDom.resolveComponentType(parent, context, true) === compilerDom.TRANSITION &&
|
|
136
|
+
parent.children.filter(c => c.type === 1 /* ELEMENT */).length === 1) {
|
|
137
|
+
method = SSR_RENDER_SLOT_INNER;
|
|
138
|
+
}
|
|
139
|
+
node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
|
|
125
140
|
}
|
|
126
141
|
};
|
|
127
142
|
function ssrProcessSlotOutlet(node, context) {
|
|
@@ -129,7 +144,7 @@ function ssrProcessSlotOutlet(node, context) {
|
|
|
129
144
|
// has fallback content
|
|
130
145
|
if (node.children.length) {
|
|
131
146
|
const fallbackRenderFn = compilerDom.createFunctionExpression([]);
|
|
132
|
-
fallbackRenderFn.body = processChildrenAsStatement(node
|
|
147
|
+
fallbackRenderFn.body = processChildrenAsStatement(node, context);
|
|
133
148
|
// _renderSlot(slots, name, props, fallback, ...)
|
|
134
149
|
renderCall.arguments[3] = fallbackRenderFn;
|
|
135
150
|
}
|
|
@@ -181,7 +196,7 @@ function ssrProcessTeleport(node, context) {
|
|
|
181
196
|
true, // newline
|
|
182
197
|
false, // isSlot
|
|
183
198
|
node.loc);
|
|
184
|
-
contentRenderFn.body = processChildrenAsStatement(node
|
|
199
|
+
contentRenderFn.body = processChildrenAsStatement(node, context);
|
|
185
200
|
context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
|
|
186
201
|
`_push`,
|
|
187
202
|
contentRenderFn,
|
|
@@ -224,8 +239,8 @@ function ssrProcessSuspense(node, context) {
|
|
|
224
239
|
}
|
|
225
240
|
const { slotsExp, wipSlots } = wipEntry;
|
|
226
241
|
for (let i = 0; i < wipSlots.length; i++) {
|
|
227
|
-
const
|
|
228
|
-
fn.body = processChildrenAsStatement(
|
|
242
|
+
const slot = wipSlots[i];
|
|
243
|
+
slot.fn.body = processChildrenAsStatement(slot, context);
|
|
229
244
|
}
|
|
230
245
|
// _push(ssrRenderSuspense(slots))
|
|
231
246
|
context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
|
|
@@ -234,39 +249,6 @@ function ssrProcessSuspense(node, context) {
|
|
|
234
249
|
]));
|
|
235
250
|
}
|
|
236
251
|
|
|
237
|
-
function ssrProcessTransitionGroup(node, context) {
|
|
238
|
-
const tag = compilerDom.findProp(node, 'tag');
|
|
239
|
-
if (tag) {
|
|
240
|
-
if (tag.type === 7 /* DIRECTIVE */) {
|
|
241
|
-
// dynamic :tag
|
|
242
|
-
context.pushStringPart(`<`);
|
|
243
|
-
context.pushStringPart(tag.exp);
|
|
244
|
-
context.pushStringPart(`>`);
|
|
245
|
-
processChildren(node.children, context, false,
|
|
246
|
-
/**
|
|
247
|
-
* TransitionGroup has the special runtime behavior of flattening and
|
|
248
|
-
* concatenating all children into a single fragment (in order for them to
|
|
249
|
-
* be patched using the same key map) so we need to account for that here
|
|
250
|
-
* by disabling nested fragment wrappers from being generated.
|
|
251
|
-
*/
|
|
252
|
-
true);
|
|
253
|
-
context.pushStringPart(`</`);
|
|
254
|
-
context.pushStringPart(tag.exp);
|
|
255
|
-
context.pushStringPart(`>`);
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
// static tag
|
|
259
|
-
context.pushStringPart(`<${tag.value.content}>`);
|
|
260
|
-
processChildren(node.children, context, false, true);
|
|
261
|
-
context.pushStringPart(`</${tag.value.content}>`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
// fragment
|
|
266
|
-
processChildren(node.children, context, true, true);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
252
|
// for directives with children overwrite (e.g. v-html & v-text), we need to
|
|
271
253
|
// store the raw children so that they can be added in the 2nd pass.
|
|
272
254
|
const rawChildrenMap = new WeakMap();
|
|
@@ -288,7 +270,7 @@ const ssrTransformElement = (node, context) => {
|
|
|
288
270
|
const hasCustomDir = node.props.some(p => p.type === 7 /* DIRECTIVE */ && !shared.isBuiltInDirective(p.name));
|
|
289
271
|
const needMergeProps = hasDynamicVBind || hasCustomDir;
|
|
290
272
|
if (needMergeProps) {
|
|
291
|
-
const { props, directives } = compilerDom.buildProps(node, context, node.props, true /* ssr */);
|
|
273
|
+
const { props, directives } = compilerDom.buildProps(node, context, node.props, false /* isComponent */, false /* isDynamicComponent */, true /* ssr */);
|
|
292
274
|
if (props || directives.length) {
|
|
293
275
|
const mergedProps = buildSSRProps(props, directives, context);
|
|
294
276
|
const propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [mergedProps]);
|
|
@@ -367,7 +349,7 @@ const ssrTransformElement = (node, context) => {
|
|
|
367
349
|
node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
|
|
368
350
|
}
|
|
369
351
|
}
|
|
370
|
-
else if (!needMergeProps) {
|
|
352
|
+
else if (!needMergeProps && prop.name !== 'on') {
|
|
371
353
|
// Directive transforms.
|
|
372
354
|
const directiveTransform = context.directiveTransforms[prop.name];
|
|
373
355
|
if (directiveTransform) {
|
|
@@ -532,7 +514,7 @@ function ssrProcessElement(node, context) {
|
|
|
532
514
|
context.pushStringPart(rawChildren);
|
|
533
515
|
}
|
|
534
516
|
else if (node.children.length) {
|
|
535
|
-
processChildren(node
|
|
517
|
+
processChildren(node, context);
|
|
536
518
|
}
|
|
537
519
|
if (!isVoidTag(node.tag)) {
|
|
538
520
|
// push closing tag
|
|
@@ -540,11 +522,75 @@ function ssrProcessElement(node, context) {
|
|
|
540
522
|
}
|
|
541
523
|
}
|
|
542
524
|
|
|
525
|
+
const wipMap$1 = new WeakMap();
|
|
526
|
+
// phase 1: build props
|
|
527
|
+
function ssrTransformTransitionGroup(node, context) {
|
|
528
|
+
return () => {
|
|
529
|
+
const tag = compilerDom.findProp(node, 'tag');
|
|
530
|
+
if (tag) {
|
|
531
|
+
const otherProps = node.props.filter(p => p !== tag);
|
|
532
|
+
const { props, directives } = compilerDom.buildProps(node, context, otherProps, true, /* isComponent */ false, /* isDynamicComponent */ true /* ssr (skip event listeners) */);
|
|
533
|
+
let propsExp = null;
|
|
534
|
+
if (props || directives.length) {
|
|
535
|
+
propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
|
|
536
|
+
buildSSRProps(props, directives, context)
|
|
537
|
+
]);
|
|
538
|
+
}
|
|
539
|
+
wipMap$1.set(node, {
|
|
540
|
+
tag,
|
|
541
|
+
propsExp
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
// phase 2: process children
|
|
547
|
+
function ssrProcessTransitionGroup(node, context) {
|
|
548
|
+
const entry = wipMap$1.get(node);
|
|
549
|
+
if (entry) {
|
|
550
|
+
const { tag, propsExp } = entry;
|
|
551
|
+
if (tag.type === 7 /* DIRECTIVE */) {
|
|
552
|
+
// dynamic :tag
|
|
553
|
+
context.pushStringPart(`<`);
|
|
554
|
+
context.pushStringPart(tag.exp);
|
|
555
|
+
if (propsExp) {
|
|
556
|
+
context.pushStringPart(propsExp);
|
|
557
|
+
}
|
|
558
|
+
context.pushStringPart(`>`);
|
|
559
|
+
processChildren(node, context, false,
|
|
560
|
+
/**
|
|
561
|
+
* TransitionGroup has the special runtime behavior of flattening and
|
|
562
|
+
* concatenating all children into a single fragment (in order for them to
|
|
563
|
+
* be patched using the same key map) so we need to account for that here
|
|
564
|
+
* by disabling nested fragment wrappers from being generated.
|
|
565
|
+
*/
|
|
566
|
+
true);
|
|
567
|
+
context.pushStringPart(`</`);
|
|
568
|
+
context.pushStringPart(tag.exp);
|
|
569
|
+
context.pushStringPart(`>`);
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
// static tag
|
|
573
|
+
context.pushStringPart(`<${tag.value.content}`);
|
|
574
|
+
if (propsExp) {
|
|
575
|
+
context.pushStringPart(propsExp);
|
|
576
|
+
}
|
|
577
|
+
context.pushStringPart(`>`);
|
|
578
|
+
processChildren(node, context, false, true);
|
|
579
|
+
context.pushStringPart(`</${tag.value.content}>`);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
// fragment
|
|
584
|
+
processChildren(node, context, true, true);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
543
588
|
// We need to construct the slot functions in the 1st pass to ensure proper
|
|
544
589
|
// scope tracking, but the children of each slot cannot be processed until
|
|
545
590
|
// the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
|
|
546
591
|
// pass and complete them in the 2nd pass.
|
|
547
|
-
const wipMap$
|
|
592
|
+
const wipMap$2 = new WeakMap();
|
|
593
|
+
const WIP_SLOT = Symbol();
|
|
548
594
|
const componentTypeMap = new WeakMap();
|
|
549
595
|
// ssr component transform is done in two phases:
|
|
550
596
|
// In phase 1. we use `buildSlot` to analyze the children of the component into
|
|
@@ -558,12 +604,16 @@ const ssrTransformComponent = (node, context) => {
|
|
|
558
604
|
return;
|
|
559
605
|
}
|
|
560
606
|
const component = compilerDom.resolveComponentType(node, context, true /* ssr */);
|
|
607
|
+
const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
|
|
561
608
|
componentTypeMap.set(node, component);
|
|
562
609
|
if (shared.isSymbol(component)) {
|
|
563
610
|
if (component === compilerDom.SUSPENSE) {
|
|
564
611
|
return ssrTransformSuspense(node, context);
|
|
565
612
|
}
|
|
566
|
-
|
|
613
|
+
if (component === compilerDom.TRANSITION_GROUP) {
|
|
614
|
+
return ssrTransformTransitionGroup(node, context);
|
|
615
|
+
}
|
|
616
|
+
return; // other built-in components: fallthrough
|
|
567
617
|
}
|
|
568
618
|
// Build the fallback vnode-based branch for the component's slots.
|
|
569
619
|
// We need to clone the node into a fresh copy and use the buildSlots' logic
|
|
@@ -587,19 +637,20 @@ const ssrTransformComponent = (node, context) => {
|
|
|
587
637
|
if (node.props.length) {
|
|
588
638
|
// note we are not passing ssr: true here because for components, v-on
|
|
589
639
|
// handlers should still be passed
|
|
590
|
-
const { props, directives } = compilerDom.buildProps(node, context);
|
|
640
|
+
const { props, directives } = compilerDom.buildProps(node, context, undefined, true, isDynamicComponent);
|
|
591
641
|
if (props || directives.length) {
|
|
592
642
|
propsExp = buildSSRProps(props, directives, context);
|
|
593
643
|
}
|
|
594
644
|
}
|
|
595
645
|
const wipEntries = [];
|
|
596
|
-
wipMap$
|
|
646
|
+
wipMap$2.set(node, wipEntries);
|
|
597
647
|
const buildSSRSlotFn = (props, children, loc) => {
|
|
598
648
|
const fn = compilerDom.createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
|
|
599
649
|
true, // newline
|
|
600
650
|
true, // isSlot
|
|
601
651
|
loc);
|
|
602
652
|
wipEntries.push({
|
|
653
|
+
type: WIP_SLOT,
|
|
603
654
|
fn,
|
|
604
655
|
children,
|
|
605
656
|
// also collect the corresponding vnode branch built earlier
|
|
@@ -629,7 +680,7 @@ const ssrTransformComponent = (node, context) => {
|
|
|
629
680
|
}
|
|
630
681
|
};
|
|
631
682
|
};
|
|
632
|
-
function ssrProcessComponent(node, context) {
|
|
683
|
+
function ssrProcessComponent(node, context, parent) {
|
|
633
684
|
const component = componentTypeMap.get(node);
|
|
634
685
|
if (!node.ssrCodegenNode) {
|
|
635
686
|
// this is a built-in component that fell-through.
|
|
@@ -645,19 +696,29 @@ function ssrProcessComponent(node, context) {
|
|
|
645
696
|
else {
|
|
646
697
|
// real fall-through: Transition / KeepAlive
|
|
647
698
|
// just render its children.
|
|
648
|
-
|
|
699
|
+
// #5352: if is at root level of a slot, push an empty string.
|
|
700
|
+
// this does not affect the final output, but avoids all-comment slot
|
|
701
|
+
// content of being treated as empty by ssrRenderSlot().
|
|
702
|
+
if (parent.type === WIP_SLOT) {
|
|
703
|
+
context.pushStringPart(``);
|
|
704
|
+
}
|
|
705
|
+
// #5351: filter out comment children inside transition
|
|
706
|
+
if (component === compilerDom.TRANSITION) {
|
|
707
|
+
node.children = node.children.filter(c => c.type !== 3 /* COMMENT */);
|
|
708
|
+
}
|
|
709
|
+
processChildren(node, context);
|
|
649
710
|
}
|
|
650
711
|
}
|
|
651
712
|
else {
|
|
652
713
|
// finish up slot function expressions from the 1st pass.
|
|
653
|
-
const wipEntries = wipMap$
|
|
714
|
+
const wipEntries = wipMap$2.get(node) || [];
|
|
654
715
|
for (let i = 0; i < wipEntries.length; i++) {
|
|
655
|
-
const { fn,
|
|
716
|
+
const { fn, vnodeBranch } = wipEntries[i];
|
|
656
717
|
// For each slot, we generate two branches: one SSR-optimized branch and
|
|
657
718
|
// one normal vnode-based branch. The branches are taken based on the
|
|
658
719
|
// presence of the 2nd `_push` argument (which is only present if the slot
|
|
659
720
|
// is called by `_ssrRenderSlot`.
|
|
660
|
-
fn.body = compilerDom.createIfStatement(compilerDom.createSimpleExpression(`_push`, false), processChildrenAsStatement(
|
|
721
|
+
fn.body = compilerDom.createIfStatement(compilerDom.createSimpleExpression(`_push`, false), processChildrenAsStatement(wipEntries[i], context, false, true /* withSlotScopeId */), vnodeBranch);
|
|
661
722
|
}
|
|
662
723
|
// component is inside a slot, inherit slot scope Id
|
|
663
724
|
if (context.withSlotScopeId) {
|
|
@@ -677,16 +738,25 @@ function ssrProcessComponent(node, context) {
|
|
|
677
738
|
const rawOptionsMap = new WeakMap();
|
|
678
739
|
const [baseNodeTransforms, baseDirectiveTransforms] = compilerDom.getBaseTransformPreset(true);
|
|
679
740
|
const vnodeNodeTransforms = [...baseNodeTransforms, ...compilerDom.DOMNodeTransforms];
|
|
680
|
-
const vnodeDirectiveTransforms =
|
|
741
|
+
const vnodeDirectiveTransforms = {
|
|
742
|
+
...baseDirectiveTransforms,
|
|
743
|
+
...compilerDom.DOMDirectiveTransforms
|
|
744
|
+
};
|
|
681
745
|
function createVNodeSlotBranch(props, children, parentContext) {
|
|
682
746
|
// apply a sub-transform using vnode-based transforms.
|
|
683
747
|
const rawOptions = rawOptionsMap.get(parentContext.root);
|
|
684
|
-
const subOptions =
|
|
748
|
+
const subOptions = {
|
|
749
|
+
...rawOptions,
|
|
685
750
|
// overwrite with vnode-based transforms
|
|
686
751
|
nodeTransforms: [
|
|
687
752
|
...vnodeNodeTransforms,
|
|
688
753
|
...(rawOptions.nodeTransforms || [])
|
|
689
|
-
],
|
|
754
|
+
],
|
|
755
|
+
directiveTransforms: {
|
|
756
|
+
...vnodeDirectiveTransforms,
|
|
757
|
+
...(rawOptions.directiveTransforms || {})
|
|
758
|
+
}
|
|
759
|
+
};
|
|
690
760
|
// wrap the children with a wrapper template for proper children treatment.
|
|
691
761
|
const wrapperNode = {
|
|
692
762
|
type: 1 /* ELEMENT */,
|
|
@@ -720,8 +790,8 @@ function subTransform(node, options, parentContext) {
|
|
|
720
790
|
// like normal render functions
|
|
721
791
|
childContext.ssr = false;
|
|
722
792
|
// inherit parent scope analysis state
|
|
723
|
-
childContext.scopes =
|
|
724
|
-
childContext.identifiers =
|
|
793
|
+
childContext.scopes = { ...parentContext.scopes };
|
|
794
|
+
childContext.identifiers = { ...parentContext.identifiers };
|
|
725
795
|
childContext.imports = parentContext.imports;
|
|
726
796
|
// traverse
|
|
727
797
|
compilerDom.traverseNode(childRoot, childContext);
|
|
@@ -777,7 +847,7 @@ function ssrCodegenTransform(ast, options) {
|
|
|
777
847
|
context.body.push(compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`]));
|
|
778
848
|
}
|
|
779
849
|
const isFragment = ast.children.length > 1 && ast.children.some(c => !compilerDom.isText(c));
|
|
780
|
-
processChildren(ast
|
|
850
|
+
processChildren(ast, context, isFragment);
|
|
781
851
|
ast.codegenNode = compilerDom.createBlockStatement(context.body);
|
|
782
852
|
// Finalize helpers.
|
|
783
853
|
// We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
|
|
@@ -828,10 +898,11 @@ function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
|
|
|
828
898
|
// ensure child inherits parent helpers
|
|
829
899
|
return createSSRTransformContext(parent.root, parent.options, parent.helpers, withSlotScopeId);
|
|
830
900
|
}
|
|
831
|
-
function processChildren(
|
|
901
|
+
function processChildren(parent, context, asFragment = false, disableNestedFragments = false) {
|
|
832
902
|
if (asFragment) {
|
|
833
903
|
context.pushStringPart(`<!--[-->`);
|
|
834
904
|
}
|
|
905
|
+
const { children } = parent;
|
|
835
906
|
for (let i = 0; i < children.length; i++) {
|
|
836
907
|
const child = children[i];
|
|
837
908
|
switch (child.type) {
|
|
@@ -841,7 +912,7 @@ function processChildren(children, context, asFragment = false, disableNestedFra
|
|
|
841
912
|
ssrProcessElement(child, context);
|
|
842
913
|
break;
|
|
843
914
|
case 1 /* COMPONENT */:
|
|
844
|
-
ssrProcessComponent(child, context);
|
|
915
|
+
ssrProcessComponent(child, context, parent);
|
|
845
916
|
break;
|
|
846
917
|
case 2 /* SLOT */:
|
|
847
918
|
ssrProcessSlotOutlet(child, context);
|
|
@@ -892,9 +963,9 @@ function processChildren(children, context, asFragment = false, disableNestedFra
|
|
|
892
963
|
context.pushStringPart(`<!--]-->`);
|
|
893
964
|
}
|
|
894
965
|
}
|
|
895
|
-
function processChildrenAsStatement(
|
|
966
|
+
function processChildrenAsStatement(parent, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
|
|
896
967
|
const childContext = createChildContext(parentContext, withSlotScopeId);
|
|
897
|
-
processChildren(
|
|
968
|
+
processChildren(parent, childContext, asFragment);
|
|
898
969
|
return compilerDom.createBlockStatement(childContext.body);
|
|
899
970
|
}
|
|
900
971
|
|
|
@@ -1013,7 +1084,8 @@ const ssrTransformShow = (dir, node, context) => {
|
|
|
1013
1084
|
};
|
|
1014
1085
|
};
|
|
1015
1086
|
|
|
1016
|
-
const
|
|
1087
|
+
const filterChild = (node) => node.children.filter(n => n.type !== 3 /* COMMENT */);
|
|
1088
|
+
const hasSingleChild = (node) => filterChild(node).length === 1;
|
|
1017
1089
|
const ssrInjectFallthroughAttrs = (node, context) => {
|
|
1018
1090
|
// _attrs is provided as a function argument.
|
|
1019
1091
|
// mark it as a known identifier so that it doesn't get prefixed by
|
|
@@ -1025,16 +1097,37 @@ const ssrInjectFallthroughAttrs = (node, context) => {
|
|
|
1025
1097
|
node.tagType === 1 /* COMPONENT */ &&
|
|
1026
1098
|
(compilerDom.isBuiltInType(node.tag, 'Transition') ||
|
|
1027
1099
|
compilerDom.isBuiltInType(node.tag, 'KeepAlive'))) {
|
|
1028
|
-
|
|
1029
|
-
|
|
1100
|
+
const rootChildren = filterChild(context.root);
|
|
1101
|
+
if (rootChildren.length === 1 && rootChildren[0] === node) {
|
|
1102
|
+
if (hasSingleChild(node)) {
|
|
1103
|
+
injectFallthroughAttrs(node.children[0]);
|
|
1104
|
+
}
|
|
1105
|
+
return;
|
|
1030
1106
|
}
|
|
1031
|
-
return;
|
|
1032
1107
|
}
|
|
1033
1108
|
const parent = context.parent;
|
|
1034
1109
|
if (!parent || parent.type !== 0 /* ROOT */) {
|
|
1035
1110
|
return;
|
|
1036
1111
|
}
|
|
1037
1112
|
if (node.type === 10 /* IF_BRANCH */ && hasSingleChild(node)) {
|
|
1113
|
+
// detect cases where the parent v-if is not the only root level node
|
|
1114
|
+
let hasEncounteredIf = false;
|
|
1115
|
+
for (const c of filterChild(parent)) {
|
|
1116
|
+
if (c.type === 9 /* IF */ ||
|
|
1117
|
+
(c.type === 1 /* ELEMENT */ && compilerDom.findDir(c, 'if'))) {
|
|
1118
|
+
// multiple root v-if
|
|
1119
|
+
if (hasEncounteredIf)
|
|
1120
|
+
return;
|
|
1121
|
+
hasEncounteredIf = true;
|
|
1122
|
+
}
|
|
1123
|
+
else if (
|
|
1124
|
+
// node before v-if
|
|
1125
|
+
!hasEncounteredIf ||
|
|
1126
|
+
// non else nodes
|
|
1127
|
+
!(c.type === 1 /* ELEMENT */ && compilerDom.findDir(c, /else/, true))) {
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1038
1131
|
injectFallthroughAttrs(node.children[0]);
|
|
1039
1132
|
}
|
|
1040
1133
|
else if (hasSingleChild(parent)) {
|
|
@@ -1111,16 +1204,27 @@ function injectCssVars(node) {
|
|
|
1111
1204
|
}
|
|
1112
1205
|
|
|
1113
1206
|
function compile(template, options = {}) {
|
|
1114
|
-
options =
|
|
1207
|
+
options = {
|
|
1208
|
+
...options,
|
|
1209
|
+
// apply DOM-specific parsing options
|
|
1210
|
+
...compilerDom.parserOptions,
|
|
1211
|
+
ssr: true,
|
|
1212
|
+
inSSR: true,
|
|
1213
|
+
scopeId: options.mode === 'function' ? null : options.scopeId,
|
|
1115
1214
|
// always prefix since compiler-ssr doesn't have size concern
|
|
1116
|
-
prefixIdentifiers: true,
|
|
1215
|
+
prefixIdentifiers: true,
|
|
1117
1216
|
// disable optimizations that are unnecessary for ssr
|
|
1118
|
-
cacheHandlers: false,
|
|
1217
|
+
cacheHandlers: false,
|
|
1218
|
+
hoistStatic: false
|
|
1219
|
+
};
|
|
1119
1220
|
const ast = compilerDom.baseParse(template, options);
|
|
1120
1221
|
// Save raw options for AST. This is needed when performing sub-transforms
|
|
1121
1222
|
// on slot vnode branches.
|
|
1122
1223
|
rawOptionsMap.set(ast, options);
|
|
1123
|
-
compilerDom.transform(ast,
|
|
1224
|
+
compilerDom.transform(ast, {
|
|
1225
|
+
...options,
|
|
1226
|
+
hoistStatic: false,
|
|
1227
|
+
nodeTransforms: [
|
|
1124
1228
|
ssrTransformIf,
|
|
1125
1229
|
ssrTransformFor,
|
|
1126
1230
|
compilerDom.trackVForSlotScopes,
|
|
@@ -1133,14 +1237,22 @@ function compile(template, options = {}) {
|
|
|
1133
1237
|
compilerDom.trackSlotScopes,
|
|
1134
1238
|
compilerDom.transformStyle,
|
|
1135
1239
|
...(options.nodeTransforms || []) // user transforms
|
|
1136
|
-
],
|
|
1240
|
+
],
|
|
1241
|
+
directiveTransforms: {
|
|
1137
1242
|
// reusing core v-bind
|
|
1138
|
-
bind: compilerDom.transformBind,
|
|
1243
|
+
bind: compilerDom.transformBind,
|
|
1244
|
+
on: compilerDom.transformOn,
|
|
1139
1245
|
// model and show has dedicated SSR handling
|
|
1140
|
-
model: ssrTransformModel,
|
|
1246
|
+
model: ssrTransformModel,
|
|
1247
|
+
show: ssrTransformShow,
|
|
1141
1248
|
// the following are ignored during SSR
|
|
1142
|
-
on:
|
|
1143
|
-
|
|
1249
|
+
// on: noopDirectiveTransform,
|
|
1250
|
+
cloak: compilerDom.noopDirectiveTransform,
|
|
1251
|
+
once: compilerDom.noopDirectiveTransform,
|
|
1252
|
+
memo: compilerDom.noopDirectiveTransform,
|
|
1253
|
+
...(options.directiveTransforms || {}) // user transforms
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1144
1256
|
// traverse the template AST and convert into SSR codegen AST
|
|
1145
1257
|
// by replacing ast.codegenNode.
|
|
1146
1258
|
ssrCodegenTransform(ast, options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/compiler-ssr",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.35",
|
|
4
4
|
"description": "@vue/compiler-ssr",
|
|
5
5
|
"main": "dist/compiler-ssr.cjs.js",
|
|
6
6
|
"types": "dist/compiler-ssr.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-ssr#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@vue/shared": "3.2.
|
|
32
|
-
"@vue/compiler-dom": "3.2.
|
|
31
|
+
"@vue/shared": "3.2.35",
|
|
32
|
+
"@vue/compiler-dom": "3.2.35"
|
|
33
33
|
}
|
|
34
34
|
}
|