@vue/compiler-ssr 3.2.46 → 3.3.0-alpha.1

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.
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var compilerDom = require('@vue/compiler-dom');
4
6
  var shared = require('@vue/shared');
5
7
 
@@ -23,1250 +25,1256 @@ const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
23
25
  const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
24
26
  const SSR_GET_DIRECTIVE_PROPS = Symbol(`ssrGetDirectiveProps`);
25
27
  const ssrHelpers = {
26
- [SSR_INTERPOLATE]: `ssrInterpolate`,
27
- [SSR_RENDER_VNODE]: `ssrRenderVNode`,
28
- [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
29
- [SSR_RENDER_SLOT]: `ssrRenderSlot`,
30
- [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
31
- [SSR_RENDER_CLASS]: `ssrRenderClass`,
32
- [SSR_RENDER_STYLE]: `ssrRenderStyle`,
33
- [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
34
- [SSR_RENDER_ATTR]: `ssrRenderAttr`,
35
- [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
36
- [SSR_RENDER_LIST]: `ssrRenderList`,
37
- [SSR_INCLUDE_BOOLEAN_ATTR]: `ssrIncludeBooleanAttr`,
38
- [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
39
- [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
40
- [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
41
- [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
42
- [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
43
- [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
44
- [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
28
+ [SSR_INTERPOLATE]: `ssrInterpolate`,
29
+ [SSR_RENDER_VNODE]: `ssrRenderVNode`,
30
+ [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
31
+ [SSR_RENDER_SLOT]: `ssrRenderSlot`,
32
+ [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
33
+ [SSR_RENDER_CLASS]: `ssrRenderClass`,
34
+ [SSR_RENDER_STYLE]: `ssrRenderStyle`,
35
+ [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
36
+ [SSR_RENDER_ATTR]: `ssrRenderAttr`,
37
+ [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
38
+ [SSR_RENDER_LIST]: `ssrRenderList`,
39
+ [SSR_INCLUDE_BOOLEAN_ATTR]: `ssrIncludeBooleanAttr`,
40
+ [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
41
+ [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
42
+ [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
43
+ [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
44
+ [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
45
+ [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
46
+ [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
45
47
  };
46
- // Note: these are helpers imported from @vue/server-renderer
47
- // make sure the names match!
48
48
  compilerDom.registerRuntimeHelpers(ssrHelpers);
49
49
 
50
- // Plugin for the first transform pass, which simply constructs the AST node
51
- const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(/^(if|else|else-if)$/, compilerDom.processIf);
52
- // This is called during the 2nd transform pass to construct the SSR-specific
53
- // codegen nodes.
50
+ const ssrTransformIf = compilerDom.createStructuralDirectiveTransform(
51
+ /^(if|else|else-if)$/,
52
+ compilerDom.processIf
53
+ );
54
54
  function ssrProcessIf(node, context, disableNestedFragments = false) {
55
- const [rootBranch] = node.branches;
56
- const ifStatement = compilerDom.createIfStatement(rootBranch.condition, processIfBranch(rootBranch, context, disableNestedFragments));
57
- context.pushStatement(ifStatement);
58
- let currentIf = ifStatement;
59
- for (let i = 1; i < node.branches.length; i++) {
60
- const branch = node.branches[i];
61
- const branchBlockStatement = processIfBranch(branch, context, disableNestedFragments);
62
- if (branch.condition) {
63
- // else-if
64
- currentIf = currentIf.alternate = compilerDom.createIfStatement(branch.condition, branchBlockStatement);
65
- }
66
- else {
67
- // else
68
- currentIf.alternate = branchBlockStatement;
69
- }
70
- }
71
- if (!currentIf.alternate) {
72
- currentIf.alternate = compilerDom.createBlockStatement([
73
- compilerDom.createCallExpression(`_push`, ['`<!---->`'])
74
- ]);
55
+ const [rootBranch] = node.branches;
56
+ const ifStatement = compilerDom.createIfStatement(
57
+ rootBranch.condition,
58
+ processIfBranch(rootBranch, context, disableNestedFragments)
59
+ );
60
+ context.pushStatement(ifStatement);
61
+ let currentIf = ifStatement;
62
+ for (let i = 1; i < node.branches.length; i++) {
63
+ const branch = node.branches[i];
64
+ const branchBlockStatement = processIfBranch(
65
+ branch,
66
+ context,
67
+ disableNestedFragments
68
+ );
69
+ if (branch.condition) {
70
+ currentIf = currentIf.alternate = compilerDom.createIfStatement(
71
+ branch.condition,
72
+ branchBlockStatement
73
+ );
74
+ } else {
75
+ currentIf.alternate = branchBlockStatement;
75
76
  }
77
+ }
78
+ if (!currentIf.alternate) {
79
+ currentIf.alternate = compilerDom.createBlockStatement([
80
+ compilerDom.createCallExpression(`_push`, ["`<!---->`"])
81
+ ]);
82
+ }
76
83
  }
77
84
  function processIfBranch(branch, context, disableNestedFragments = false) {
78
- const { children } = branch;
79
- const needFragmentWrapper = !disableNestedFragments &&
80
- (children.length !== 1 || children[0].type !== 1 /* NodeTypes.ELEMENT */) &&
81
- // optimize away nested fragments when the only child is a ForNode
82
- !(children.length === 1 && children[0].type === 11 /* NodeTypes.FOR */);
83
- return processChildrenAsStatement(branch, context, needFragmentWrapper);
85
+ const { children } = branch;
86
+ const needFragmentWrapper = !disableNestedFragments && (children.length !== 1 || children[0].type !== "element") && // optimize away nested fragments when the only child is a ForNode
87
+ !(children.length === 1 && children[0].type === 11);
88
+ return processChildrenAsStatement(branch, context, needFragmentWrapper);
84
89
  }
85
90
 
86
- // Plugin for the first transform pass, which simply constructs the AST node
87
- const ssrTransformFor = compilerDom.createStructuralDirectiveTransform('for', compilerDom.processFor);
88
- // This is called during the 2nd transform pass to construct the SSR-specific
89
- // codegen nodes.
91
+ const ssrTransformFor = compilerDom.createStructuralDirectiveTransform(
92
+ "for",
93
+ compilerDom.processFor
94
+ );
90
95
  function ssrProcessFor(node, context, disableNestedFragments = false) {
91
- const needFragmentWrapper = !disableNestedFragments &&
92
- (node.children.length !== 1 || node.children[0].type !== 1 /* NodeTypes.ELEMENT */);
93
- const renderLoop = compilerDom.createFunctionExpression(compilerDom.createForLoopParams(node.parseResult));
94
- renderLoop.body = processChildrenAsStatement(node, context, needFragmentWrapper);
95
- // v-for always renders a fragment unless explicitly disabled
96
- if (!disableNestedFragments) {
97
- context.pushStringPart(`<!--[-->`);
98
- }
99
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_LIST), [
100
- node.source,
101
- renderLoop
102
- ]));
103
- if (!disableNestedFragments) {
104
- context.pushStringPart(`<!--]-->`);
105
- }
96
+ const needFragmentWrapper = !disableNestedFragments && (node.children.length !== 1 || node.children[0].type !== "element");
97
+ const renderLoop = compilerDom.createFunctionExpression(
98
+ compilerDom.createForLoopParams(node.parseResult)
99
+ );
100
+ renderLoop.body = processChildrenAsStatement(
101
+ node,
102
+ context,
103
+ needFragmentWrapper
104
+ );
105
+ if (!disableNestedFragments) {
106
+ context.pushStringPart(`<!--[-->`);
107
+ }
108
+ context.pushStatement(
109
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_LIST), [
110
+ node.source,
111
+ renderLoop
112
+ ])
113
+ );
114
+ if (!disableNestedFragments) {
115
+ context.pushStringPart(`<!--]-->`);
116
+ }
106
117
  }
107
118
 
108
119
  const ssrTransformSlotOutlet = (node, context) => {
109
- if (compilerDom.isSlotOutlet(node)) {
110
- const { slotName, slotProps } = compilerDom.processSlotOutlet(node, context);
111
- const args = [
112
- `_ctx.$slots`,
113
- slotName,
114
- slotProps || `{}`,
115
- // fallback content placeholder. will be replaced in the process phase
116
- `null`,
117
- `_push`,
118
- `_parent`
119
- ];
120
- // inject slot scope id if current template uses :slotted
121
- if (context.scopeId && context.slotted !== false) {
122
- args.push(`"${context.scopeId}-s"`);
123
- }
124
- let method = SSR_RENDER_SLOT;
125
- // #3989
126
- // check if this is a single slot inside a transition wrapper - since
127
- // transition will unwrap the slot fragment into a single vnode at runtime,
128
- // we need to avoid rendering the slot as a fragment.
129
- const parent = context.parent;
130
- if (parent &&
131
- parent.type === 1 /* NodeTypes.ELEMENT */ &&
132
- parent.tagType === 1 /* ElementTypes.COMPONENT */ &&
133
- compilerDom.resolveComponentType(parent, context, true) === compilerDom.TRANSITION &&
134
- parent.children.filter(c => c.type === 1 /* NodeTypes.ELEMENT */).length === 1) {
135
- method = SSR_RENDER_SLOT_INNER;
136
- if (!(context.scopeId && context.slotted !== false)) {
137
- args.push('null');
138
- }
139
- args.push('true');
140
- }
141
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
120
+ if (compilerDom.isSlotOutlet(node)) {
121
+ const { slotName, slotProps } = compilerDom.processSlotOutlet(node, context);
122
+ const args = [
123
+ `_ctx.$slots`,
124
+ slotName,
125
+ slotProps || `{}`,
126
+ // fallback content placeholder. will be replaced in the process phase
127
+ `null`,
128
+ `_push`,
129
+ `_parent`
130
+ ];
131
+ if (context.scopeId && context.slotted !== false) {
132
+ args.push(`"${context.scopeId}-s"`);
133
+ }
134
+ let method = SSR_RENDER_SLOT;
135
+ const parent = context.parent;
136
+ if (parent && parent.type === "element" && parent.tagType === 1 && compilerDom.resolveComponentType(parent, context, true) === compilerDom.TRANSITION && parent.children.filter((c) => c.type === "element").length === 1) {
137
+ method = SSR_RENDER_SLOT_INNER;
138
+ if (!(context.scopeId && context.slotted !== false)) {
139
+ args.push("null");
140
+ }
141
+ args.push("true");
142
142
  }
143
+ node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(method), args);
144
+ }
143
145
  };
144
146
  function ssrProcessSlotOutlet(node, context) {
145
- const renderCall = node.ssrCodegenNode;
146
- // has fallback content
147
- if (node.children.length) {
148
- const fallbackRenderFn = compilerDom.createFunctionExpression([]);
149
- fallbackRenderFn.body = processChildrenAsStatement(node, context);
150
- // _renderSlot(slots, name, props, fallback, ...)
151
- renderCall.arguments[3] = fallbackRenderFn;
152
- }
153
- // Forwarded <slot/>. Merge slot scope ids
154
- if (context.withSlotScopeId) {
155
- const slotScopeId = renderCall.arguments[6];
156
- renderCall.arguments[6] = slotScopeId
157
- ? `${slotScopeId} + _scopeId`
158
- : `_scopeId`;
159
- }
160
- context.pushStatement(node.ssrCodegenNode);
147
+ const renderCall = node.ssrCodegenNode;
148
+ if (node.children.length) {
149
+ const fallbackRenderFn = compilerDom.createFunctionExpression([]);
150
+ fallbackRenderFn.body = processChildrenAsStatement(node, context);
151
+ renderCall.arguments[3] = fallbackRenderFn;
152
+ }
153
+ if (context.withSlotScopeId) {
154
+ const slotScopeId = renderCall.arguments[6];
155
+ renderCall.arguments[6] = slotScopeId ? `${slotScopeId} + _scopeId` : `_scopeId`;
156
+ }
157
+ context.pushStatement(node.ssrCodegenNode);
161
158
  }
162
159
 
163
160
  function createSSRCompilerError(code, loc) {
164
- return compilerDom.createCompilerError(code, loc, SSRErrorMessages);
161
+ return compilerDom.createCompilerError(code, loc, SSRErrorMessages);
165
162
  }
166
163
  const SSRErrorMessages = {
167
- [62 /* SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME */]: `Unsafe attribute name for SSR.`,
168
- [63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */]: `Missing the 'to' prop on teleport element.`,
169
- [64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */]: `Invalid AST node during SSR transform.`
164
+ [62]: `Unsafe attribute name for SSR.`,
165
+ [63]: `Missing the 'to' prop on teleport element.`,
166
+ [64]: `Invalid AST node during SSR transform.`
170
167
  };
171
168
 
172
- // Note: this is a 2nd-pass codegen transform.
173
169
  function ssrProcessTeleport(node, context) {
174
- const targetProp = compilerDom.findProp(node, 'to');
175
- if (!targetProp) {
176
- context.onError(createSSRCompilerError(63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */, node.loc));
177
- return;
178
- }
179
- let target;
180
- if (targetProp.type === 6 /* NodeTypes.ATTRIBUTE */) {
181
- target =
182
- targetProp.value && compilerDom.createSimpleExpression(targetProp.value.content, true);
183
- }
184
- else {
185
- target = targetProp.exp;
186
- }
187
- if (!target) {
188
- context.onError(createSSRCompilerError(63 /* SSRErrorCodes.X_SSR_NO_TELEPORT_TARGET */, targetProp.loc));
189
- return;
190
- }
191
- const disabledProp = compilerDom.findProp(node, 'disabled', false, true /* allow empty */);
192
- const disabled = disabledProp
193
- ? disabledProp.type === 6 /* NodeTypes.ATTRIBUTE */
194
- ? `true`
195
- : disabledProp.exp || `false`
196
- : `false`;
197
- const contentRenderFn = compilerDom.createFunctionExpression([`_push`], undefined, // Body is added later
198
- true, // newline
199
- false, // isSlot
200
- node.loc);
201
- contentRenderFn.body = processChildrenAsStatement(node, context);
202
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
203
- `_push`,
204
- contentRenderFn,
205
- target,
206
- disabled,
207
- `_parent`
208
- ]));
170
+ const targetProp = compilerDom.findProp(node, "to");
171
+ if (!targetProp) {
172
+ context.onError(
173
+ createSSRCompilerError(63, node.loc)
174
+ );
175
+ return;
176
+ }
177
+ let target;
178
+ if (targetProp.type === 6) {
179
+ target = targetProp.value && compilerDom.createSimpleExpression(targetProp.value.content, true);
180
+ } else {
181
+ target = targetProp.exp;
182
+ }
183
+ if (!target) {
184
+ context.onError(
185
+ createSSRCompilerError(
186
+ 63,
187
+ targetProp.loc
188
+ )
189
+ );
190
+ return;
191
+ }
192
+ const disabledProp = compilerDom.findProp(
193
+ node,
194
+ "disabled",
195
+ false,
196
+ true
197
+ /* allow empty */
198
+ );
199
+ const disabled = disabledProp ? disabledProp.type === 6 ? `true` : disabledProp.exp || `false` : `false`;
200
+ const contentRenderFn = compilerDom.createFunctionExpression(
201
+ [`_push`],
202
+ void 0,
203
+ // Body is added later
204
+ true,
205
+ // newline
206
+ false,
207
+ // isSlot
208
+ node.loc
209
+ );
210
+ contentRenderFn.body = processChildrenAsStatement(node, context);
211
+ context.pushStatement(
212
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
213
+ `_push`,
214
+ contentRenderFn,
215
+ target,
216
+ disabled,
217
+ `_parent`
218
+ ])
219
+ );
209
220
  }
210
221
 
211
- const wipMap$2 = new WeakMap();
212
- // phase 1
222
+ const wipMap$2 = /* @__PURE__ */ new WeakMap();
213
223
  function ssrTransformSuspense(node, context) {
214
- return () => {
215
- if (node.children.length) {
216
- const wipEntry = {
217
- slotsExp: null,
218
- wipSlots: []
219
- };
220
- wipMap$2.set(node, wipEntry);
221
- wipEntry.slotsExp = compilerDom.buildSlots(node, context, (_props, children, loc) => {
222
- const fn = compilerDom.createFunctionExpression([], undefined, // no return, assign body later
223
- true, // newline
224
- false, // suspense slots are not treated as normal slots
225
- loc);
226
- wipEntry.wipSlots.push({
227
- fn,
228
- children
229
- });
230
- return fn;
231
- }).slots;
232
- }
233
- };
224
+ return () => {
225
+ if (node.children.length) {
226
+ const wipEntry = {
227
+ slotsExp: null,
228
+ // to be immediately set
229
+ wipSlots: []
230
+ };
231
+ wipMap$2.set(node, wipEntry);
232
+ wipEntry.slotsExp = compilerDom.buildSlots(node, context, (_props, children, loc) => {
233
+ const fn = compilerDom.createFunctionExpression(
234
+ [],
235
+ void 0,
236
+ // no return, assign body later
237
+ true,
238
+ // newline
239
+ false,
240
+ // suspense slots are not treated as normal slots
241
+ loc
242
+ );
243
+ wipEntry.wipSlots.push({
244
+ fn,
245
+ children
246
+ });
247
+ return fn;
248
+ }).slots;
249
+ }
250
+ };
234
251
  }
235
- // phase 2
236
252
  function ssrProcessSuspense(node, context) {
237
- // complete wip slots with ssr code
238
- const wipEntry = wipMap$2.get(node);
239
- if (!wipEntry) {
240
- return;
241
- }
242
- const { slotsExp, wipSlots } = wipEntry;
243
- for (let i = 0; i < wipSlots.length; i++) {
244
- const slot = wipSlots[i];
245
- slot.fn.body = processChildrenAsStatement(slot, context);
246
- }
247
- // _push(ssrRenderSuspense(slots))
248
- context.pushStatement(compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
249
- `_push`,
250
- slotsExp
251
- ]));
253
+ const wipEntry = wipMap$2.get(node);
254
+ if (!wipEntry) {
255
+ return;
256
+ }
257
+ const { slotsExp, wipSlots } = wipEntry;
258
+ for (let i = 0; i < wipSlots.length; i++) {
259
+ const slot = wipSlots[i];
260
+ slot.fn.body = processChildrenAsStatement(slot, context);
261
+ }
262
+ context.pushStatement(
263
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
264
+ `_push`,
265
+ slotsExp
266
+ ])
267
+ );
252
268
  }
253
269
 
254
- // for directives with children overwrite (e.g. v-html & v-text), we need to
255
- // store the raw children so that they can be added in the 2nd pass.
256
- const rawChildrenMap = new WeakMap();
270
+ const rawChildrenMap = /* @__PURE__ */ new WeakMap();
257
271
  const ssrTransformElement = (node, context) => {
258
- if (node.type !== 1 /* NodeTypes.ELEMENT */ ||
259
- node.tagType !== 0 /* ElementTypes.ELEMENT */) {
260
- return;
261
- }
262
- return function ssrPostTransformElement() {
263
- // element
264
- // generate the template literal representing the open tag.
265
- const openTag = [`<${node.tag}`];
266
- // some tags need to be passed to runtime for special checks
267
- const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
268
- // v-bind="obj", v-bind:[key] and custom directives can potentially
269
- // overwrite other static attrs and can affect final rendering result,
270
- // so when they are present we need to bail out to full `renderAttrs`
271
- const hasDynamicVBind = compilerDom.hasDynamicKeyVBind(node);
272
- const hasCustomDir = node.props.some(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && !shared.isBuiltInDirective(p.name));
273
- const needMergeProps = hasDynamicVBind || hasCustomDir;
274
- if (needMergeProps) {
275
- const { props, directives } = compilerDom.buildProps(node, context, node.props, false /* isComponent */, false /* isDynamicComponent */, true /* ssr */);
276
- if (props || directives.length) {
277
- const mergedProps = buildSSRProps(props, directives, context);
278
- const propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [mergedProps]);
279
- if (node.tag === 'textarea') {
280
- const existingText = node.children[0];
281
- // If interpolation, this is dynamic <textarea> content, potentially
282
- // injected by v-model and takes higher priority than v-bind value
283
- if (!existingText || existingText.type !== 5 /* NodeTypes.INTERPOLATION */) {
284
- // <textarea> with dynamic v-bind. We don't know if the final props
285
- // will contain .value, so we will have to do something special:
286
- // assign the merged props to a temp variable, and check whether
287
- // it contains value (if yes, render is as children).
288
- const tempId = `_temp${context.temps++}`;
289
- propsExp.arguments = [
290
- compilerDom.createAssignmentExpression(compilerDom.createSimpleExpression(tempId, false), mergedProps)
291
- ];
292
- rawChildrenMap.set(node, compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
293
- compilerDom.createConditionalExpression(compilerDom.createSimpleExpression(`"value" in ${tempId}`, false), compilerDom.createSimpleExpression(`${tempId}.value`, false), compilerDom.createSimpleExpression(existingText ? existingText.content : ``, true), false)
294
- ]));
295
- }
296
- }
297
- else if (node.tag === 'input') {
298
- // <input v-bind="obj" v-model>
299
- // we need to determine the props to render for the dynamic v-model
300
- // and merge it with the v-bind expression.
301
- const vModel = findVModel(node);
302
- if (vModel) {
303
- // 1. save the props (san v-model) in a temp variable
304
- const tempId = `_temp${context.temps++}`;
305
- const tempExp = compilerDom.createSimpleExpression(tempId, false);
306
- propsExp.arguments = [
307
- compilerDom.createSequenceExpression([
308
- compilerDom.createAssignmentExpression(tempExp, mergedProps),
309
- compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), [
310
- tempExp,
311
- compilerDom.createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
312
- tempExp,
313
- vModel.exp // model
314
- ])
315
- ])
316
- ])
317
- ];
318
- }
319
- }
320
- if (needTagForRuntime) {
321
- propsExp.arguments.push(`"${node.tag}"`);
322
- }
323
- openTag.push(propsExp);
324
- }
272
+ if (node.type !== "element" || node.tagType !== 0) {
273
+ return;
274
+ }
275
+ return function ssrPostTransformElement() {
276
+ const openTag = [`<${node.tag}`];
277
+ const needTagForRuntime = node.tag === "textarea" || node.tag.indexOf("-") > 0;
278
+ const hasDynamicVBind = compilerDom.hasDynamicKeyVBind(node);
279
+ const hasCustomDir = node.props.some(
280
+ (p) => p.type === 7 && !shared.isBuiltInDirective(p.name)
281
+ );
282
+ const needMergeProps = hasDynamicVBind || hasCustomDir;
283
+ if (needMergeProps) {
284
+ const { props, directives } = compilerDom.buildProps(
285
+ node,
286
+ context,
287
+ node.props,
288
+ false,
289
+ false,
290
+ true
291
+ /* ssr */
292
+ );
293
+ if (props || directives.length) {
294
+ const mergedProps = buildSSRProps(props, directives, context);
295
+ const propsExp = compilerDom.createCallExpression(
296
+ context.helper(SSR_RENDER_ATTRS),
297
+ [mergedProps]
298
+ );
299
+ if (node.tag === "textarea") {
300
+ const existingText = node.children[0];
301
+ if (!existingText || existingText.type !== 5) {
302
+ const tempId = `_temp${context.temps++}`;
303
+ propsExp.arguments = [
304
+ compilerDom.createAssignmentExpression(
305
+ compilerDom.createSimpleExpression(tempId, false),
306
+ mergedProps
307
+ )
308
+ ];
309
+ rawChildrenMap.set(
310
+ node,
311
+ compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [
312
+ compilerDom.createConditionalExpression(
313
+ compilerDom.createSimpleExpression(`"value" in ${tempId}`, false),
314
+ compilerDom.createSimpleExpression(`${tempId}.value`, false),
315
+ compilerDom.createSimpleExpression(
316
+ existingText ? existingText.content : ``,
317
+ true
318
+ ),
319
+ false
320
+ )
321
+ ])
322
+ );
323
+ }
324
+ } else if (node.tag === "input") {
325
+ const vModel = findVModel(node);
326
+ if (vModel) {
327
+ const tempId = `_temp${context.temps++}`;
328
+ const tempExp = compilerDom.createSimpleExpression(tempId, false);
329
+ propsExp.arguments = [
330
+ compilerDom.createSequenceExpression([
331
+ compilerDom.createAssignmentExpression(tempExp, mergedProps),
332
+ compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), [
333
+ tempExp,
334
+ compilerDom.createCallExpression(
335
+ context.helper(SSR_GET_DYNAMIC_MODEL_PROPS),
336
+ [
337
+ tempExp,
338
+ // existing props
339
+ vModel.exp
340
+ // model
341
+ ]
342
+ )
343
+ ])
344
+ ])
345
+ ];
346
+ }
347
+ }
348
+ if (needTagForRuntime) {
349
+ propsExp.arguments.push(`"${node.tag}"`);
325
350
  }
326
- // book keeping static/dynamic class merging.
327
- let dynamicClassBinding = undefined;
328
- let staticClassBinding = undefined;
329
- // all style bindings are converted to dynamic by transformStyle.
330
- // but we need to make sure to merge them.
331
- let dynamicStyleBinding = undefined;
332
- for (let i = 0; i < node.props.length; i++) {
333
- const prop = node.props[i];
334
- // ignore true-value/false-value on input
335
- if (node.tag === 'input' && isTrueFalseValue(prop)) {
336
- continue;
351
+ openTag.push(propsExp);
352
+ }
353
+ }
354
+ let dynamicClassBinding = void 0;
355
+ let staticClassBinding = void 0;
356
+ let dynamicStyleBinding = void 0;
357
+ for (let i = 0; i < node.props.length; i++) {
358
+ const prop = node.props[i];
359
+ if (node.tag === "input" && isTrueFalseValue(prop)) {
360
+ continue;
361
+ }
362
+ if (prop.type === 7) {
363
+ if (prop.name === "html" && prop.exp) {
364
+ rawChildrenMap.set(node, prop.exp);
365
+ } else if (prop.name === "text" && prop.exp) {
366
+ node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
367
+ } else if (prop.name === "slot") {
368
+ context.onError(
369
+ compilerDom.createCompilerError(40, prop.loc)
370
+ );
371
+ } else if (isTextareaWithValue(node, prop) && prop.exp) {
372
+ if (!needMergeProps) {
373
+ node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
374
+ }
375
+ } else if (!needMergeProps && prop.name !== "on") {
376
+ const directiveTransform = context.directiveTransforms[prop.name];
377
+ if (directiveTransform) {
378
+ const { props, ssrTagParts } = directiveTransform(
379
+ prop,
380
+ node,
381
+ context
382
+ );
383
+ if (ssrTagParts) {
384
+ openTag.push(...ssrTagParts);
337
385
  }
338
- // special cases with children override
339
- if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
340
- if (prop.name === 'html' && prop.exp) {
341
- rawChildrenMap.set(node, prop.exp);
342
- }
343
- else if (prop.name === 'text' && prop.exp) {
344
- node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
345
- }
346
- else if (prop.name === 'slot') {
347
- context.onError(compilerDom.createCompilerError(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, prop.loc));
386
+ for (let j = 0; j < props.length; j++) {
387
+ const { key, value } = props[j];
388
+ if (compilerDom.isStaticExp(key)) {
389
+ let attrName = key.content;
390
+ if (attrName === "key" || attrName === "ref") {
391
+ continue;
348
392
  }
349
- else if (isTextareaWithValue(node, prop) && prop.exp) {
350
- if (!needMergeProps) {
351
- node.children = [compilerDom.createInterpolation(prop.exp, prop.loc)];
352
- }
393
+ if (attrName === "class") {
394
+ openTag.push(
395
+ ` class="`,
396
+ dynamicClassBinding = compilerDom.createCallExpression(
397
+ context.helper(SSR_RENDER_CLASS),
398
+ [value]
399
+ ),
400
+ `"`
401
+ );
402
+ } else if (attrName === "style") {
403
+ if (dynamicStyleBinding) {
404
+ mergeCall(dynamicStyleBinding, value);
405
+ } else {
406
+ openTag.push(
407
+ ` style="`,
408
+ dynamicStyleBinding = compilerDom.createCallExpression(
409
+ context.helper(SSR_RENDER_STYLE),
410
+ [value]
411
+ ),
412
+ `"`
413
+ );
414
+ }
415
+ } else {
416
+ attrName = node.tag.indexOf("-") > 0 ? attrName : shared.propsToAttrMap[attrName] || attrName.toLowerCase();
417
+ if (shared.isBooleanAttr(attrName)) {
418
+ openTag.push(
419
+ compilerDom.createConditionalExpression(
420
+ compilerDom.createCallExpression(
421
+ context.helper(SSR_INCLUDE_BOOLEAN_ATTR),
422
+ [value]
423
+ ),
424
+ compilerDom.createSimpleExpression(" " + attrName, true),
425
+ compilerDom.createSimpleExpression("", true),
426
+ false
427
+ /* no newline */
428
+ )
429
+ );
430
+ } else if (shared.isSSRSafeAttrName(attrName)) {
431
+ openTag.push(
432
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTR), [
433
+ key,
434
+ value
435
+ ])
436
+ );
437
+ } else {
438
+ context.onError(
439
+ createSSRCompilerError(
440
+ 62,
441
+ key.loc
442
+ )
443
+ );
444
+ }
353
445
  }
354
- else if (!needMergeProps && prop.name !== 'on') {
355
- // Directive transforms.
356
- const directiveTransform = context.directiveTransforms[prop.name];
357
- if (directiveTransform) {
358
- const { props, ssrTagParts } = directiveTransform(prop, node, context);
359
- if (ssrTagParts) {
360
- openTag.push(...ssrTagParts);
361
- }
362
- for (let j = 0; j < props.length; j++) {
363
- const { key, value } = props[j];
364
- if (compilerDom.isStaticExp(key)) {
365
- let attrName = key.content;
366
- // static key attr
367
- if (attrName === 'key' || attrName === 'ref') {
368
- continue;
369
- }
370
- if (attrName === 'class') {
371
- openTag.push(` class="`, (dynamicClassBinding = compilerDom.createCallExpression(context.helper(SSR_RENDER_CLASS), [value])), `"`);
372
- }
373
- else if (attrName === 'style') {
374
- if (dynamicStyleBinding) {
375
- // already has style binding, merge into it.
376
- mergeCall(dynamicStyleBinding, value);
377
- }
378
- else {
379
- openTag.push(` style="`, (dynamicStyleBinding = compilerDom.createCallExpression(context.helper(SSR_RENDER_STYLE), [value])), `"`);
380
- }
381
- }
382
- else {
383
- attrName =
384
- node.tag.indexOf('-') > 0
385
- ? attrName // preserve raw name on custom elements
386
- : shared.propsToAttrMap[attrName] || attrName.toLowerCase();
387
- if (shared.isBooleanAttr(attrName)) {
388
- openTag.push(compilerDom.createConditionalExpression(compilerDom.createCallExpression(context.helper(SSR_INCLUDE_BOOLEAN_ATTR), [value]), compilerDom.createSimpleExpression(' ' + attrName, true), compilerDom.createSimpleExpression('', true), false /* no newline */));
389
- }
390
- else if (shared.isSSRSafeAttrName(attrName)) {
391
- openTag.push(compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTR), [
392
- key,
393
- value
394
- ]));
395
- }
396
- else {
397
- context.onError(createSSRCompilerError(62 /* SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME */, key.loc));
398
- }
399
- }
400
- }
401
- else {
402
- // dynamic key attr
403
- // this branch is only encountered for custom directive
404
- // transforms that returns properties with dynamic keys
405
- const args = [key, value];
406
- if (needTagForRuntime) {
407
- args.push(`"${node.tag}"`);
408
- }
409
- openTag.push(compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_ATTR), args));
410
- }
411
- }
412
- }
413
- }
414
- }
415
- else {
416
- // special case: value on <textarea>
417
- if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
418
- rawChildrenMap.set(node, shared.escapeHtml(prop.value.content));
419
- }
420
- else if (!needMergeProps) {
421
- if (prop.name === 'key' || prop.name === 'ref') {
422
- continue;
423
- }
424
- // static prop
425
- if (prop.name === 'class' && prop.value) {
426
- staticClassBinding = JSON.stringify(prop.value.content);
427
- }
428
- openTag.push(` ${prop.name}` +
429
- (prop.value ? `="${shared.escapeHtml(prop.value.content)}"` : ``));
446
+ } else {
447
+ const args = [key, value];
448
+ if (needTagForRuntime) {
449
+ args.push(`"${node.tag}"`);
430
450
  }
451
+ openTag.push(
452
+ compilerDom.createCallExpression(
453
+ context.helper(SSR_RENDER_DYNAMIC_ATTR),
454
+ args
455
+ )
456
+ );
457
+ }
431
458
  }
459
+ }
432
460
  }
433
- // handle co-existence of dynamic + static class bindings
434
- if (dynamicClassBinding && staticClassBinding) {
435
- mergeCall(dynamicClassBinding, staticClassBinding);
436
- removeStaticBinding(openTag, 'class');
437
- }
438
- if (context.scopeId) {
439
- openTag.push(` ${context.scopeId}`);
461
+ } else {
462
+ if (node.tag === "textarea" && prop.name === "value" && prop.value) {
463
+ rawChildrenMap.set(node, shared.escapeHtml(prop.value.content));
464
+ } else if (!needMergeProps) {
465
+ if (prop.name === "key" || prop.name === "ref") {
466
+ continue;
467
+ }
468
+ if (prop.name === "class" && prop.value) {
469
+ staticClassBinding = JSON.stringify(prop.value.content);
470
+ }
471
+ openTag.push(
472
+ ` ${prop.name}` + (prop.value ? `="${shared.escapeHtml(prop.value.content)}"` : ``)
473
+ );
440
474
  }
441
- node.ssrCodegenNode = compilerDom.createTemplateLiteral(openTag);
442
- };
475
+ }
476
+ }
477
+ if (dynamicClassBinding && staticClassBinding) {
478
+ mergeCall(dynamicClassBinding, staticClassBinding);
479
+ removeStaticBinding(openTag, "class");
480
+ }
481
+ if (context.scopeId) {
482
+ openTag.push(` ${context.scopeId}`);
483
+ }
484
+ node.ssrCodegenNode = compilerDom.createTemplateLiteral(openTag);
485
+ };
443
486
  };
444
487
  function buildSSRProps(props, directives, context) {
445
- let mergePropsArgs = [];
446
- if (props) {
447
- if (props.type === 14 /* NodeTypes.JS_CALL_EXPRESSION */) {
448
- // already a mergeProps call
449
- mergePropsArgs = props.arguments;
450
- }
451
- else {
452
- mergePropsArgs.push(props);
453
- }
488
+ let mergePropsArgs = [];
489
+ if (props) {
490
+ if (props.type === 14) {
491
+ mergePropsArgs = props.arguments;
492
+ } else {
493
+ mergePropsArgs.push(props);
454
494
  }
455
- if (directives.length) {
456
- for (const dir of directives) {
457
- mergePropsArgs.push(compilerDom.createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
458
- `_ctx`,
459
- ...compilerDom.buildDirectiveArgs(dir, context).elements
460
- ]));
461
- }
495
+ }
496
+ if (directives.length) {
497
+ for (const dir of directives) {
498
+ mergePropsArgs.push(
499
+ compilerDom.createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
500
+ `_ctx`,
501
+ ...compilerDom.buildDirectiveArgs(dir, context).elements
502
+ ])
503
+ );
462
504
  }
463
- return mergePropsArgs.length > 1
464
- ? compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), mergePropsArgs)
465
- : mergePropsArgs[0];
505
+ }
506
+ return mergePropsArgs.length > 1 ? compilerDom.createCallExpression(context.helper(compilerDom.MERGE_PROPS), mergePropsArgs) : mergePropsArgs[0];
466
507
  }
467
508
  function isTrueFalseValue(prop) {
468
- if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
469
- return (prop.name === 'bind' &&
470
- prop.arg &&
471
- compilerDom.isStaticExp(prop.arg) &&
472
- (prop.arg.content === 'true-value' || prop.arg.content === 'false-value'));
473
- }
474
- else {
475
- return prop.name === 'true-value' || prop.name === 'false-value';
476
- }
509
+ if (prop.type === 7) {
510
+ return prop.name === "bind" && prop.arg && compilerDom.isStaticExp(prop.arg) && (prop.arg.content === "true-value" || prop.arg.content === "false-value");
511
+ } else {
512
+ return prop.name === "true-value" || prop.name === "false-value";
513
+ }
477
514
  }
478
515
  function isTextareaWithValue(node, prop) {
479
- return !!(node.tag === 'textarea' &&
480
- prop.name === 'bind' &&
481
- compilerDom.isStaticArgOf(prop.arg, 'value'));
516
+ return !!(node.tag === "textarea" && prop.name === "bind" && compilerDom.isStaticArgOf(prop.arg, "value"));
482
517
  }
483
518
  function mergeCall(call, arg) {
484
- const existing = call.arguments[0];
485
- if (existing.type === 17 /* NodeTypes.JS_ARRAY_EXPRESSION */) {
486
- existing.elements.push(arg);
487
- }
488
- else {
489
- call.arguments[0] = compilerDom.createArrayExpression([existing, arg]);
490
- }
519
+ const existing = call.arguments[0];
520
+ if (existing.type === 17) {
521
+ existing.elements.push(arg);
522
+ } else {
523
+ call.arguments[0] = compilerDom.createArrayExpression([existing, arg]);
524
+ }
491
525
  }
492
526
  function removeStaticBinding(tag, binding) {
493
- const regExp = new RegExp(`^ ${binding}=".+"$`);
494
- const i = tag.findIndex(e => typeof e === 'string' && regExp.test(e));
495
- if (i > -1) {
496
- tag.splice(i, 1);
497
- }
527
+ const regExp = new RegExp(`^ ${binding}=".+"$`);
528
+ const i = tag.findIndex((e) => typeof e === "string" && regExp.test(e));
529
+ if (i > -1) {
530
+ tag.splice(i, 1);
531
+ }
498
532
  }
499
533
  function findVModel(node) {
500
- return node.props.find(p => p.type === 7 /* NodeTypes.DIRECTIVE */ && p.name === 'model' && p.exp);
534
+ return node.props.find(
535
+ (p) => p.type === 7 && p.name === "model" && p.exp
536
+ );
501
537
  }
502
538
  function ssrProcessElement(node, context) {
503
- const isVoidTag = context.options.isVoidTag || shared.NO;
504
- const elementsToAdd = node.ssrCodegenNode.elements;
505
- for (let j = 0; j < elementsToAdd.length; j++) {
506
- context.pushStringPart(elementsToAdd[j]);
507
- }
508
- // Handle slot scopeId
509
- if (context.withSlotScopeId) {
510
- context.pushStringPart(compilerDom.createSimpleExpression(`_scopeId`, false));
511
- }
512
- // close open tag
513
- context.pushStringPart(`>`);
514
- const rawChildren = rawChildrenMap.get(node);
515
- if (rawChildren) {
516
- context.pushStringPart(rawChildren);
517
- }
518
- else if (node.children.length) {
519
- processChildren(node, context);
520
- }
521
- if (!isVoidTag(node.tag)) {
522
- // push closing tag
523
- context.pushStringPart(`</${node.tag}>`);
524
- }
539
+ const isVoidTag = context.options.isVoidTag || shared.NO;
540
+ const elementsToAdd = node.ssrCodegenNode.elements;
541
+ for (let j = 0; j < elementsToAdd.length; j++) {
542
+ context.pushStringPart(elementsToAdd[j]);
543
+ }
544
+ if (context.withSlotScopeId) {
545
+ context.pushStringPart(compilerDom.createSimpleExpression(`_scopeId`, false));
546
+ }
547
+ context.pushStringPart(`>`);
548
+ const rawChildren = rawChildrenMap.get(node);
549
+ if (rawChildren) {
550
+ context.pushStringPart(rawChildren);
551
+ } else if (node.children.length) {
552
+ processChildren(node, context);
553
+ }
554
+ if (!isVoidTag(node.tag)) {
555
+ context.pushStringPart(`</${node.tag}>`);
556
+ }
525
557
  }
526
558
 
527
- const wipMap$1 = new WeakMap();
528
- // phase 1: build props
559
+ const wipMap$1 = /* @__PURE__ */ new WeakMap();
529
560
  function ssrTransformTransitionGroup(node, context) {
530
- return () => {
531
- const tag = compilerDom.findProp(node, 'tag');
532
- if (tag) {
533
- const otherProps = node.props.filter(p => p !== tag);
534
- const { props, directives } = compilerDom.buildProps(node, context, otherProps, true /* isComponent */, false /* isDynamicComponent */, true /* ssr (skip event listeners) */);
535
- let propsExp = null;
536
- if (props || directives.length) {
537
- propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
538
- buildSSRProps(props, directives, context)
539
- ]);
540
- }
541
- wipMap$1.set(node, {
542
- tag,
543
- propsExp
544
- });
545
- }
546
- };
561
+ return () => {
562
+ const tag = compilerDom.findProp(node, "tag");
563
+ if (tag) {
564
+ const otherProps = node.props.filter((p) => p !== tag);
565
+ const { props, directives } = compilerDom.buildProps(
566
+ node,
567
+ context,
568
+ otherProps,
569
+ true,
570
+ false,
571
+ true
572
+ /* ssr (skip event listeners) */
573
+ );
574
+ let propsExp = null;
575
+ if (props || directives.length) {
576
+ propsExp = compilerDom.createCallExpression(context.helper(SSR_RENDER_ATTRS), [
577
+ buildSSRProps(props, directives, context)
578
+ ]);
579
+ }
580
+ wipMap$1.set(node, {
581
+ tag,
582
+ propsExp
583
+ });
584
+ }
585
+ };
547
586
  }
548
- // phase 2: process children
549
587
  function ssrProcessTransitionGroup(node, context) {
550
- const entry = wipMap$1.get(node);
551
- if (entry) {
552
- const { tag, propsExp } = entry;
553
- if (tag.type === 7 /* NodeTypes.DIRECTIVE */) {
554
- // dynamic :tag
555
- context.pushStringPart(`<`);
556
- context.pushStringPart(tag.exp);
557
- if (propsExp) {
558
- context.pushStringPart(propsExp);
559
- }
560
- context.pushStringPart(`>`);
561
- processChildren(node, context, false,
562
- /**
563
- * TransitionGroup has the special runtime behavior of flattening and
564
- * concatenating all children into a single fragment (in order for them to
565
- * be patched using the same key map) so we need to account for that here
566
- * by disabling nested fragment wrappers from being generated.
567
- */
568
- true);
569
- context.pushStringPart(`</`);
570
- context.pushStringPart(tag.exp);
571
- context.pushStringPart(`>`);
572
- }
573
- else {
574
- // static tag
575
- context.pushStringPart(`<${tag.value.content}`);
576
- if (propsExp) {
577
- context.pushStringPart(propsExp);
578
- }
579
- context.pushStringPart(`>`);
580
- processChildren(node, context, false, true);
581
- context.pushStringPart(`</${tag.value.content}>`);
582
- }
583
- }
584
- else {
585
- // fragment
586
- processChildren(node, context, true, true);
588
+ const entry = wipMap$1.get(node);
589
+ if (entry) {
590
+ const { tag, propsExp } = entry;
591
+ if (tag.type === 7) {
592
+ context.pushStringPart(`<`);
593
+ context.pushStringPart(tag.exp);
594
+ if (propsExp) {
595
+ context.pushStringPart(propsExp);
596
+ }
597
+ context.pushStringPart(`>`);
598
+ processChildren(
599
+ node,
600
+ context,
601
+ false,
602
+ /**
603
+ * TransitionGroup has the special runtime behavior of flattening and
604
+ * concatenating all children into a single fragment (in order for them to
605
+ * be patched using the same key map) so we need to account for that here
606
+ * by disabling nested fragment wrappers from being generated.
607
+ */
608
+ true
609
+ );
610
+ context.pushStringPart(`</`);
611
+ context.pushStringPart(tag.exp);
612
+ context.pushStringPart(`>`);
613
+ } else {
614
+ context.pushStringPart(`<${tag.value.content}`);
615
+ if (propsExp) {
616
+ context.pushStringPart(propsExp);
617
+ }
618
+ context.pushStringPart(`>`);
619
+ processChildren(node, context, false, true);
620
+ context.pushStringPart(`</${tag.value.content}>`);
587
621
  }
622
+ } else {
623
+ processChildren(node, context, true, true);
624
+ }
588
625
  }
589
626
 
590
- // We need to construct the slot functions in the 1st pass to ensure proper
591
- // scope tracking, but the children of each slot cannot be processed until
592
- // the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
593
- // pass and complete them in the 2nd pass.
594
- const wipMap = new WeakMap();
627
+ const wipMap = /* @__PURE__ */ new WeakMap();
595
628
  const WIP_SLOT = Symbol();
596
- const componentTypeMap = new WeakMap();
597
- // ssr component transform is done in two phases:
598
- // In phase 1. we use `buildSlot` to analyze the children of the component into
599
- // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
600
- // the core transform context).
601
- // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
602
- // nodes.
629
+ const componentTypeMap = /* @__PURE__ */ new WeakMap();
603
630
  const ssrTransformComponent = (node, context) => {
604
- if (node.type !== 1 /* NodeTypes.ELEMENT */ ||
605
- node.tagType !== 1 /* ElementTypes.COMPONENT */) {
606
- return;
631
+ if (node.type !== "element" || node.tagType !== 1) {
632
+ return;
633
+ }
634
+ const component = compilerDom.resolveComponentType(
635
+ node,
636
+ context,
637
+ true
638
+ /* ssr */
639
+ );
640
+ const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
641
+ componentTypeMap.set(node, component);
642
+ if (shared.isSymbol(component)) {
643
+ if (component === compilerDom.SUSPENSE) {
644
+ return ssrTransformSuspense(node, context);
607
645
  }
608
- const component = compilerDom.resolveComponentType(node, context, true /* ssr */);
609
- const isDynamicComponent = shared.isObject(component) && component.callee === compilerDom.RESOLVE_DYNAMIC_COMPONENT;
610
- componentTypeMap.set(node, component);
611
- if (shared.isSymbol(component)) {
612
- if (component === compilerDom.SUSPENSE) {
613
- return ssrTransformSuspense(node, context);
614
- }
615
- if (component === compilerDom.TRANSITION_GROUP) {
616
- return ssrTransformTransitionGroup(node, context);
617
- }
618
- return; // other built-in components: fallthrough
646
+ if (component === compilerDom.TRANSITION_GROUP) {
647
+ return ssrTransformTransitionGroup(node, context);
619
648
  }
620
- // Build the fallback vnode-based branch for the component's slots.
621
- // We need to clone the node into a fresh copy and use the buildSlots' logic
622
- // to get access to the children of each slot. We then compile them with
623
- // a child transform pipeline using vnode-based transforms (instead of ssr-
624
- // based ones), and save the result branch (a ReturnStatement) in an array.
625
- // The branch is retrieved when processing slots again in ssr mode.
626
- const vnodeBranches = [];
627
- const clonedNode = clone(node);
628
- return function ssrPostTransformComponent() {
629
- // Using the cloned node, build the normal VNode-based branches (for
630
- // fallback in case the child is render-fn based). Store them in an array
631
- // for later use.
632
- if (clonedNode.children.length) {
633
- compilerDom.buildSlots(clonedNode, context, (props, children) => {
634
- vnodeBranches.push(createVNodeSlotBranch(props, children, context));
635
- return compilerDom.createFunctionExpression(undefined);
636
- });
637
- }
638
- let propsExp = `null`;
639
- if (node.props.length) {
640
- // note we are not passing ssr: true here because for components, v-on
641
- // handlers should still be passed
642
- const { props, directives } = compilerDom.buildProps(node, context, undefined, true, isDynamicComponent);
643
- if (props || directives.length) {
644
- propsExp = buildSSRProps(props, directives, context);
645
- }
646
- }
647
- const wipEntries = [];
648
- wipMap.set(node, wipEntries);
649
- const buildSSRSlotFn = (props, children, loc) => {
650
- const param0 = (props && compilerDom.stringifyExpression(props)) || `_`;
651
- const fn = compilerDom.createFunctionExpression([param0, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
652
- true, // newline
653
- true, // isSlot
654
- loc);
655
- wipEntries.push({
656
- type: WIP_SLOT,
657
- fn,
658
- children,
659
- // also collect the corresponding vnode branch built earlier
660
- vnodeBranch: vnodeBranches[wipEntries.length]
661
- });
662
- return fn;
663
- };
664
- const slots = node.children.length
665
- ? compilerDom.buildSlots(node, context, buildSSRSlotFn).slots
666
- : `null`;
667
- if (typeof component !== 'string') {
668
- // dynamic component that resolved to a `resolveDynamicComponent` call
669
- // expression - since the resolved result may be a plain element (string)
670
- // or a VNode, handle it with `renderVNode`.
671
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(SSR_RENDER_VNODE), [
672
- `_push`,
673
- compilerDom.createCallExpression(context.helper(compilerDom.CREATE_VNODE), [
674
- component,
675
- propsExp,
676
- slots
677
- ]),
678
- `_parent`
679
- ]);
680
- }
681
- else {
682
- node.ssrCodegenNode = compilerDom.createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, propsExp, slots, `_parent`]);
683
- }
649
+ return;
650
+ }
651
+ const vnodeBranches = [];
652
+ const clonedNode = clone(node);
653
+ return function ssrPostTransformComponent() {
654
+ if (clonedNode.children.length) {
655
+ compilerDom.buildSlots(clonedNode, context, (props, children) => {
656
+ vnodeBranches.push(createVNodeSlotBranch(props, children, context));
657
+ return compilerDom.createFunctionExpression(void 0);
658
+ });
659
+ }
660
+ let propsExp = `null`;
661
+ if (node.props.length) {
662
+ const { props, directives } = compilerDom.buildProps(
663
+ node,
664
+ context,
665
+ void 0,
666
+ true,
667
+ isDynamicComponent
668
+ );
669
+ if (props || directives.length) {
670
+ propsExp = buildSSRProps(props, directives, context);
671
+ }
672
+ }
673
+ const wipEntries = [];
674
+ wipMap.set(node, wipEntries);
675
+ const buildSSRSlotFn = (props, children, loc) => {
676
+ const param0 = props && compilerDom.stringifyExpression(props) || `_`;
677
+ const fn = compilerDom.createFunctionExpression(
678
+ [param0, `_push`, `_parent`, `_scopeId`],
679
+ void 0,
680
+ // no return, assign body later
681
+ true,
682
+ // newline
683
+ true,
684
+ // isSlot
685
+ loc
686
+ );
687
+ wipEntries.push({
688
+ type: WIP_SLOT,
689
+ fn,
690
+ children,
691
+ // also collect the corresponding vnode branch built earlier
692
+ vnodeBranch: vnodeBranches[wipEntries.length]
693
+ });
694
+ return fn;
684
695
  };
696
+ const slots = node.children.length ? compilerDom.buildSlots(node, context, buildSSRSlotFn).slots : `null`;
697
+ if (typeof component !== "string") {
698
+ node.ssrCodegenNode = compilerDom.createCallExpression(
699
+ context.helper(SSR_RENDER_VNODE),
700
+ [
701
+ `_push`,
702
+ compilerDom.createCallExpression(context.helper(compilerDom.CREATE_VNODE), [
703
+ component,
704
+ propsExp,
705
+ slots
706
+ ]),
707
+ `_parent`
708
+ ]
709
+ );
710
+ } else {
711
+ node.ssrCodegenNode = compilerDom.createCallExpression(
712
+ context.helper(SSR_RENDER_COMPONENT),
713
+ [component, propsExp, slots, `_parent`]
714
+ );
715
+ }
716
+ };
685
717
  };
686
718
  function ssrProcessComponent(node, context, parent) {
687
- const component = componentTypeMap.get(node);
688
- if (!node.ssrCodegenNode) {
689
- // this is a built-in component that fell-through.
690
- if (component === compilerDom.TELEPORT) {
691
- return ssrProcessTeleport(node, context);
692
- }
693
- else if (component === compilerDom.SUSPENSE) {
694
- return ssrProcessSuspense(node, context);
695
- }
696
- else if (component === compilerDom.TRANSITION_GROUP) {
697
- return ssrProcessTransitionGroup(node, context);
698
- }
699
- else {
700
- // real fall-through: Transition / KeepAlive
701
- // just render its children.
702
- // #5352: if is at root level of a slot, push an empty string.
703
- // this does not affect the final output, but avoids all-comment slot
704
- // content of being treated as empty by ssrRenderSlot().
705
- if (parent.type === WIP_SLOT) {
706
- context.pushStringPart(``);
707
- }
708
- // #5351: filter out comment children inside transition
709
- if (component === compilerDom.TRANSITION) {
710
- node.children = node.children.filter(c => c.type !== 3 /* NodeTypes.COMMENT */);
711
- }
712
- processChildren(node, context);
713
- }
719
+ const component = componentTypeMap.get(node);
720
+ if (!node.ssrCodegenNode) {
721
+ if (component === compilerDom.TELEPORT) {
722
+ return ssrProcessTeleport(node, context);
723
+ } else if (component === compilerDom.SUSPENSE) {
724
+ return ssrProcessSuspense(node, context);
725
+ } else if (component === compilerDom.TRANSITION_GROUP) {
726
+ return ssrProcessTransitionGroup(node, context);
727
+ } else {
728
+ if (parent.type === WIP_SLOT) {
729
+ context.pushStringPart(``);
730
+ }
731
+ if (component === compilerDom.TRANSITION) {
732
+ node.children = node.children.filter((c) => c.type !== "comment");
733
+ }
734
+ processChildren(node, context);
714
735
  }
715
- else {
716
- // finish up slot function expressions from the 1st pass.
717
- const wipEntries = wipMap.get(node) || [];
718
- for (let i = 0; i < wipEntries.length; i++) {
719
- const { fn, vnodeBranch } = wipEntries[i];
720
- // For each slot, we generate two branches: one SSR-optimized branch and
721
- // one normal vnode-based branch. The branches are taken based on the
722
- // presence of the 2nd `_push` argument (which is only present if the slot
723
- // is called by `_ssrRenderSlot`.
724
- fn.body = compilerDom.createIfStatement(compilerDom.createSimpleExpression(`_push`, false), processChildrenAsStatement(wipEntries[i], context, false, true /* withSlotScopeId */), vnodeBranch);
725
- }
726
- // component is inside a slot, inherit slot scope Id
727
- if (context.withSlotScopeId) {
728
- node.ssrCodegenNode.arguments.push(`_scopeId`);
729
- }
730
- if (typeof component === 'string') {
731
- // static component
732
- context.pushStatement(compilerDom.createCallExpression(`_push`, [node.ssrCodegenNode]));
733
- }
734
- else {
735
- // dynamic component (`resolveDynamicComponent` call)
736
- // the codegen node is a `renderVNode` call
737
- context.pushStatement(node.ssrCodegenNode);
738
- }
736
+ } else {
737
+ const wipEntries = wipMap.get(node) || [];
738
+ for (let i = 0; i < wipEntries.length; i++) {
739
+ const { fn, vnodeBranch } = wipEntries[i];
740
+ fn.body = compilerDom.createIfStatement(
741
+ compilerDom.createSimpleExpression(`_push`, false),
742
+ processChildrenAsStatement(
743
+ wipEntries[i],
744
+ context,
745
+ false,
746
+ true
747
+ /* withSlotScopeId */
748
+ ),
749
+ vnodeBranch
750
+ );
751
+ }
752
+ if (context.withSlotScopeId) {
753
+ node.ssrCodegenNode.arguments.push(`_scopeId`);
739
754
  }
755
+ if (typeof component === "string") {
756
+ context.pushStatement(
757
+ compilerDom.createCallExpression(`_push`, [node.ssrCodegenNode])
758
+ );
759
+ } else {
760
+ context.pushStatement(node.ssrCodegenNode);
761
+ }
762
+ }
740
763
  }
741
- const rawOptionsMap = new WeakMap();
764
+ const rawOptionsMap = /* @__PURE__ */ new WeakMap();
742
765
  const [baseNodeTransforms, baseDirectiveTransforms] = compilerDom.getBaseTransformPreset(true);
743
766
  const vnodeNodeTransforms = [...baseNodeTransforms, ...compilerDom.DOMNodeTransforms];
744
767
  const vnodeDirectiveTransforms = {
745
- ...baseDirectiveTransforms,
746
- ...compilerDom.DOMDirectiveTransforms
768
+ ...baseDirectiveTransforms,
769
+ ...compilerDom.DOMDirectiveTransforms
747
770
  };
748
771
  function createVNodeSlotBranch(props, children, parentContext) {
749
- // apply a sub-transform using vnode-based transforms.
750
- const rawOptions = rawOptionsMap.get(parentContext.root);
751
- const subOptions = {
752
- ...rawOptions,
753
- // overwrite with vnode-based transforms
754
- nodeTransforms: [
755
- ...vnodeNodeTransforms,
756
- ...(rawOptions.nodeTransforms || [])
757
- ],
758
- directiveTransforms: {
759
- ...vnodeDirectiveTransforms,
760
- ...(rawOptions.directiveTransforms || {})
761
- }
762
- };
763
- // wrap the children with a wrapper template for proper children treatment.
764
- const wrapperNode = {
765
- type: 1 /* NodeTypes.ELEMENT */,
766
- ns: 0 /* Namespaces.HTML */,
767
- tag: 'template',
768
- tagType: 3 /* ElementTypes.TEMPLATE */,
769
- isSelfClosing: false,
770
- // important: provide v-slot="props" on the wrapper for proper
771
- // scope analysis
772
- props: [
773
- {
774
- type: 7 /* NodeTypes.DIRECTIVE */,
775
- name: 'slot',
776
- exp: props,
777
- arg: undefined,
778
- modifiers: [],
779
- loc: compilerDom.locStub
780
- }
781
- ],
782
- children,
783
- loc: compilerDom.locStub,
784
- codegenNode: undefined
785
- };
786
- subTransform(wrapperNode, subOptions, parentContext);
787
- return compilerDom.createReturnStatement(children);
772
+ const rawOptions = rawOptionsMap.get(parentContext.root);
773
+ const subOptions = {
774
+ ...rawOptions,
775
+ // overwrite with vnode-based transforms
776
+ nodeTransforms: [
777
+ ...vnodeNodeTransforms,
778
+ ...rawOptions.nodeTransforms || []
779
+ ],
780
+ directiveTransforms: {
781
+ ...vnodeDirectiveTransforms,
782
+ ...rawOptions.directiveTransforms || {}
783
+ }
784
+ };
785
+ const wrapperNode = {
786
+ type: "element",
787
+ ns: 0,
788
+ tag: "template",
789
+ tagType: 3,
790
+ isSelfClosing: false,
791
+ // important: provide v-slot="props" on the wrapper for proper
792
+ // scope analysis
793
+ props: [
794
+ {
795
+ type: 7,
796
+ name: "slot",
797
+ exp: props,
798
+ arg: void 0,
799
+ modifiers: [],
800
+ loc: compilerDom.locStub
801
+ }
802
+ ],
803
+ children,
804
+ loc: compilerDom.locStub,
805
+ codegenNode: void 0
806
+ };
807
+ subTransform(wrapperNode, subOptions, parentContext);
808
+ return compilerDom.createReturnStatement(children);
788
809
  }
789
810
  function subTransform(node, options, parentContext) {
790
- const childRoot = compilerDom.createRoot([node]);
791
- const childContext = compilerDom.createTransformContext(childRoot, options);
792
- // this sub transform is for vnode fallback branch so it should be handled
793
- // like normal render functions
794
- childContext.ssr = false;
795
- // inherit parent scope analysis state
796
- childContext.scopes = { ...parentContext.scopes };
797
- childContext.identifiers = { ...parentContext.identifiers };
798
- childContext.imports = parentContext.imports;
799
- // traverse
800
- compilerDom.traverseNode(childRoot, childContext);
801
- ['helpers', 'components', 'directives'].forEach(key => {
802
- childContext[key].forEach((value, helperKey) => {
803
- if (key === 'helpers') {
804
- const parentCount = parentContext.helpers.get(helperKey);
805
- if (parentCount === undefined) {
806
- parentContext.helpers.set(helperKey, value);
807
- }
808
- else {
809
- parentContext.helpers.set(helperKey, value + parentCount);
810
- }
811
- }
812
- else {
813
- parentContext[key].add(value);
814
- }
815
- });
811
+ const childRoot = compilerDom.createRoot([node]);
812
+ const childContext = compilerDom.createTransformContext(childRoot, options);
813
+ childContext.ssr = false;
814
+ childContext.scopes = { ...parentContext.scopes };
815
+ childContext.identifiers = { ...parentContext.identifiers };
816
+ childContext.imports = parentContext.imports;
817
+ compilerDom.traverseNode(childRoot, childContext);
818
+ ["helpers", "components", "directives"].forEach((key) => {
819
+ childContext[key].forEach((value, helperKey) => {
820
+ if (key === "helpers") {
821
+ const parentCount = parentContext.helpers.get(helperKey);
822
+ if (parentCount === void 0) {
823
+ parentContext.helpers.set(helperKey, value);
824
+ } else {
825
+ parentContext.helpers.set(helperKey, value + parentCount);
826
+ }
827
+ } else {
828
+ parentContext[key].add(value);
829
+ }
816
830
  });
817
- // imports/hoists are not merged because:
818
- // - imports are only used for asset urls and should be consistent between
819
- // node/client branches
820
- // - hoists are not enabled for the client branch here
831
+ });
821
832
  }
822
833
  function clone(v) {
823
- if (shared.isArray(v)) {
824
- return v.map(clone);
825
- }
826
- else if (shared.isObject(v)) {
827
- const res = {};
828
- for (const key in v) {
829
- res[key] = clone(v[key]);
830
- }
831
- return res;
832
- }
833
- else {
834
- return v;
834
+ if (shared.isArray(v)) {
835
+ return v.map(clone);
836
+ } else if (shared.isObject(v)) {
837
+ const res = {};
838
+ for (const key in v) {
839
+ res[key] = clone(v[key]);
835
840
  }
841
+ return res;
842
+ } else {
843
+ return v;
844
+ }
836
845
  }
837
846
 
838
- // Because SSR codegen output is completely different from client-side output
839
- // (e.g. multiple elements can be concatenated into a single template literal
840
- // instead of each getting a corresponding call), we need to apply an extra
841
- // transform pass to convert the template AST into a fresh JS AST before
842
- // passing it to codegen.
843
847
  function ssrCodegenTransform(ast, options) {
844
- const context = createSSRTransformContext(ast, options);
845
- // inject SFC <style> CSS variables
846
- // we do this instead of inlining the expression to ensure the vars are
847
- // only resolved once per render
848
- if (options.ssrCssVars) {
849
- const cssContext = compilerDom.createTransformContext(compilerDom.createRoot([]), options);
850
- const varsExp = compilerDom.processExpression(compilerDom.createSimpleExpression(options.ssrCssVars, false), cssContext);
851
- context.body.push(compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`]));
852
- Array.from(cssContext.helpers.keys()).forEach(helper => {
853
- ast.helpers.add(helper);
854
- });
855
- }
856
- const isFragment = ast.children.length > 1 && ast.children.some(c => !compilerDom.isText(c));
857
- processChildren(ast, context, isFragment);
858
- ast.codegenNode = compilerDom.createBlockStatement(context.body);
859
- // Finalize helpers.
860
- // We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
861
- ast.ssrHelpers = Array.from(new Set([
862
- ...Array.from(ast.helpers).filter(h => h in ssrHelpers),
863
- ...context.helpers
864
- ]));
865
- ast.helpers = new Set(Array.from(ast.helpers).filter(h => !(h in ssrHelpers)));
848
+ const context = createSSRTransformContext(ast, options);
849
+ if (options.ssrCssVars) {
850
+ const cssContext = compilerDom.createTransformContext(compilerDom.createRoot([]), options);
851
+ const varsExp = compilerDom.processExpression(
852
+ compilerDom.createSimpleExpression(options.ssrCssVars, false),
853
+ cssContext
854
+ );
855
+ context.body.push(
856
+ compilerDom.createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`])
857
+ );
858
+ Array.from(cssContext.helpers.keys()).forEach((helper) => {
859
+ ast.helpers.add(helper);
860
+ });
861
+ }
862
+ const isFragment = ast.children.length > 1 && ast.children.some((c) => !compilerDom.isText(c));
863
+ processChildren(ast, context, isFragment);
864
+ ast.codegenNode = compilerDom.createBlockStatement(context.body);
865
+ ast.ssrHelpers = Array.from(
866
+ /* @__PURE__ */ new Set([
867
+ ...Array.from(ast.helpers).filter((h) => h in ssrHelpers),
868
+ ...context.helpers
869
+ ])
870
+ );
871
+ ast.helpers = new Set(Array.from(ast.helpers).filter((h) => !(h in ssrHelpers)));
866
872
  }
867
- function createSSRTransformContext(root, options, helpers = new Set(), withSlotScopeId = false) {
868
- const body = [];
869
- let currentString = null;
870
- return {
871
- root,
872
- options,
873
- body,
874
- helpers,
875
- withSlotScopeId,
876
- onError: options.onError ||
877
- (e => {
878
- throw e;
879
- }),
880
- helper(name) {
881
- helpers.add(name);
882
- return name;
883
- },
884
- pushStringPart(part) {
885
- if (!currentString) {
886
- const currentCall = compilerDom.createCallExpression(`_push`);
887
- body.push(currentCall);
888
- currentString = compilerDom.createTemplateLiteral([]);
889
- currentCall.arguments.push(currentString);
890
- }
891
- const bufferedElements = currentString.elements;
892
- const lastItem = bufferedElements[bufferedElements.length - 1];
893
- if (shared.isString(part) && shared.isString(lastItem)) {
894
- bufferedElements[bufferedElements.length - 1] += part;
895
- }
896
- else {
897
- bufferedElements.push(part);
898
- }
899
- },
900
- pushStatement(statement) {
901
- // close current string
902
- currentString = null;
903
- body.push(statement);
904
- }
905
- };
873
+ function createSSRTransformContext(root, options, helpers = /* @__PURE__ */ new Set(), withSlotScopeId = false) {
874
+ const body = [];
875
+ let currentString = null;
876
+ return {
877
+ root,
878
+ options,
879
+ body,
880
+ helpers,
881
+ withSlotScopeId,
882
+ onError: options.onError || ((e) => {
883
+ throw e;
884
+ }),
885
+ helper(name) {
886
+ helpers.add(name);
887
+ return name;
888
+ },
889
+ pushStringPart(part) {
890
+ if (!currentString) {
891
+ const currentCall = compilerDom.createCallExpression(`_push`);
892
+ body.push(currentCall);
893
+ currentString = compilerDom.createTemplateLiteral([]);
894
+ currentCall.arguments.push(currentString);
895
+ }
896
+ const bufferedElements = currentString.elements;
897
+ const lastItem = bufferedElements[bufferedElements.length - 1];
898
+ if (shared.isString(part) && shared.isString(lastItem)) {
899
+ bufferedElements[bufferedElements.length - 1] += part;
900
+ } else {
901
+ bufferedElements.push(part);
902
+ }
903
+ },
904
+ pushStatement(statement) {
905
+ currentString = null;
906
+ body.push(statement);
907
+ }
908
+ };
906
909
  }
907
910
  function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
908
- // ensure child inherits parent helpers
909
- return createSSRTransformContext(parent.root, parent.options, parent.helpers, withSlotScopeId);
911
+ return createSSRTransformContext(
912
+ parent.root,
913
+ parent.options,
914
+ parent.helpers,
915
+ withSlotScopeId
916
+ );
910
917
  }
911
918
  function processChildren(parent, context, asFragment = false, disableNestedFragments = false) {
912
- if (asFragment) {
913
- context.pushStringPart(`<!--[-->`);
914
- }
915
- const { children } = parent;
916
- for (let i = 0; i < children.length; i++) {
917
- const child = children[i];
918
- switch (child.type) {
919
- case 1 /* NodeTypes.ELEMENT */:
920
- switch (child.tagType) {
921
- case 0 /* ElementTypes.ELEMENT */:
922
- ssrProcessElement(child, context);
923
- break;
924
- case 1 /* ElementTypes.COMPONENT */:
925
- ssrProcessComponent(child, context, parent);
926
- break;
927
- case 2 /* ElementTypes.SLOT */:
928
- ssrProcessSlotOutlet(child, context);
929
- break;
930
- case 3 /* ElementTypes.TEMPLATE */:
931
- // TODO
932
- break;
933
- default:
934
- context.onError(createSSRCompilerError(64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */, child.loc));
935
- // make sure we exhaust all possible types
936
- const exhaustiveCheck = child;
937
- return exhaustiveCheck;
938
- }
939
- break;
940
- case 2 /* NodeTypes.TEXT */:
941
- context.pushStringPart(shared.escapeHtml(child.content));
942
- break;
943
- case 3 /* NodeTypes.COMMENT */:
944
- // no need to escape comment here because the AST can only
945
- // contain valid comments.
946
- context.pushStringPart(`<!--${child.content}-->`);
947
- break;
948
- case 5 /* NodeTypes.INTERPOLATION */:
949
- context.pushStringPart(compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [child.content]));
950
- break;
951
- case 9 /* NodeTypes.IF */:
952
- ssrProcessIf(child, context, disableNestedFragments);
953
- break;
954
- case 11 /* NodeTypes.FOR */:
955
- ssrProcessFor(child, context, disableNestedFragments);
956
- break;
957
- case 10 /* NodeTypes.IF_BRANCH */:
958
- // no-op - handled by ssrProcessIf
959
- break;
960
- case 12 /* NodeTypes.TEXT_CALL */:
961
- case 8 /* NodeTypes.COMPOUND_EXPRESSION */:
962
- // no-op - these two types can never appear as template child node since
963
- // `transformText` is not used during SSR compile.
964
- break;
965
- default:
966
- context.onError(createSSRCompilerError(64 /* SSRErrorCodes.X_SSR_INVALID_AST_NODE */, child.loc));
967
- // make sure we exhaust all possible types
968
- const exhaustiveCheck = child;
969
- return exhaustiveCheck;
919
+ if (asFragment) {
920
+ context.pushStringPart(`<!--[-->`);
921
+ }
922
+ const { children } = parent;
923
+ for (let i = 0; i < children.length; i++) {
924
+ const child = children[i];
925
+ switch (child.type) {
926
+ case "element":
927
+ switch (child.tagType) {
928
+ case 0:
929
+ ssrProcessElement(child, context);
930
+ break;
931
+ case 1:
932
+ ssrProcessComponent(child, context, parent);
933
+ break;
934
+ case 2:
935
+ ssrProcessSlotOutlet(child, context);
936
+ break;
937
+ case 3:
938
+ break;
939
+ default:
940
+ context.onError(
941
+ createSSRCompilerError(
942
+ 64,
943
+ child.loc
944
+ )
945
+ );
946
+ const exhaustiveCheck2 = child;
947
+ return exhaustiveCheck2;
970
948
  }
949
+ break;
950
+ case "text":
951
+ context.pushStringPart(shared.escapeHtml(child.content));
952
+ break;
953
+ case "comment":
954
+ context.pushStringPart(`<!--${child.content}-->`);
955
+ break;
956
+ case 5:
957
+ context.pushStringPart(
958
+ compilerDom.createCallExpression(context.helper(SSR_INTERPOLATE), [child.content])
959
+ );
960
+ break;
961
+ case 9:
962
+ ssrProcessIf(child, context, disableNestedFragments);
963
+ break;
964
+ case 11:
965
+ ssrProcessFor(child, context, disableNestedFragments);
966
+ break;
967
+ case 10:
968
+ break;
969
+ case 12:
970
+ case 8:
971
+ break;
972
+ default:
973
+ context.onError(
974
+ createSSRCompilerError(
975
+ 64,
976
+ child.loc
977
+ )
978
+ );
979
+ const exhaustiveCheck = child;
980
+ return exhaustiveCheck;
971
981
  }
972
- if (asFragment) {
973
- context.pushStringPart(`<!--]-->`);
974
- }
982
+ }
983
+ if (asFragment) {
984
+ context.pushStringPart(`<!--]-->`);
985
+ }
975
986
  }
976
987
  function processChildrenAsStatement(parent, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
977
- const childContext = createChildContext(parentContext, withSlotScopeId);
978
- processChildren(parent, childContext, asFragment);
979
- return compilerDom.createBlockStatement(childContext.body);
988
+ const childContext = createChildContext(parentContext, withSlotScopeId);
989
+ processChildren(parent, childContext, asFragment);
990
+ return compilerDom.createBlockStatement(childContext.body);
980
991
  }
981
992
 
982
993
  const ssrTransformModel = (dir, node, context) => {
983
- const model = dir.exp;
984
- function checkDuplicatedValue() {
985
- const value = compilerDom.findProp(node, 'value');
986
- if (value) {
987
- context.onError(compilerDom.createDOMCompilerError(58 /* DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
988
- }
994
+ const model = dir.exp;
995
+ function checkDuplicatedValue() {
996
+ const value = compilerDom.findProp(node, "value");
997
+ if (value) {
998
+ context.onError(
999
+ compilerDom.createDOMCompilerError(
1000
+ 58,
1001
+ value.loc
1002
+ )
1003
+ );
989
1004
  }
990
- if (node.tagType === 0 /* ElementTypes.ELEMENT */) {
991
- const res = { props: [] };
992
- const defaultProps = [
993
- // default value binding for text type inputs
994
- compilerDom.createObjectProperty(`value`, model)
995
- ];
996
- if (node.tag === 'input') {
997
- const type = compilerDom.findProp(node, 'type');
998
- if (type) {
999
- const value = findValueBinding(node);
1000
- if (type.type === 7 /* NodeTypes.DIRECTIVE */) {
1001
- // dynamic type
1002
- res.ssrTagParts = [
1003
- compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
1004
- type.exp,
1005
- model,
1006
- value
1007
- ])
1008
- ];
1009
- }
1010
- else if (type.value) {
1011
- // static type
1012
- switch (type.value.content) {
1013
- case 'radio':
1014
- res.props = [
1015
- compilerDom.createObjectProperty(`checked`, compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1016
- model,
1017
- value
1018
- ]))
1019
- ];
1020
- break;
1021
- case 'checkbox':
1022
- const trueValueBinding = compilerDom.findProp(node, 'true-value');
1023
- if (trueValueBinding) {
1024
- const trueValue = trueValueBinding.type === 6 /* NodeTypes.ATTRIBUTE */
1025
- ? JSON.stringify(trueValueBinding.value.content)
1026
- : trueValueBinding.exp;
1027
- res.props = [
1028
- compilerDom.createObjectProperty(`checked`, compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1029
- model,
1030
- trueValue
1031
- ]))
1032
- ];
1033
- }
1034
- else {
1035
- res.props = [
1036
- compilerDom.createObjectProperty(`checked`, compilerDom.createConditionalExpression(compilerDom.createCallExpression(`Array.isArray`, [model]), compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1037
- model,
1038
- value
1039
- ]), model))
1040
- ];
1041
- }
1042
- break;
1043
- case 'file':
1044
- context.onError(compilerDom.createDOMCompilerError(57 /* DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
1045
- break;
1046
- default:
1047
- checkDuplicatedValue();
1048
- res.props = defaultProps;
1049
- break;
1050
- }
1051
- }
1052
- }
1053
- else if (compilerDom.hasDynamicKeyVBind(node)) ;
1054
- else {
1055
- // text type
1056
- checkDuplicatedValue();
1057
- res.props = defaultProps;
1058
- }
1059
- }
1060
- else if (node.tag === 'textarea') {
1061
- checkDuplicatedValue();
1062
- node.children = [compilerDom.createInterpolation(model, model.loc)];
1063
- }
1064
- else if (node.tag === 'select') ;
1065
- else {
1066
- context.onError(compilerDom.createDOMCompilerError(55 /* DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
1005
+ }
1006
+ if (node.tagType === 0) {
1007
+ const res = { props: [] };
1008
+ const defaultProps = [
1009
+ // default value binding for text type inputs
1010
+ compilerDom.createObjectProperty(`value`, model)
1011
+ ];
1012
+ if (node.tag === "input") {
1013
+ const type = compilerDom.findProp(node, "type");
1014
+ if (type) {
1015
+ const value = findValueBinding(node);
1016
+ if (type.type === 7) {
1017
+ res.ssrTagParts = [
1018
+ compilerDom.createCallExpression(context.helper(SSR_RENDER_DYNAMIC_MODEL), [
1019
+ type.exp,
1020
+ model,
1021
+ value
1022
+ ])
1023
+ ];
1024
+ } else if (type.value) {
1025
+ switch (type.value.content) {
1026
+ case "radio":
1027
+ res.props = [
1028
+ compilerDom.createObjectProperty(
1029
+ `checked`,
1030
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1031
+ model,
1032
+ value
1033
+ ])
1034
+ )
1035
+ ];
1036
+ break;
1037
+ case "checkbox":
1038
+ const trueValueBinding = compilerDom.findProp(node, "true-value");
1039
+ if (trueValueBinding) {
1040
+ const trueValue = trueValueBinding.type === 6 ? JSON.stringify(trueValueBinding.value.content) : trueValueBinding.exp;
1041
+ res.props = [
1042
+ compilerDom.createObjectProperty(
1043
+ `checked`,
1044
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
1045
+ model,
1046
+ trueValue
1047
+ ])
1048
+ )
1049
+ ];
1050
+ } else {
1051
+ res.props = [
1052
+ compilerDom.createObjectProperty(
1053
+ `checked`,
1054
+ compilerDom.createConditionalExpression(
1055
+ compilerDom.createCallExpression(`Array.isArray`, [model]),
1056
+ compilerDom.createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
1057
+ model,
1058
+ value
1059
+ ]),
1060
+ model
1061
+ )
1062
+ )
1063
+ ];
1064
+ }
1065
+ break;
1066
+ case "file":
1067
+ context.onError(
1068
+ compilerDom.createDOMCompilerError(
1069
+ 57,
1070
+ dir.loc
1071
+ )
1072
+ );
1073
+ break;
1074
+ default:
1075
+ checkDuplicatedValue();
1076
+ res.props = defaultProps;
1077
+ break;
1078
+ }
1067
1079
  }
1068
- return res;
1069
- }
1070
- else {
1071
- // component v-model
1072
- return compilerDom.transformModel(dir, node, context);
1080
+ } else if (compilerDom.hasDynamicKeyVBind(node)) ; else {
1081
+ checkDuplicatedValue();
1082
+ res.props = defaultProps;
1083
+ }
1084
+ } else if (node.tag === "textarea") {
1085
+ checkDuplicatedValue();
1086
+ node.children = [compilerDom.createInterpolation(model, model.loc)];
1087
+ } else if (node.tag === "select") ; else {
1088
+ context.onError(
1089
+ compilerDom.createDOMCompilerError(
1090
+ 55,
1091
+ dir.loc
1092
+ )
1093
+ );
1073
1094
  }
1095
+ return res;
1096
+ } else {
1097
+ return compilerDom.transformModel(dir, node, context);
1098
+ }
1074
1099
  };
1075
1100
  function findValueBinding(node) {
1076
- const valueBinding = compilerDom.findProp(node, 'value');
1077
- return valueBinding
1078
- ? valueBinding.type === 7 /* NodeTypes.DIRECTIVE */
1079
- ? valueBinding.exp
1080
- : compilerDom.createSimpleExpression(valueBinding.value.content, true)
1081
- : compilerDom.createSimpleExpression(`null`, false);
1101
+ const valueBinding = compilerDom.findProp(node, "value");
1102
+ return valueBinding ? valueBinding.type === 7 ? valueBinding.exp : compilerDom.createSimpleExpression(valueBinding.value.content, true) : compilerDom.createSimpleExpression(`null`, false);
1082
1103
  }
1083
1104
 
1084
1105
  const ssrTransformShow = (dir, node, context) => {
1085
- if (!dir.exp) {
1086
- context.onError(compilerDom.createDOMCompilerError(59 /* DOMErrorCodes.X_V_SHOW_NO_EXPRESSION */));
1087
- }
1088
- return {
1089
- props: [
1090
- compilerDom.createObjectProperty(`style`, compilerDom.createConditionalExpression(dir.exp, compilerDom.createSimpleExpression(`null`, false), compilerDom.createObjectExpression([
1091
- compilerDom.createObjectProperty(`display`, compilerDom.createSimpleExpression(`none`, true))
1092
- ]), false /* no newline */))
1093
- ]
1094
- };
1106
+ if (!dir.exp) {
1107
+ context.onError(
1108
+ compilerDom.createDOMCompilerError(59)
1109
+ );
1110
+ }
1111
+ return {
1112
+ props: [
1113
+ compilerDom.createObjectProperty(
1114
+ `style`,
1115
+ compilerDom.createConditionalExpression(
1116
+ dir.exp,
1117
+ compilerDom.createSimpleExpression(`null`, false),
1118
+ compilerDom.createObjectExpression([
1119
+ compilerDom.createObjectProperty(
1120
+ `display`,
1121
+ compilerDom.createSimpleExpression(`none`, true)
1122
+ )
1123
+ ]),
1124
+ false
1125
+ /* no newline */
1126
+ )
1127
+ )
1128
+ ]
1129
+ };
1095
1130
  };
1096
1131
 
1097
- const filterChild = (node) => node.children.filter(n => n.type !== 3 /* NodeTypes.COMMENT */);
1132
+ const filterChild = (node) => node.children.filter((n) => n.type !== "comment");
1098
1133
  const hasSingleChild = (node) => filterChild(node).length === 1;
1099
1134
  const ssrInjectFallthroughAttrs = (node, context) => {
1100
- // _attrs is provided as a function argument.
1101
- // mark it as a known identifier so that it doesn't get prefixed by
1102
- // transformExpression.
1103
- if (node.type === 0 /* NodeTypes.ROOT */) {
1104
- context.identifiers._attrs = 1;
1105
- }
1106
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1107
- node.tagType === 1 /* ElementTypes.COMPONENT */ &&
1108
- (compilerDom.isBuiltInType(node.tag, 'Transition') ||
1109
- compilerDom.isBuiltInType(node.tag, 'KeepAlive'))) {
1110
- const rootChildren = filterChild(context.root);
1111
- if (rootChildren.length === 1 && rootChildren[0] === node) {
1112
- if (hasSingleChild(node)) {
1113
- injectFallthroughAttrs(node.children[0]);
1114
- }
1115
- return;
1116
- }
1117
- }
1118
- const parent = context.parent;
1119
- if (!parent || parent.type !== 0 /* NodeTypes.ROOT */) {
1120
- return;
1121
- }
1122
- if (node.type === 10 /* NodeTypes.IF_BRANCH */ && hasSingleChild(node)) {
1123
- // detect cases where the parent v-if is not the only root level node
1124
- let hasEncounteredIf = false;
1125
- for (const c of filterChild(parent)) {
1126
- if (c.type === 9 /* NodeTypes.IF */ ||
1127
- (c.type === 1 /* NodeTypes.ELEMENT */ && compilerDom.findDir(c, 'if'))) {
1128
- // multiple root v-if
1129
- if (hasEncounteredIf)
1130
- return;
1131
- hasEncounteredIf = true;
1132
- }
1133
- else if (
1134
- // node before v-if
1135
- !hasEncounteredIf ||
1136
- // non else nodes
1137
- !(c.type === 1 /* NodeTypes.ELEMENT */ && compilerDom.findDir(c, /else/, true))) {
1138
- return;
1139
- }
1140
- }
1135
+ if (node.type === 0) {
1136
+ context.identifiers._attrs = 1;
1137
+ }
1138
+ if (node.type === "element" && node.tagType === 1 && (compilerDom.isBuiltInType(node.tag, "Transition") || compilerDom.isBuiltInType(node.tag, "KeepAlive"))) {
1139
+ const rootChildren = filterChild(context.root);
1140
+ if (rootChildren.length === 1 && rootChildren[0] === node) {
1141
+ if (hasSingleChild(node)) {
1141
1142
  injectFallthroughAttrs(node.children[0]);
1143
+ }
1144
+ return;
1142
1145
  }
1143
- else if (hasSingleChild(parent)) {
1144
- injectFallthroughAttrs(node);
1146
+ }
1147
+ const parent = context.parent;
1148
+ if (!parent || parent.type !== 0) {
1149
+ return;
1150
+ }
1151
+ if (node.type === 10 && hasSingleChild(node)) {
1152
+ let hasEncounteredIf = false;
1153
+ for (const c of filterChild(parent)) {
1154
+ if (c.type === 9 || c.type === "element" && compilerDom.findDir(c, "if")) {
1155
+ if (hasEncounteredIf)
1156
+ return;
1157
+ hasEncounteredIf = true;
1158
+ } else if (
1159
+ // node before v-if
1160
+ !hasEncounteredIf || // non else nodes
1161
+ !(c.type === "element" && compilerDom.findDir(c, /else/, true))
1162
+ ) {
1163
+ return;
1164
+ }
1145
1165
  }
1166
+ injectFallthroughAttrs(node.children[0]);
1167
+ } else if (hasSingleChild(parent)) {
1168
+ injectFallthroughAttrs(node);
1169
+ }
1146
1170
  };
1147
1171
  function injectFallthroughAttrs(node) {
1148
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1149
- (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
1150
- node.tagType === 1 /* ElementTypes.COMPONENT */) &&
1151
- !compilerDom.findDir(node, 'for')) {
1152
- node.props.push({
1153
- type: 7 /* NodeTypes.DIRECTIVE */,
1154
- name: 'bind',
1155
- arg: undefined,
1156
- exp: compilerDom.createSimpleExpression(`_attrs`, false),
1157
- modifiers: [],
1158
- loc: compilerDom.locStub
1159
- });
1160
- }
1172
+ if (node.type === "element" && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1173
+ node.props.push({
1174
+ type: 7,
1175
+ name: "bind",
1176
+ arg: void 0,
1177
+ exp: compilerDom.createSimpleExpression(`_attrs`, false),
1178
+ modifiers: [],
1179
+ loc: compilerDom.locStub
1180
+ });
1181
+ }
1161
1182
  }
1162
1183
 
1163
1184
  const ssrInjectCssVars = (node, context) => {
1164
- if (!context.ssrCssVars) {
1165
- return;
1166
- }
1167
- // _cssVars is initialized once per render function
1168
- // the code is injected in ssrCodegenTransform when creating the
1169
- // ssr transform context
1170
- if (node.type === 0 /* NodeTypes.ROOT */) {
1171
- context.identifiers._cssVars = 1;
1172
- }
1173
- const parent = context.parent;
1174
- if (!parent || parent.type !== 0 /* NodeTypes.ROOT */) {
1175
- return;
1176
- }
1177
- if (node.type === 10 /* NodeTypes.IF_BRANCH */) {
1178
- for (const child of node.children) {
1179
- injectCssVars(child);
1180
- }
1181
- }
1182
- else {
1183
- injectCssVars(node);
1185
+ if (!context.ssrCssVars) {
1186
+ return;
1187
+ }
1188
+ if (node.type === 0) {
1189
+ context.identifiers._cssVars = 1;
1190
+ }
1191
+ const parent = context.parent;
1192
+ if (!parent || parent.type !== 0) {
1193
+ return;
1194
+ }
1195
+ if (node.type === 10) {
1196
+ for (const child of node.children) {
1197
+ injectCssVars(child);
1184
1198
  }
1199
+ } else {
1200
+ injectCssVars(node);
1201
+ }
1185
1202
  };
1186
1203
  function injectCssVars(node) {
1187
- if (node.type === 1 /* NodeTypes.ELEMENT */ &&
1188
- (node.tagType === 0 /* ElementTypes.ELEMENT */ ||
1189
- node.tagType === 1 /* ElementTypes.COMPONENT */) &&
1190
- !compilerDom.findDir(node, 'for')) {
1191
- if (compilerDom.isBuiltInType(node.tag, 'Suspense')) {
1192
- for (const child of node.children) {
1193
- if (child.type === 1 /* NodeTypes.ELEMENT */ &&
1194
- child.tagType === 3 /* ElementTypes.TEMPLATE */) {
1195
- // suspense slot
1196
- child.children.forEach(injectCssVars);
1197
- }
1198
- else {
1199
- injectCssVars(child);
1200
- }
1201
- }
1202
- }
1203
- else {
1204
- node.props.push({
1205
- type: 7 /* NodeTypes.DIRECTIVE */,
1206
- name: 'bind',
1207
- arg: undefined,
1208
- exp: compilerDom.createSimpleExpression(`_cssVars`, false),
1209
- modifiers: [],
1210
- loc: compilerDom.locStub
1211
- });
1204
+ if (node.type === "element" && (node.tagType === 0 || node.tagType === 1) && !compilerDom.findDir(node, "for")) {
1205
+ if (compilerDom.isBuiltInType(node.tag, "Suspense")) {
1206
+ for (const child of node.children) {
1207
+ if (child.type === "element" && child.tagType === 3) {
1208
+ child.children.forEach(injectCssVars);
1209
+ } else {
1210
+ injectCssVars(child);
1212
1211
  }
1212
+ }
1213
+ } else {
1214
+ node.props.push({
1215
+ type: 7,
1216
+ name: "bind",
1217
+ arg: void 0,
1218
+ exp: compilerDom.createSimpleExpression(`_cssVars`, false),
1219
+ modifiers: [],
1220
+ loc: compilerDom.locStub
1221
+ });
1213
1222
  }
1223
+ }
1214
1224
  }
1215
1225
 
1216
1226
  function compile(template, options = {}) {
1217
- options = {
1218
- ...options,
1219
- // apply DOM-specific parsing options
1220
- ...compilerDom.parserOptions,
1221
- ssr: true,
1222
- inSSR: true,
1223
- scopeId: options.mode === 'function' ? null : options.scopeId,
1224
- // always prefix since compiler-ssr doesn't have size concern
1225
- prefixIdentifiers: true,
1226
- // disable optimizations that are unnecessary for ssr
1227
- cacheHandlers: false,
1228
- hoistStatic: false
1229
- };
1230
- const ast = compilerDom.baseParse(template, options);
1231
- // Save raw options for AST. This is needed when performing sub-transforms
1232
- // on slot vnode branches.
1233
- rawOptionsMap.set(ast, options);
1234
- compilerDom.transform(ast, {
1235
- ...options,
1236
- hoistStatic: false,
1237
- nodeTransforms: [
1238
- ssrTransformIf,
1239
- ssrTransformFor,
1240
- compilerDom.trackVForSlotScopes,
1241
- compilerDom.transformExpression,
1242
- ssrTransformSlotOutlet,
1243
- ssrInjectFallthroughAttrs,
1244
- ssrInjectCssVars,
1245
- ssrTransformElement,
1246
- ssrTransformComponent,
1247
- compilerDom.trackSlotScopes,
1248
- compilerDom.transformStyle,
1249
- ...(options.nodeTransforms || []) // user transforms
1250
- ],
1251
- directiveTransforms: {
1252
- // reusing core v-bind
1253
- bind: compilerDom.transformBind,
1254
- on: compilerDom.transformOn,
1255
- // model and show has dedicated SSR handling
1256
- model: ssrTransformModel,
1257
- show: ssrTransformShow,
1258
- // the following are ignored during SSR
1259
- // on: noopDirectiveTransform,
1260
- cloak: compilerDom.noopDirectiveTransform,
1261
- once: compilerDom.noopDirectiveTransform,
1262
- memo: compilerDom.noopDirectiveTransform,
1263
- ...(options.directiveTransforms || {}) // user transforms
1264
- }
1265
- });
1266
- // traverse the template AST and convert into SSR codegen AST
1267
- // by replacing ast.codegenNode.
1268
- ssrCodegenTransform(ast, options);
1269
- return compilerDom.generate(ast, options);
1227
+ options = {
1228
+ ...options,
1229
+ // apply DOM-specific parsing options
1230
+ ...compilerDom.parserOptions,
1231
+ ssr: true,
1232
+ inSSR: true,
1233
+ scopeId: options.mode === "function" ? null : options.scopeId,
1234
+ // always prefix since compiler-ssr doesn't have size concern
1235
+ prefixIdentifiers: true,
1236
+ // disable optimizations that are unnecessary for ssr
1237
+ cacheHandlers: false,
1238
+ hoistStatic: false
1239
+ };
1240
+ const ast = compilerDom.baseParse(template, options);
1241
+ rawOptionsMap.set(ast, options);
1242
+ compilerDom.transform(ast, {
1243
+ ...options,
1244
+ hoistStatic: false,
1245
+ nodeTransforms: [
1246
+ ssrTransformIf,
1247
+ ssrTransformFor,
1248
+ compilerDom.trackVForSlotScopes,
1249
+ compilerDom.transformExpression,
1250
+ ssrTransformSlotOutlet,
1251
+ ssrInjectFallthroughAttrs,
1252
+ ssrInjectCssVars,
1253
+ ssrTransformElement,
1254
+ ssrTransformComponent,
1255
+ compilerDom.trackSlotScopes,
1256
+ compilerDom.transformStyle,
1257
+ ...options.nodeTransforms || []
1258
+ // user transforms
1259
+ ],
1260
+ directiveTransforms: {
1261
+ // reusing core v-bind
1262
+ bind: compilerDom.transformBind,
1263
+ on: compilerDom.transformOn,
1264
+ // model and show has dedicated SSR handling
1265
+ model: ssrTransformModel,
1266
+ show: ssrTransformShow,
1267
+ // the following are ignored during SSR
1268
+ // on: noopDirectiveTransform,
1269
+ cloak: compilerDom.noopDirectiveTransform,
1270
+ once: compilerDom.noopDirectiveTransform,
1271
+ memo: compilerDom.noopDirectiveTransform,
1272
+ ...options.directiveTransforms || {}
1273
+ // user transforms
1274
+ }
1275
+ });
1276
+ ssrCodegenTransform(ast, options);
1277
+ return compilerDom.generate(ast, options);
1270
1278
  }
1271
1279
 
1272
1280
  exports.compile = compile;