@vue/server-renderer 3.2.40 → 3.2.41
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/server-renderer.cjs.js +964 -964
- package/dist/server-renderer.cjs.prod.js +726 -726
- package/dist/server-renderer.esm-browser.js +7882 -7880
- package/dist/server-renderer.esm-browser.prod.js +1 -1
- package/dist/server-renderer.esm-bundler.js +939 -939
- package/package.json +4 -4
|
@@ -6,1004 +6,1004 @@ var vue = require('vue');
|
|
|
6
6
|
var shared = require('@vue/shared');
|
|
7
7
|
var compilerSsr = require('@vue/compiler-ssr');
|
|
8
8
|
|
|
9
|
-
// leading comma for empty string ""
|
|
10
|
-
const shouldIgnoreProp = shared.makeMap(`,key,ref,innerHTML,textContent,ref_key,ref_for`);
|
|
11
|
-
function ssrRenderAttrs(props, tag) {
|
|
12
|
-
let ret = '';
|
|
13
|
-
for (const key in props) {
|
|
14
|
-
if (shouldIgnoreProp(key) ||
|
|
15
|
-
shared.isOn(key) ||
|
|
16
|
-
(tag === 'textarea' && key === 'value')) {
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
const value = props[key];
|
|
20
|
-
if (key === 'class') {
|
|
21
|
-
ret += ` class="${ssrRenderClass(value)}"`;
|
|
22
|
-
}
|
|
23
|
-
else if (key === 'style') {
|
|
24
|
-
ret += ` style="${ssrRenderStyle(value)}"`;
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
ret += ssrRenderDynamicAttr(key, value, tag);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return ret;
|
|
31
|
-
}
|
|
32
|
-
// render an attr with dynamic (unknown) key.
|
|
33
|
-
function ssrRenderDynamicAttr(key, value, tag) {
|
|
34
|
-
if (!isRenderableValue(value)) {
|
|
35
|
-
return ``;
|
|
36
|
-
}
|
|
37
|
-
const attrKey = tag && (tag.indexOf('-') > 0 || shared.isSVGTag(tag))
|
|
38
|
-
? key // preserve raw name on custom elements and svg
|
|
39
|
-
: shared.propsToAttrMap[key] || key.toLowerCase();
|
|
40
|
-
if (shared.isBooleanAttr(attrKey)) {
|
|
41
|
-
return shared.includeBooleanAttr(value) ? ` ${attrKey}` : ``;
|
|
42
|
-
}
|
|
43
|
-
else if (shared.isSSRSafeAttrName(attrKey)) {
|
|
44
|
-
return value === '' ? ` ${attrKey}` : ` ${attrKey}="${shared.escapeHtml(value)}"`;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.warn(`[@vue/server-renderer] Skipped rendering unsafe attribute name: ${attrKey}`);
|
|
48
|
-
return ``;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
// Render a v-bind attr with static key. The key is pre-processed at compile
|
|
52
|
-
// time and we only need to check and escape value.
|
|
53
|
-
function ssrRenderAttr(key, value) {
|
|
54
|
-
if (!isRenderableValue(value)) {
|
|
55
|
-
return ``;
|
|
56
|
-
}
|
|
57
|
-
return ` ${key}="${shared.escapeHtml(value)}"`;
|
|
58
|
-
}
|
|
59
|
-
function isRenderableValue(value) {
|
|
60
|
-
if (value == null) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
const type = typeof value;
|
|
64
|
-
return type === 'string' || type === 'number' || type === 'boolean';
|
|
65
|
-
}
|
|
66
|
-
function ssrRenderClass(raw) {
|
|
67
|
-
return shared.escapeHtml(shared.normalizeClass(raw));
|
|
68
|
-
}
|
|
69
|
-
function ssrRenderStyle(raw) {
|
|
70
|
-
if (!raw) {
|
|
71
|
-
return '';
|
|
72
|
-
}
|
|
73
|
-
if (shared.isString(raw)) {
|
|
74
|
-
return shared.escapeHtml(raw);
|
|
75
|
-
}
|
|
76
|
-
const styles = shared.normalizeStyle(raw);
|
|
77
|
-
return shared.escapeHtml(shared.stringifyStyle(styles));
|
|
9
|
+
// leading comma for empty string ""
|
|
10
|
+
const shouldIgnoreProp = shared.makeMap(`,key,ref,innerHTML,textContent,ref_key,ref_for`);
|
|
11
|
+
function ssrRenderAttrs(props, tag) {
|
|
12
|
+
let ret = '';
|
|
13
|
+
for (const key in props) {
|
|
14
|
+
if (shouldIgnoreProp(key) ||
|
|
15
|
+
shared.isOn(key) ||
|
|
16
|
+
(tag === 'textarea' && key === 'value')) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const value = props[key];
|
|
20
|
+
if (key === 'class') {
|
|
21
|
+
ret += ` class="${ssrRenderClass(value)}"`;
|
|
22
|
+
}
|
|
23
|
+
else if (key === 'style') {
|
|
24
|
+
ret += ` style="${ssrRenderStyle(value)}"`;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
ret += ssrRenderDynamicAttr(key, value, tag);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return ret;
|
|
31
|
+
}
|
|
32
|
+
// render an attr with dynamic (unknown) key.
|
|
33
|
+
function ssrRenderDynamicAttr(key, value, tag) {
|
|
34
|
+
if (!isRenderableValue(value)) {
|
|
35
|
+
return ``;
|
|
36
|
+
}
|
|
37
|
+
const attrKey = tag && (tag.indexOf('-') > 0 || shared.isSVGTag(tag))
|
|
38
|
+
? key // preserve raw name on custom elements and svg
|
|
39
|
+
: shared.propsToAttrMap[key] || key.toLowerCase();
|
|
40
|
+
if (shared.isBooleanAttr(attrKey)) {
|
|
41
|
+
return shared.includeBooleanAttr(value) ? ` ${attrKey}` : ``;
|
|
42
|
+
}
|
|
43
|
+
else if (shared.isSSRSafeAttrName(attrKey)) {
|
|
44
|
+
return value === '' ? ` ${attrKey}` : ` ${attrKey}="${shared.escapeHtml(value)}"`;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.warn(`[@vue/server-renderer] Skipped rendering unsafe attribute name: ${attrKey}`);
|
|
48
|
+
return ``;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Render a v-bind attr with static key. The key is pre-processed at compile
|
|
52
|
+
// time and we only need to check and escape value.
|
|
53
|
+
function ssrRenderAttr(key, value) {
|
|
54
|
+
if (!isRenderableValue(value)) {
|
|
55
|
+
return ``;
|
|
56
|
+
}
|
|
57
|
+
return ` ${key}="${shared.escapeHtml(value)}"`;
|
|
58
|
+
}
|
|
59
|
+
function isRenderableValue(value) {
|
|
60
|
+
if (value == null) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const type = typeof value;
|
|
64
|
+
return type === 'string' || type === 'number' || type === 'boolean';
|
|
65
|
+
}
|
|
66
|
+
function ssrRenderClass(raw) {
|
|
67
|
+
return shared.escapeHtml(shared.normalizeClass(raw));
|
|
68
|
+
}
|
|
69
|
+
function ssrRenderStyle(raw) {
|
|
70
|
+
if (!raw) {
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
if (shared.isString(raw)) {
|
|
74
|
+
return shared.escapeHtml(raw);
|
|
75
|
+
}
|
|
76
|
+
const styles = shared.normalizeStyle(raw);
|
|
77
|
+
return shared.escapeHtml(shared.stringifyStyle(styles));
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const compileCache = Object.create(null);
|
|
81
|
-
function ssrCompile(template, instance) {
|
|
82
|
-
// TODO: This is copied from runtime-core/src/component.ts and should probably be refactored
|
|
83
|
-
const Component = instance.type;
|
|
84
|
-
const { isCustomElement, compilerOptions } = instance.appContext.config;
|
|
85
|
-
const { delimiters, compilerOptions: componentCompilerOptions } = Component;
|
|
86
|
-
const finalCompilerOptions = shared.extend(shared.extend({
|
|
87
|
-
isCustomElement,
|
|
88
|
-
delimiters
|
|
89
|
-
}, compilerOptions), componentCompilerOptions);
|
|
90
|
-
finalCompilerOptions.isCustomElement =
|
|
91
|
-
finalCompilerOptions.isCustomElement || shared.NO;
|
|
92
|
-
finalCompilerOptions.isNativeTag = finalCompilerOptions.isNativeTag || shared.NO;
|
|
93
|
-
const cacheKey = JSON.stringify({
|
|
94
|
-
template,
|
|
95
|
-
compilerOptions: finalCompilerOptions
|
|
96
|
-
}, (key, value) => {
|
|
97
|
-
return shared.isFunction(value) ? value.toString() : value;
|
|
98
|
-
});
|
|
99
|
-
const cached = compileCache[cacheKey];
|
|
100
|
-
if (cached) {
|
|
101
|
-
return cached;
|
|
102
|
-
}
|
|
103
|
-
finalCompilerOptions.onError = (err) => {
|
|
104
|
-
{
|
|
105
|
-
const message = `[@vue/server-renderer] Template compilation error: ${err.message}`;
|
|
106
|
-
const codeFrame = err.loc &&
|
|
107
|
-
shared.generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
|
|
108
|
-
vue.warn(codeFrame ? `${message}\n${codeFrame}` : message);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
const { code } = compilerSsr.compile(template, finalCompilerOptions);
|
|
112
|
-
return (compileCache[cacheKey] = Function('require', code)(require));
|
|
80
|
+
const compileCache = Object.create(null);
|
|
81
|
+
function ssrCompile(template, instance) {
|
|
82
|
+
// TODO: This is copied from runtime-core/src/component.ts and should probably be refactored
|
|
83
|
+
const Component = instance.type;
|
|
84
|
+
const { isCustomElement, compilerOptions } = instance.appContext.config;
|
|
85
|
+
const { delimiters, compilerOptions: componentCompilerOptions } = Component;
|
|
86
|
+
const finalCompilerOptions = shared.extend(shared.extend({
|
|
87
|
+
isCustomElement,
|
|
88
|
+
delimiters
|
|
89
|
+
}, compilerOptions), componentCompilerOptions);
|
|
90
|
+
finalCompilerOptions.isCustomElement =
|
|
91
|
+
finalCompilerOptions.isCustomElement || shared.NO;
|
|
92
|
+
finalCompilerOptions.isNativeTag = finalCompilerOptions.isNativeTag || shared.NO;
|
|
93
|
+
const cacheKey = JSON.stringify({
|
|
94
|
+
template,
|
|
95
|
+
compilerOptions: finalCompilerOptions
|
|
96
|
+
}, (key, value) => {
|
|
97
|
+
return shared.isFunction(value) ? value.toString() : value;
|
|
98
|
+
});
|
|
99
|
+
const cached = compileCache[cacheKey];
|
|
100
|
+
if (cached) {
|
|
101
|
+
return cached;
|
|
102
|
+
}
|
|
103
|
+
finalCompilerOptions.onError = (err) => {
|
|
104
|
+
{
|
|
105
|
+
const message = `[@vue/server-renderer] Template compilation error: ${err.message}`;
|
|
106
|
+
const codeFrame = err.loc &&
|
|
107
|
+
shared.generateCodeFrame(template, err.loc.start.offset, err.loc.end.offset);
|
|
108
|
+
vue.warn(codeFrame ? `${message}\n${codeFrame}` : message);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const { code } = compilerSsr.compile(template, finalCompilerOptions);
|
|
112
|
+
return (compileCache[cacheKey] = Function('require', code)(require));
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function ssrRenderTeleport(parentPush, contentRenderFn, target, disabled, parentComponent) {
|
|
116
|
-
parentPush('<!--teleport start-->');
|
|
117
|
-
const context = parentComponent.appContext.provides[vue.ssrContextKey];
|
|
118
|
-
const teleportBuffers = context.__teleportBuffers || (context.__teleportBuffers = {});
|
|
119
|
-
const targetBuffer = teleportBuffers[target] || (teleportBuffers[target] = []);
|
|
120
|
-
// record current index of the target buffer to handle nested teleports
|
|
121
|
-
// since the parent needs to be rendered before the child
|
|
122
|
-
const bufferIndex = targetBuffer.length;
|
|
123
|
-
let teleportContent;
|
|
124
|
-
if (disabled) {
|
|
125
|
-
contentRenderFn(parentPush);
|
|
126
|
-
teleportContent = `<!--teleport anchor-->`;
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
const { getBuffer, push } = createBuffer();
|
|
130
|
-
contentRenderFn(push);
|
|
131
|
-
push(`<!--teleport anchor-->`);
|
|
132
|
-
teleportContent = getBuffer();
|
|
133
|
-
}
|
|
134
|
-
targetBuffer.splice(bufferIndex, 0, teleportContent);
|
|
135
|
-
parentPush('<!--teleport end-->');
|
|
115
|
+
function ssrRenderTeleport(parentPush, contentRenderFn, target, disabled, parentComponent) {
|
|
116
|
+
parentPush('<!--teleport start-->');
|
|
117
|
+
const context = parentComponent.appContext.provides[vue.ssrContextKey];
|
|
118
|
+
const teleportBuffers = context.__teleportBuffers || (context.__teleportBuffers = {});
|
|
119
|
+
const targetBuffer = teleportBuffers[target] || (teleportBuffers[target] = []);
|
|
120
|
+
// record current index of the target buffer to handle nested teleports
|
|
121
|
+
// since the parent needs to be rendered before the child
|
|
122
|
+
const bufferIndex = targetBuffer.length;
|
|
123
|
+
let teleportContent;
|
|
124
|
+
if (disabled) {
|
|
125
|
+
contentRenderFn(parentPush);
|
|
126
|
+
teleportContent = `<!--teleport anchor-->`;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const { getBuffer, push } = createBuffer();
|
|
130
|
+
contentRenderFn(push);
|
|
131
|
+
push(`<!--teleport anchor-->`);
|
|
132
|
+
teleportContent = getBuffer();
|
|
133
|
+
}
|
|
134
|
+
targetBuffer.splice(bufferIndex, 0, teleportContent);
|
|
135
|
+
parentPush('<!--teleport end-->');
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
const { createComponentInstance, setCurrentRenderingInstance, setupComponent, renderComponentRoot, normalizeVNode } = vue.ssrUtils;
|
|
139
|
-
// Each component has a buffer array.
|
|
140
|
-
// A buffer array can contain one of the following:
|
|
141
|
-
// - plain string
|
|
142
|
-
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
|
143
|
-
// synchronously)
|
|
144
|
-
// - An async buffer (a Promise that resolves to a resolved buffer)
|
|
145
|
-
function createBuffer() {
|
|
146
|
-
let appendable = false;
|
|
147
|
-
const buffer = [];
|
|
148
|
-
return {
|
|
149
|
-
getBuffer() {
|
|
150
|
-
// Return static buffer and await on items during unroll stage
|
|
151
|
-
return buffer;
|
|
152
|
-
},
|
|
153
|
-
push(item) {
|
|
154
|
-
const isStringItem = shared.isString(item);
|
|
155
|
-
if (appendable && isStringItem) {
|
|
156
|
-
buffer[buffer.length - 1] += item;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
buffer.push(item);
|
|
160
|
-
}
|
|
161
|
-
appendable = isStringItem;
|
|
162
|
-
if (shared.isPromise(item) || (shared.isArray(item) && item.hasAsync)) {
|
|
163
|
-
// promise, or child buffer with async, mark as async.
|
|
164
|
-
// this allows skipping unnecessary await ticks during unroll stage
|
|
165
|
-
buffer.hasAsync = true;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function renderComponentVNode(vnode, parentComponent = null, slotScopeId) {
|
|
171
|
-
const instance = createComponentInstance(vnode, parentComponent, null);
|
|
172
|
-
const res = setupComponent(instance, true /* isSSR */);
|
|
173
|
-
const hasAsyncSetup = shared.isPromise(res);
|
|
174
|
-
const prefetches = instance.sp; /* LifecycleHooks.SERVER_PREFETCH */
|
|
175
|
-
if (hasAsyncSetup || prefetches) {
|
|
176
|
-
let p = hasAsyncSetup
|
|
177
|
-
? res
|
|
178
|
-
: Promise.resolve();
|
|
179
|
-
if (prefetches) {
|
|
180
|
-
p = p
|
|
181
|
-
.then(() => Promise.all(prefetches.map(prefetch => prefetch.call(instance.proxy))))
|
|
182
|
-
// Note: error display is already done by the wrapped lifecycle hook function.
|
|
183
|
-
.catch(() => { });
|
|
184
|
-
}
|
|
185
|
-
return p.then(() => renderComponentSubTree(instance, slotScopeId));
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
return renderComponentSubTree(instance, slotScopeId);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
function renderComponentSubTree(instance, slotScopeId) {
|
|
192
|
-
const comp = instance.type;
|
|
193
|
-
const { getBuffer, push } = createBuffer();
|
|
194
|
-
if (shared.isFunction(comp)) {
|
|
195
|
-
let root = renderComponentRoot(instance);
|
|
196
|
-
// #5817 scope ID attrs not falling through if functional component doesn't
|
|
197
|
-
// have props
|
|
198
|
-
if (!comp.props) {
|
|
199
|
-
for (const key in instance.attrs) {
|
|
200
|
-
if (key.startsWith(`data-v-`)) {
|
|
201
|
-
(root.props || (root.props = {}))[key] = ``;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
renderVNode(push, (instance.subTree = root), instance, slotScopeId);
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
if ((!instance.render || instance.render === shared.NOOP) &&
|
|
209
|
-
!instance.ssrRender &&
|
|
210
|
-
!comp.ssrRender &&
|
|
211
|
-
shared.isString(comp.template)) {
|
|
212
|
-
comp.ssrRender = ssrCompile(comp.template, instance);
|
|
213
|
-
}
|
|
214
|
-
// perf: enable caching of computed getters during render
|
|
215
|
-
// since there cannot be state mutations during render.
|
|
216
|
-
for (const e of instance.scope.effects) {
|
|
217
|
-
if (e.computed)
|
|
218
|
-
e.computed._cacheable = true;
|
|
219
|
-
}
|
|
220
|
-
const ssrRender = instance.ssrRender || comp.ssrRender;
|
|
221
|
-
if (ssrRender) {
|
|
222
|
-
// optimized
|
|
223
|
-
// resolve fallthrough attrs
|
|
224
|
-
let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined;
|
|
225
|
-
let hasCloned = false;
|
|
226
|
-
let cur = instance;
|
|
227
|
-
while (true) {
|
|
228
|
-
const scopeId = cur.vnode.scopeId;
|
|
229
|
-
if (scopeId) {
|
|
230
|
-
if (!hasCloned) {
|
|
231
|
-
attrs = { ...attrs };
|
|
232
|
-
hasCloned = true;
|
|
233
|
-
}
|
|
234
|
-
attrs[scopeId] = '';
|
|
235
|
-
}
|
|
236
|
-
const parent = cur.parent;
|
|
237
|
-
if (parent && parent.subTree && parent.subTree === cur.vnode) {
|
|
238
|
-
// parent is a non-SSR compiled component and is rendering this
|
|
239
|
-
// component as root. inherit its scopeId if present.
|
|
240
|
-
cur = parent;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (slotScopeId) {
|
|
247
|
-
if (!hasCloned)
|
|
248
|
-
attrs = { ...attrs };
|
|
249
|
-
attrs[slotScopeId.trim()] = '';
|
|
250
|
-
}
|
|
251
|
-
// set current rendering instance for asset resolution
|
|
252
|
-
const prev = setCurrentRenderingInstance(instance);
|
|
253
|
-
try {
|
|
254
|
-
ssrRender(instance.proxy, push, instance, attrs,
|
|
255
|
-
// compiler-optimized bindings
|
|
256
|
-
instance.props, instance.setupState, instance.data, instance.ctx);
|
|
257
|
-
}
|
|
258
|
-
finally {
|
|
259
|
-
setCurrentRenderingInstance(prev);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
else if (instance.render && instance.render !== shared.NOOP) {
|
|
263
|
-
renderVNode(push, (instance.subTree = renderComponentRoot(instance)), instance, slotScopeId);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
const componentName = comp.name || comp.__file || `<Anonymous>`;
|
|
267
|
-
vue.warn(`Component ${componentName} is missing template or render function.`);
|
|
268
|
-
push(`<!---->`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return getBuffer();
|
|
272
|
-
}
|
|
273
|
-
function renderVNode(push, vnode, parentComponent, slotScopeId) {
|
|
274
|
-
const { type, shapeFlag, children } = vnode;
|
|
275
|
-
switch (type) {
|
|
276
|
-
case vue.Text:
|
|
277
|
-
push(shared.escapeHtml(children));
|
|
278
|
-
break;
|
|
279
|
-
case vue.Comment:
|
|
280
|
-
push(children ? `<!--${shared.escapeHtmlComment(children)}-->` : `<!---->`);
|
|
281
|
-
break;
|
|
282
|
-
case vue.Static:
|
|
283
|
-
push(children);
|
|
284
|
-
break;
|
|
285
|
-
case vue.Fragment:
|
|
286
|
-
if (vnode.slotScopeIds) {
|
|
287
|
-
slotScopeId =
|
|
288
|
-
(slotScopeId ? slotScopeId + ' ' : '') + vnode.slotScopeIds.join(' ');
|
|
289
|
-
}
|
|
290
|
-
push(`<!--[-->`); // open
|
|
291
|
-
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
292
|
-
push(`<!--]-->`); // close
|
|
293
|
-
break;
|
|
294
|
-
default:
|
|
295
|
-
if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
|
|
296
|
-
renderElementVNode(push, vnode, parentComponent, slotScopeId);
|
|
297
|
-
}
|
|
298
|
-
else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
|
|
299
|
-
push(renderComponentVNode(vnode, parentComponent, slotScopeId));
|
|
300
|
-
}
|
|
301
|
-
else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
|
|
302
|
-
renderTeleportVNode(push, vnode, parentComponent, slotScopeId);
|
|
303
|
-
}
|
|
304
|
-
else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
|
|
305
|
-
renderVNode(push, vnode.ssContent, parentComponent, slotScopeId);
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
vue.warn('[@vue/server-renderer] Invalid VNode type:', type, `(${typeof type})`);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
function renderVNodeChildren(push, children, parentComponent, slotScopeId) {
|
|
313
|
-
for (let i = 0; i < children.length; i++) {
|
|
314
|
-
renderVNode(push, normalizeVNode(children[i]), parentComponent, slotScopeId);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
function renderElementVNode(push, vnode, parentComponent, slotScopeId) {
|
|
318
|
-
const tag = vnode.type;
|
|
319
|
-
let { props, children, shapeFlag, scopeId, dirs } = vnode;
|
|
320
|
-
let openTag = `<${tag}`;
|
|
321
|
-
if (dirs) {
|
|
322
|
-
props = applySSRDirectives(vnode, props, dirs);
|
|
323
|
-
}
|
|
324
|
-
if (props) {
|
|
325
|
-
openTag += ssrRenderAttrs(props, tag);
|
|
326
|
-
}
|
|
327
|
-
if (scopeId) {
|
|
328
|
-
openTag += ` ${scopeId}`;
|
|
329
|
-
}
|
|
330
|
-
// inherit parent chain scope id if this is the root node
|
|
331
|
-
let curParent = parentComponent;
|
|
332
|
-
let curVnode = vnode;
|
|
333
|
-
while (curParent && curVnode === curParent.subTree) {
|
|
334
|
-
curVnode = curParent.vnode;
|
|
335
|
-
if (curVnode.scopeId) {
|
|
336
|
-
openTag += ` ${curVnode.scopeId}`;
|
|
337
|
-
}
|
|
338
|
-
curParent = curParent.parent;
|
|
339
|
-
}
|
|
340
|
-
if (slotScopeId) {
|
|
341
|
-
openTag += ` ${slotScopeId}`;
|
|
342
|
-
}
|
|
343
|
-
push(openTag + `>`);
|
|
344
|
-
if (!shared.isVoidTag(tag)) {
|
|
345
|
-
let hasChildrenOverride = false;
|
|
346
|
-
if (props) {
|
|
347
|
-
if (props.innerHTML) {
|
|
348
|
-
hasChildrenOverride = true;
|
|
349
|
-
push(props.innerHTML);
|
|
350
|
-
}
|
|
351
|
-
else if (props.textContent) {
|
|
352
|
-
hasChildrenOverride = true;
|
|
353
|
-
push(shared.escapeHtml(props.textContent));
|
|
354
|
-
}
|
|
355
|
-
else if (tag === 'textarea' && props.value) {
|
|
356
|
-
hasChildrenOverride = true;
|
|
357
|
-
push(shared.escapeHtml(props.value));
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
if (!hasChildrenOverride) {
|
|
361
|
-
if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
|
|
362
|
-
push(shared.escapeHtml(children));
|
|
363
|
-
}
|
|
364
|
-
else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
|
|
365
|
-
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
push(`</${tag}>`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function applySSRDirectives(vnode, rawProps, dirs) {
|
|
372
|
-
const toMerge = [];
|
|
373
|
-
for (let i = 0; i < dirs.length; i++) {
|
|
374
|
-
const binding = dirs[i];
|
|
375
|
-
const { dir: { getSSRProps } } = binding;
|
|
376
|
-
if (getSSRProps) {
|
|
377
|
-
const props = getSSRProps(binding, vnode);
|
|
378
|
-
if (props)
|
|
379
|
-
toMerge.push(props);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return vue.mergeProps(rawProps || {}, ...toMerge);
|
|
383
|
-
}
|
|
384
|
-
function renderTeleportVNode(push, vnode, parentComponent, slotScopeId) {
|
|
385
|
-
const target = vnode.props && vnode.props.to;
|
|
386
|
-
const disabled = vnode.props && vnode.props.disabled;
|
|
387
|
-
if (!target) {
|
|
388
|
-
if (!disabled) {
|
|
389
|
-
vue.warn(`[@vue/server-renderer] Teleport is missing target prop.`);
|
|
390
|
-
}
|
|
391
|
-
return [];
|
|
392
|
-
}
|
|
393
|
-
if (!shared.isString(target)) {
|
|
394
|
-
vue.warn(`[@vue/server-renderer] Teleport target must be a query selector string.`);
|
|
395
|
-
return [];
|
|
396
|
-
}
|
|
397
|
-
ssrRenderTeleport(push, push => {
|
|
398
|
-
renderVNodeChildren(push, vnode.children, parentComponent, slotScopeId);
|
|
399
|
-
}, target, disabled || disabled === '', parentComponent);
|
|
138
|
+
const { createComponentInstance, setCurrentRenderingInstance, setupComponent, renderComponentRoot, normalizeVNode } = vue.ssrUtils;
|
|
139
|
+
// Each component has a buffer array.
|
|
140
|
+
// A buffer array can contain one of the following:
|
|
141
|
+
// - plain string
|
|
142
|
+
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
|
143
|
+
// synchronously)
|
|
144
|
+
// - An async buffer (a Promise that resolves to a resolved buffer)
|
|
145
|
+
function createBuffer() {
|
|
146
|
+
let appendable = false;
|
|
147
|
+
const buffer = [];
|
|
148
|
+
return {
|
|
149
|
+
getBuffer() {
|
|
150
|
+
// Return static buffer and await on items during unroll stage
|
|
151
|
+
return buffer;
|
|
152
|
+
},
|
|
153
|
+
push(item) {
|
|
154
|
+
const isStringItem = shared.isString(item);
|
|
155
|
+
if (appendable && isStringItem) {
|
|
156
|
+
buffer[buffer.length - 1] += item;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
buffer.push(item);
|
|
160
|
+
}
|
|
161
|
+
appendable = isStringItem;
|
|
162
|
+
if (shared.isPromise(item) || (shared.isArray(item) && item.hasAsync)) {
|
|
163
|
+
// promise, or child buffer with async, mark as async.
|
|
164
|
+
// this allows skipping unnecessary await ticks during unroll stage
|
|
165
|
+
buffer.hasAsync = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function renderComponentVNode(vnode, parentComponent = null, slotScopeId) {
|
|
171
|
+
const instance = createComponentInstance(vnode, parentComponent, null);
|
|
172
|
+
const res = setupComponent(instance, true /* isSSR */);
|
|
173
|
+
const hasAsyncSetup = shared.isPromise(res);
|
|
174
|
+
const prefetches = instance.sp; /* LifecycleHooks.SERVER_PREFETCH */
|
|
175
|
+
if (hasAsyncSetup || prefetches) {
|
|
176
|
+
let p = hasAsyncSetup
|
|
177
|
+
? res
|
|
178
|
+
: Promise.resolve();
|
|
179
|
+
if (prefetches) {
|
|
180
|
+
p = p
|
|
181
|
+
.then(() => Promise.all(prefetches.map(prefetch => prefetch.call(instance.proxy))))
|
|
182
|
+
// Note: error display is already done by the wrapped lifecycle hook function.
|
|
183
|
+
.catch(() => { });
|
|
184
|
+
}
|
|
185
|
+
return p.then(() => renderComponentSubTree(instance, slotScopeId));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return renderComponentSubTree(instance, slotScopeId);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function renderComponentSubTree(instance, slotScopeId) {
|
|
192
|
+
const comp = instance.type;
|
|
193
|
+
const { getBuffer, push } = createBuffer();
|
|
194
|
+
if (shared.isFunction(comp)) {
|
|
195
|
+
let root = renderComponentRoot(instance);
|
|
196
|
+
// #5817 scope ID attrs not falling through if functional component doesn't
|
|
197
|
+
// have props
|
|
198
|
+
if (!comp.props) {
|
|
199
|
+
for (const key in instance.attrs) {
|
|
200
|
+
if (key.startsWith(`data-v-`)) {
|
|
201
|
+
(root.props || (root.props = {}))[key] = ``;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
renderVNode(push, (instance.subTree = root), instance, slotScopeId);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
if ((!instance.render || instance.render === shared.NOOP) &&
|
|
209
|
+
!instance.ssrRender &&
|
|
210
|
+
!comp.ssrRender &&
|
|
211
|
+
shared.isString(comp.template)) {
|
|
212
|
+
comp.ssrRender = ssrCompile(comp.template, instance);
|
|
213
|
+
}
|
|
214
|
+
// perf: enable caching of computed getters during render
|
|
215
|
+
// since there cannot be state mutations during render.
|
|
216
|
+
for (const e of instance.scope.effects) {
|
|
217
|
+
if (e.computed)
|
|
218
|
+
e.computed._cacheable = true;
|
|
219
|
+
}
|
|
220
|
+
const ssrRender = instance.ssrRender || comp.ssrRender;
|
|
221
|
+
if (ssrRender) {
|
|
222
|
+
// optimized
|
|
223
|
+
// resolve fallthrough attrs
|
|
224
|
+
let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined;
|
|
225
|
+
let hasCloned = false;
|
|
226
|
+
let cur = instance;
|
|
227
|
+
while (true) {
|
|
228
|
+
const scopeId = cur.vnode.scopeId;
|
|
229
|
+
if (scopeId) {
|
|
230
|
+
if (!hasCloned) {
|
|
231
|
+
attrs = { ...attrs };
|
|
232
|
+
hasCloned = true;
|
|
233
|
+
}
|
|
234
|
+
attrs[scopeId] = '';
|
|
235
|
+
}
|
|
236
|
+
const parent = cur.parent;
|
|
237
|
+
if (parent && parent.subTree && parent.subTree === cur.vnode) {
|
|
238
|
+
// parent is a non-SSR compiled component and is rendering this
|
|
239
|
+
// component as root. inherit its scopeId if present.
|
|
240
|
+
cur = parent;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (slotScopeId) {
|
|
247
|
+
if (!hasCloned)
|
|
248
|
+
attrs = { ...attrs };
|
|
249
|
+
attrs[slotScopeId.trim()] = '';
|
|
250
|
+
}
|
|
251
|
+
// set current rendering instance for asset resolution
|
|
252
|
+
const prev = setCurrentRenderingInstance(instance);
|
|
253
|
+
try {
|
|
254
|
+
ssrRender(instance.proxy, push, instance, attrs,
|
|
255
|
+
// compiler-optimized bindings
|
|
256
|
+
instance.props, instance.setupState, instance.data, instance.ctx);
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
setCurrentRenderingInstance(prev);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (instance.render && instance.render !== shared.NOOP) {
|
|
263
|
+
renderVNode(push, (instance.subTree = renderComponentRoot(instance)), instance, slotScopeId);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
const componentName = comp.name || comp.__file || `<Anonymous>`;
|
|
267
|
+
vue.warn(`Component ${componentName} is missing template or render function.`);
|
|
268
|
+
push(`<!---->`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return getBuffer();
|
|
272
|
+
}
|
|
273
|
+
function renderVNode(push, vnode, parentComponent, slotScopeId) {
|
|
274
|
+
const { type, shapeFlag, children } = vnode;
|
|
275
|
+
switch (type) {
|
|
276
|
+
case vue.Text:
|
|
277
|
+
push(shared.escapeHtml(children));
|
|
278
|
+
break;
|
|
279
|
+
case vue.Comment:
|
|
280
|
+
push(children ? `<!--${shared.escapeHtmlComment(children)}-->` : `<!---->`);
|
|
281
|
+
break;
|
|
282
|
+
case vue.Static:
|
|
283
|
+
push(children);
|
|
284
|
+
break;
|
|
285
|
+
case vue.Fragment:
|
|
286
|
+
if (vnode.slotScopeIds) {
|
|
287
|
+
slotScopeId =
|
|
288
|
+
(slotScopeId ? slotScopeId + ' ' : '') + vnode.slotScopeIds.join(' ');
|
|
289
|
+
}
|
|
290
|
+
push(`<!--[-->`); // open
|
|
291
|
+
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
292
|
+
push(`<!--]-->`); // close
|
|
293
|
+
break;
|
|
294
|
+
default:
|
|
295
|
+
if (shapeFlag & 1 /* ShapeFlags.ELEMENT */) {
|
|
296
|
+
renderElementVNode(push, vnode, parentComponent, slotScopeId);
|
|
297
|
+
}
|
|
298
|
+
else if (shapeFlag & 6 /* ShapeFlags.COMPONENT */) {
|
|
299
|
+
push(renderComponentVNode(vnode, parentComponent, slotScopeId));
|
|
300
|
+
}
|
|
301
|
+
else if (shapeFlag & 64 /* ShapeFlags.TELEPORT */) {
|
|
302
|
+
renderTeleportVNode(push, vnode, parentComponent, slotScopeId);
|
|
303
|
+
}
|
|
304
|
+
else if (shapeFlag & 128 /* ShapeFlags.SUSPENSE */) {
|
|
305
|
+
renderVNode(push, vnode.ssContent, parentComponent, slotScopeId);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
vue.warn('[@vue/server-renderer] Invalid VNode type:', type, `(${typeof type})`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function renderVNodeChildren(push, children, parentComponent, slotScopeId) {
|
|
313
|
+
for (let i = 0; i < children.length; i++) {
|
|
314
|
+
renderVNode(push, normalizeVNode(children[i]), parentComponent, slotScopeId);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function renderElementVNode(push, vnode, parentComponent, slotScopeId) {
|
|
318
|
+
const tag = vnode.type;
|
|
319
|
+
let { props, children, shapeFlag, scopeId, dirs } = vnode;
|
|
320
|
+
let openTag = `<${tag}`;
|
|
321
|
+
if (dirs) {
|
|
322
|
+
props = applySSRDirectives(vnode, props, dirs);
|
|
323
|
+
}
|
|
324
|
+
if (props) {
|
|
325
|
+
openTag += ssrRenderAttrs(props, tag);
|
|
326
|
+
}
|
|
327
|
+
if (scopeId) {
|
|
328
|
+
openTag += ` ${scopeId}`;
|
|
329
|
+
}
|
|
330
|
+
// inherit parent chain scope id if this is the root node
|
|
331
|
+
let curParent = parentComponent;
|
|
332
|
+
let curVnode = vnode;
|
|
333
|
+
while (curParent && curVnode === curParent.subTree) {
|
|
334
|
+
curVnode = curParent.vnode;
|
|
335
|
+
if (curVnode.scopeId) {
|
|
336
|
+
openTag += ` ${curVnode.scopeId}`;
|
|
337
|
+
}
|
|
338
|
+
curParent = curParent.parent;
|
|
339
|
+
}
|
|
340
|
+
if (slotScopeId) {
|
|
341
|
+
openTag += ` ${slotScopeId}`;
|
|
342
|
+
}
|
|
343
|
+
push(openTag + `>`);
|
|
344
|
+
if (!shared.isVoidTag(tag)) {
|
|
345
|
+
let hasChildrenOverride = false;
|
|
346
|
+
if (props) {
|
|
347
|
+
if (props.innerHTML) {
|
|
348
|
+
hasChildrenOverride = true;
|
|
349
|
+
push(props.innerHTML);
|
|
350
|
+
}
|
|
351
|
+
else if (props.textContent) {
|
|
352
|
+
hasChildrenOverride = true;
|
|
353
|
+
push(shared.escapeHtml(props.textContent));
|
|
354
|
+
}
|
|
355
|
+
else if (tag === 'textarea' && props.value) {
|
|
356
|
+
hasChildrenOverride = true;
|
|
357
|
+
push(shared.escapeHtml(props.value));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (!hasChildrenOverride) {
|
|
361
|
+
if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
|
|
362
|
+
push(shared.escapeHtml(children));
|
|
363
|
+
}
|
|
364
|
+
else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
|
|
365
|
+
renderVNodeChildren(push, children, parentComponent, slotScopeId);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
push(`</${tag}>`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function applySSRDirectives(vnode, rawProps, dirs) {
|
|
372
|
+
const toMerge = [];
|
|
373
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
374
|
+
const binding = dirs[i];
|
|
375
|
+
const { dir: { getSSRProps } } = binding;
|
|
376
|
+
if (getSSRProps) {
|
|
377
|
+
const props = getSSRProps(binding, vnode);
|
|
378
|
+
if (props)
|
|
379
|
+
toMerge.push(props);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return vue.mergeProps(rawProps || {}, ...toMerge);
|
|
383
|
+
}
|
|
384
|
+
function renderTeleportVNode(push, vnode, parentComponent, slotScopeId) {
|
|
385
|
+
const target = vnode.props && vnode.props.to;
|
|
386
|
+
const disabled = vnode.props && vnode.props.disabled;
|
|
387
|
+
if (!target) {
|
|
388
|
+
if (!disabled) {
|
|
389
|
+
vue.warn(`[@vue/server-renderer] Teleport is missing target prop.`);
|
|
390
|
+
}
|
|
391
|
+
return [];
|
|
392
|
+
}
|
|
393
|
+
if (!shared.isString(target)) {
|
|
394
|
+
vue.warn(`[@vue/server-renderer] Teleport target must be a query selector string.`);
|
|
395
|
+
return [];
|
|
396
|
+
}
|
|
397
|
+
ssrRenderTeleport(push, push => {
|
|
398
|
+
renderVNodeChildren(push, vnode.children, parentComponent, slotScopeId);
|
|
399
|
+
}, target, disabled || disabled === '', parentComponent);
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
const { isVNode } = vue.ssrUtils;
|
|
403
|
-
async function unrollBuffer(buffer) {
|
|
404
|
-
if (buffer.hasAsync) {
|
|
405
|
-
let ret = '';
|
|
406
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
407
|
-
let item = buffer[i];
|
|
408
|
-
if (shared.isPromise(item)) {
|
|
409
|
-
item = await item;
|
|
410
|
-
}
|
|
411
|
-
if (shared.isString(item)) {
|
|
412
|
-
ret += item;
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
ret += await unrollBuffer(item);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return ret;
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
422
|
-
// ticks
|
|
423
|
-
return unrollBufferSync(buffer);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
function unrollBufferSync(buffer) {
|
|
427
|
-
let ret = '';
|
|
428
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
429
|
-
let item = buffer[i];
|
|
430
|
-
if (shared.isString(item)) {
|
|
431
|
-
ret += item;
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
// since this is a sync buffer, child buffers are never promises
|
|
435
|
-
ret += unrollBufferSync(item);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return ret;
|
|
439
|
-
}
|
|
440
|
-
async function renderToString(input, context = {}) {
|
|
441
|
-
if (isVNode(input)) {
|
|
442
|
-
// raw vnode, wrap with app (for context)
|
|
443
|
-
return renderToString(vue.createApp({ render: () => input }), context);
|
|
444
|
-
}
|
|
445
|
-
// rendering an app
|
|
446
|
-
const vnode = vue.createVNode(input._component, input._props);
|
|
447
|
-
vnode.appContext = input._context;
|
|
448
|
-
// provide the ssr context to the tree
|
|
449
|
-
input.provide(vue.ssrContextKey, context);
|
|
450
|
-
const buffer = await renderComponentVNode(vnode);
|
|
451
|
-
const result = await unrollBuffer(buffer);
|
|
452
|
-
await resolveTeleports(context);
|
|
453
|
-
return result;
|
|
454
|
-
}
|
|
455
|
-
async function resolveTeleports(context) {
|
|
456
|
-
if (context.__teleportBuffers) {
|
|
457
|
-
context.teleports = context.teleports || {};
|
|
458
|
-
for (const key in context.__teleportBuffers) {
|
|
459
|
-
// note: it's OK to await sequentially here because the Promises were
|
|
460
|
-
// created eagerly in parallel.
|
|
461
|
-
context.teleports[key] = await unrollBuffer(await Promise.all([context.__teleportBuffers[key]]));
|
|
462
|
-
}
|
|
463
|
-
}
|
|
402
|
+
const { isVNode } = vue.ssrUtils;
|
|
403
|
+
async function unrollBuffer(buffer) {
|
|
404
|
+
if (buffer.hasAsync) {
|
|
405
|
+
let ret = '';
|
|
406
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
407
|
+
let item = buffer[i];
|
|
408
|
+
if (shared.isPromise(item)) {
|
|
409
|
+
item = await item;
|
|
410
|
+
}
|
|
411
|
+
if (shared.isString(item)) {
|
|
412
|
+
ret += item;
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
ret += await unrollBuffer(item);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return ret;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
422
|
+
// ticks
|
|
423
|
+
return unrollBufferSync(buffer);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function unrollBufferSync(buffer) {
|
|
427
|
+
let ret = '';
|
|
428
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
429
|
+
let item = buffer[i];
|
|
430
|
+
if (shared.isString(item)) {
|
|
431
|
+
ret += item;
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
// since this is a sync buffer, child buffers are never promises
|
|
435
|
+
ret += unrollBufferSync(item);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return ret;
|
|
439
|
+
}
|
|
440
|
+
async function renderToString(input, context = {}) {
|
|
441
|
+
if (isVNode(input)) {
|
|
442
|
+
// raw vnode, wrap with app (for context)
|
|
443
|
+
return renderToString(vue.createApp({ render: () => input }), context);
|
|
444
|
+
}
|
|
445
|
+
// rendering an app
|
|
446
|
+
const vnode = vue.createVNode(input._component, input._props);
|
|
447
|
+
vnode.appContext = input._context;
|
|
448
|
+
// provide the ssr context to the tree
|
|
449
|
+
input.provide(vue.ssrContextKey, context);
|
|
450
|
+
const buffer = await renderComponentVNode(vnode);
|
|
451
|
+
const result = await unrollBuffer(buffer);
|
|
452
|
+
await resolveTeleports(context);
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
455
|
+
async function resolveTeleports(context) {
|
|
456
|
+
if (context.__teleportBuffers) {
|
|
457
|
+
context.teleports = context.teleports || {};
|
|
458
|
+
for (const key in context.__teleportBuffers) {
|
|
459
|
+
// note: it's OK to await sequentially here because the Promises were
|
|
460
|
+
// created eagerly in parallel.
|
|
461
|
+
context.teleports[key] = await unrollBuffer(await Promise.all([context.__teleportBuffers[key]]));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
-
const { isVNode: isVNode$1 } = vue.ssrUtils;
|
|
467
|
-
async function unrollBuffer$1(buffer, stream) {
|
|
468
|
-
if (buffer.hasAsync) {
|
|
469
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
470
|
-
let item = buffer[i];
|
|
471
|
-
if (shared.isPromise(item)) {
|
|
472
|
-
item = await item;
|
|
473
|
-
}
|
|
474
|
-
if (shared.isString(item)) {
|
|
475
|
-
stream.push(item);
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
await unrollBuffer$1(item, stream);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
484
|
-
// ticks
|
|
485
|
-
unrollBufferSync$1(buffer, stream);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
function unrollBufferSync$1(buffer, stream) {
|
|
489
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
490
|
-
let item = buffer[i];
|
|
491
|
-
if (shared.isString(item)) {
|
|
492
|
-
stream.push(item);
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
// since this is a sync buffer, child buffers are never promises
|
|
496
|
-
unrollBufferSync$1(item, stream);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
function renderToSimpleStream(input, context, stream) {
|
|
501
|
-
if (isVNode$1(input)) {
|
|
502
|
-
// raw vnode, wrap with app (for context)
|
|
503
|
-
return renderToSimpleStream(vue.createApp({ render: () => input }), context, stream);
|
|
504
|
-
}
|
|
505
|
-
// rendering an app
|
|
506
|
-
const vnode = vue.createVNode(input._component, input._props);
|
|
507
|
-
vnode.appContext = input._context;
|
|
508
|
-
// provide the ssr context to the tree
|
|
509
|
-
input.provide(vue.ssrContextKey, context);
|
|
510
|
-
Promise.resolve(renderComponentVNode(vnode))
|
|
511
|
-
.then(buffer => unrollBuffer$1(buffer, stream))
|
|
512
|
-
.then(() => resolveTeleports(context))
|
|
513
|
-
.then(() => stream.push(null))
|
|
514
|
-
.catch(error => {
|
|
515
|
-
stream.destroy(error);
|
|
516
|
-
});
|
|
517
|
-
return stream;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* @deprecated
|
|
521
|
-
*/
|
|
522
|
-
function renderToStream(input, context = {}) {
|
|
523
|
-
console.warn(`[@vue/server-renderer] renderToStream is deprecated - use renderToNodeStream instead.`);
|
|
524
|
-
return renderToNodeStream(input, context);
|
|
525
|
-
}
|
|
526
|
-
function renderToNodeStream(input, context = {}) {
|
|
527
|
-
const stream = new (require('stream').Readable)({ read() { } })
|
|
528
|
-
;
|
|
529
|
-
if (!stream) {
|
|
530
|
-
throw new Error(`ESM build of renderToStream() does not support renderToNodeStream(). ` +
|
|
531
|
-
`Use pipeToNodeWritable() with an existing Node.js Writable stream ` +
|
|
532
|
-
`instance instead.`);
|
|
533
|
-
}
|
|
534
|
-
return renderToSimpleStream(input, context, stream);
|
|
535
|
-
}
|
|
536
|
-
function pipeToNodeWritable(input, context = {}, writable) {
|
|
537
|
-
renderToSimpleStream(input, context, {
|
|
538
|
-
push(content) {
|
|
539
|
-
if (content != null) {
|
|
540
|
-
writable.write(content);
|
|
541
|
-
}
|
|
542
|
-
else {
|
|
543
|
-
writable.end();
|
|
544
|
-
}
|
|
545
|
-
},
|
|
546
|
-
destroy(err) {
|
|
547
|
-
writable.destroy(err);
|
|
548
|
-
}
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
function renderToWebStream(input, context = {}) {
|
|
552
|
-
if (typeof ReadableStream !== 'function') {
|
|
553
|
-
throw new Error(`ReadableStream constructor is not available in the global scope. ` +
|
|
554
|
-
`If the target environment does support web streams, consider using ` +
|
|
555
|
-
`pipeToWebWritable() with an existing WritableStream instance instead.`);
|
|
556
|
-
}
|
|
557
|
-
const encoder = new TextEncoder();
|
|
558
|
-
let cancelled = false;
|
|
559
|
-
return new ReadableStream({
|
|
560
|
-
start(controller) {
|
|
561
|
-
renderToSimpleStream(input, context, {
|
|
562
|
-
push(content) {
|
|
563
|
-
if (cancelled)
|
|
564
|
-
return;
|
|
565
|
-
if (content != null) {
|
|
566
|
-
controller.enqueue(encoder.encode(content));
|
|
567
|
-
}
|
|
568
|
-
else {
|
|
569
|
-
controller.close();
|
|
570
|
-
}
|
|
571
|
-
},
|
|
572
|
-
destroy(err) {
|
|
573
|
-
controller.error(err);
|
|
574
|
-
}
|
|
575
|
-
});
|
|
576
|
-
},
|
|
577
|
-
cancel() {
|
|
578
|
-
cancelled = true;
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
function pipeToWebWritable(input, context = {}, writable) {
|
|
583
|
-
const writer = writable.getWriter();
|
|
584
|
-
const encoder = new TextEncoder();
|
|
585
|
-
// #4287 CloudFlare workers do not implement `ready` property
|
|
586
|
-
let hasReady = false;
|
|
587
|
-
try {
|
|
588
|
-
hasReady = shared.isPromise(writer.ready);
|
|
589
|
-
}
|
|
590
|
-
catch (e) { }
|
|
591
|
-
renderToSimpleStream(input, context, {
|
|
592
|
-
async push(content) {
|
|
593
|
-
if (hasReady) {
|
|
594
|
-
await writer.ready;
|
|
595
|
-
}
|
|
596
|
-
if (content != null) {
|
|
597
|
-
return writer.write(encoder.encode(content));
|
|
598
|
-
}
|
|
599
|
-
else {
|
|
600
|
-
return writer.close();
|
|
601
|
-
}
|
|
602
|
-
},
|
|
603
|
-
destroy(err) {
|
|
604
|
-
// TODO better error handling?
|
|
605
|
-
console.log(err);
|
|
606
|
-
writer.close();
|
|
607
|
-
}
|
|
608
|
-
});
|
|
466
|
+
const { isVNode: isVNode$1 } = vue.ssrUtils;
|
|
467
|
+
async function unrollBuffer$1(buffer, stream) {
|
|
468
|
+
if (buffer.hasAsync) {
|
|
469
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
470
|
+
let item = buffer[i];
|
|
471
|
+
if (shared.isPromise(item)) {
|
|
472
|
+
item = await item;
|
|
473
|
+
}
|
|
474
|
+
if (shared.isString(item)) {
|
|
475
|
+
stream.push(item);
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
await unrollBuffer$1(item, stream);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
// sync buffer can be more efficiently unrolled without unnecessary await
|
|
484
|
+
// ticks
|
|
485
|
+
unrollBufferSync$1(buffer, stream);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function unrollBufferSync$1(buffer, stream) {
|
|
489
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
490
|
+
let item = buffer[i];
|
|
491
|
+
if (shared.isString(item)) {
|
|
492
|
+
stream.push(item);
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
// since this is a sync buffer, child buffers are never promises
|
|
496
|
+
unrollBufferSync$1(item, stream);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function renderToSimpleStream(input, context, stream) {
|
|
501
|
+
if (isVNode$1(input)) {
|
|
502
|
+
// raw vnode, wrap with app (for context)
|
|
503
|
+
return renderToSimpleStream(vue.createApp({ render: () => input }), context, stream);
|
|
504
|
+
}
|
|
505
|
+
// rendering an app
|
|
506
|
+
const vnode = vue.createVNode(input._component, input._props);
|
|
507
|
+
vnode.appContext = input._context;
|
|
508
|
+
// provide the ssr context to the tree
|
|
509
|
+
input.provide(vue.ssrContextKey, context);
|
|
510
|
+
Promise.resolve(renderComponentVNode(vnode))
|
|
511
|
+
.then(buffer => unrollBuffer$1(buffer, stream))
|
|
512
|
+
.then(() => resolveTeleports(context))
|
|
513
|
+
.then(() => stream.push(null))
|
|
514
|
+
.catch(error => {
|
|
515
|
+
stream.destroy(error);
|
|
516
|
+
});
|
|
517
|
+
return stream;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* @deprecated
|
|
521
|
+
*/
|
|
522
|
+
function renderToStream(input, context = {}) {
|
|
523
|
+
console.warn(`[@vue/server-renderer] renderToStream is deprecated - use renderToNodeStream instead.`);
|
|
524
|
+
return renderToNodeStream(input, context);
|
|
525
|
+
}
|
|
526
|
+
function renderToNodeStream(input, context = {}) {
|
|
527
|
+
const stream = new (require('stream').Readable)({ read() { } })
|
|
528
|
+
;
|
|
529
|
+
if (!stream) {
|
|
530
|
+
throw new Error(`ESM build of renderToStream() does not support renderToNodeStream(). ` +
|
|
531
|
+
`Use pipeToNodeWritable() with an existing Node.js Writable stream ` +
|
|
532
|
+
`instance instead.`);
|
|
533
|
+
}
|
|
534
|
+
return renderToSimpleStream(input, context, stream);
|
|
535
|
+
}
|
|
536
|
+
function pipeToNodeWritable(input, context = {}, writable) {
|
|
537
|
+
renderToSimpleStream(input, context, {
|
|
538
|
+
push(content) {
|
|
539
|
+
if (content != null) {
|
|
540
|
+
writable.write(content);
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
writable.end();
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
destroy(err) {
|
|
547
|
+
writable.destroy(err);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
function renderToWebStream(input, context = {}) {
|
|
552
|
+
if (typeof ReadableStream !== 'function') {
|
|
553
|
+
throw new Error(`ReadableStream constructor is not available in the global scope. ` +
|
|
554
|
+
`If the target environment does support web streams, consider using ` +
|
|
555
|
+
`pipeToWebWritable() with an existing WritableStream instance instead.`);
|
|
556
|
+
}
|
|
557
|
+
const encoder = new TextEncoder();
|
|
558
|
+
let cancelled = false;
|
|
559
|
+
return new ReadableStream({
|
|
560
|
+
start(controller) {
|
|
561
|
+
renderToSimpleStream(input, context, {
|
|
562
|
+
push(content) {
|
|
563
|
+
if (cancelled)
|
|
564
|
+
return;
|
|
565
|
+
if (content != null) {
|
|
566
|
+
controller.enqueue(encoder.encode(content));
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
controller.close();
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
destroy(err) {
|
|
573
|
+
controller.error(err);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
},
|
|
577
|
+
cancel() {
|
|
578
|
+
cancelled = true;
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
function pipeToWebWritable(input, context = {}, writable) {
|
|
583
|
+
const writer = writable.getWriter();
|
|
584
|
+
const encoder = new TextEncoder();
|
|
585
|
+
// #4287 CloudFlare workers do not implement `ready` property
|
|
586
|
+
let hasReady = false;
|
|
587
|
+
try {
|
|
588
|
+
hasReady = shared.isPromise(writer.ready);
|
|
589
|
+
}
|
|
590
|
+
catch (e) { }
|
|
591
|
+
renderToSimpleStream(input, context, {
|
|
592
|
+
async push(content) {
|
|
593
|
+
if (hasReady) {
|
|
594
|
+
await writer.ready;
|
|
595
|
+
}
|
|
596
|
+
if (content != null) {
|
|
597
|
+
return writer.write(encoder.encode(content));
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
return writer.close();
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
destroy(err) {
|
|
604
|
+
// TODO better error handling?
|
|
605
|
+
console.log(err);
|
|
606
|
+
writer.close();
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
609
|
}
|
|
610
610
|
|
|
611
|
-
function ssrRenderComponent(comp, props = null, children = null, parentComponent = null, slotScopeId) {
|
|
612
|
-
return renderComponentVNode(vue.createVNode(comp, props, children), parentComponent, slotScopeId);
|
|
611
|
+
function ssrRenderComponent(comp, props = null, children = null, parentComponent = null, slotScopeId) {
|
|
612
|
+
return renderComponentVNode(vue.createVNode(comp, props, children), parentComponent, slotScopeId);
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
-
function ssrRenderSlot(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId) {
|
|
616
|
-
// template-compiled slots are always rendered as fragments
|
|
617
|
-
push(`<!--[-->`);
|
|
618
|
-
ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId);
|
|
619
|
-
push(`<!--]-->`);
|
|
620
|
-
}
|
|
621
|
-
function ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId, transition) {
|
|
622
|
-
const slotFn = slots[slotName];
|
|
623
|
-
if (slotFn) {
|
|
624
|
-
const slotBuffer = [];
|
|
625
|
-
const bufferedPush = (item) => {
|
|
626
|
-
slotBuffer.push(item);
|
|
627
|
-
};
|
|
628
|
-
const ret = slotFn(slotProps, bufferedPush, parentComponent, slotScopeId ? ' ' + slotScopeId : '');
|
|
629
|
-
if (shared.isArray(ret)) {
|
|
630
|
-
// normal slot
|
|
631
|
-
renderVNodeChildren(push, ret, parentComponent, slotScopeId);
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
// ssr slot.
|
|
635
|
-
// check if the slot renders all comments, in which case use the fallback
|
|
636
|
-
let isEmptySlot = true;
|
|
637
|
-
if (transition) {
|
|
638
|
-
isEmptySlot = false;
|
|
639
|
-
}
|
|
640
|
-
else {
|
|
641
|
-
for (let i = 0; i < slotBuffer.length; i++) {
|
|
642
|
-
if (!isComment(slotBuffer[i])) {
|
|
643
|
-
isEmptySlot = false;
|
|
644
|
-
break;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (isEmptySlot) {
|
|
649
|
-
if (fallbackRenderFn) {
|
|
650
|
-
fallbackRenderFn();
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
else {
|
|
654
|
-
for (let i = 0; i < slotBuffer.length; i++) {
|
|
655
|
-
push(slotBuffer[i]);
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
else if (fallbackRenderFn) {
|
|
661
|
-
fallbackRenderFn();
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
const commentTestRE = /^<!--.*-->$/s;
|
|
665
|
-
const commentRE = /<!--[^]*?-->/gm;
|
|
666
|
-
function isComment(item) {
|
|
667
|
-
if (typeof item !== 'string' || !commentTestRE.test(item))
|
|
668
|
-
return false;
|
|
669
|
-
// if item is '<!---->' or '<!--[-->' or '<!--]-->', return true directly
|
|
670
|
-
if (item.length <= 8)
|
|
671
|
-
return true;
|
|
672
|
-
return !item.replace(commentRE, '').trim();
|
|
615
|
+
function ssrRenderSlot(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId) {
|
|
616
|
+
// template-compiled slots are always rendered as fragments
|
|
617
|
+
push(`<!--[-->`);
|
|
618
|
+
ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId);
|
|
619
|
+
push(`<!--]-->`);
|
|
620
|
+
}
|
|
621
|
+
function ssrRenderSlotInner(slots, slotName, slotProps, fallbackRenderFn, push, parentComponent, slotScopeId, transition) {
|
|
622
|
+
const slotFn = slots[slotName];
|
|
623
|
+
if (slotFn) {
|
|
624
|
+
const slotBuffer = [];
|
|
625
|
+
const bufferedPush = (item) => {
|
|
626
|
+
slotBuffer.push(item);
|
|
627
|
+
};
|
|
628
|
+
const ret = slotFn(slotProps, bufferedPush, parentComponent, slotScopeId ? ' ' + slotScopeId : '');
|
|
629
|
+
if (shared.isArray(ret)) {
|
|
630
|
+
// normal slot
|
|
631
|
+
renderVNodeChildren(push, ret, parentComponent, slotScopeId);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
// ssr slot.
|
|
635
|
+
// check if the slot renders all comments, in which case use the fallback
|
|
636
|
+
let isEmptySlot = true;
|
|
637
|
+
if (transition) {
|
|
638
|
+
isEmptySlot = false;
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
for (let i = 0; i < slotBuffer.length; i++) {
|
|
642
|
+
if (!isComment(slotBuffer[i])) {
|
|
643
|
+
isEmptySlot = false;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (isEmptySlot) {
|
|
649
|
+
if (fallbackRenderFn) {
|
|
650
|
+
fallbackRenderFn();
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
for (let i = 0; i < slotBuffer.length; i++) {
|
|
655
|
+
push(slotBuffer[i]);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
else if (fallbackRenderFn) {
|
|
661
|
+
fallbackRenderFn();
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const commentTestRE = /^<!--.*-->$/s;
|
|
665
|
+
const commentRE = /<!--[^]*?-->/gm;
|
|
666
|
+
function isComment(item) {
|
|
667
|
+
if (typeof item !== 'string' || !commentTestRE.test(item))
|
|
668
|
+
return false;
|
|
669
|
+
// if item is '<!---->' or '<!--[-->' or '<!--]-->', return true directly
|
|
670
|
+
if (item.length <= 8)
|
|
671
|
+
return true;
|
|
672
|
+
return !item.replace(commentRE, '').trim();
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
-
function ssrInterpolate(value) {
|
|
676
|
-
return shared.escapeHtml(shared.toDisplayString(value));
|
|
675
|
+
function ssrInterpolate(value) {
|
|
676
|
+
return shared.escapeHtml(shared.toDisplayString(value));
|
|
677
677
|
}
|
|
678
678
|
|
|
679
|
-
function toRaw(observed) {
|
|
680
|
-
const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
|
|
681
|
-
return raw ? toRaw(raw) : observed;
|
|
679
|
+
function toRaw(observed) {
|
|
680
|
+
const raw = observed && observed["__v_raw" /* ReactiveFlags.RAW */];
|
|
681
|
+
return raw ? toRaw(raw) : observed;
|
|
682
682
|
}
|
|
683
683
|
|
|
684
|
-
function isRef(r) {
|
|
685
|
-
return !!(r && r.__v_isRef === true);
|
|
684
|
+
function isRef(r) {
|
|
685
|
+
return !!(r && r.__v_isRef === true);
|
|
686
686
|
}
|
|
687
687
|
|
|
688
|
-
const stack = [];
|
|
689
|
-
function pushWarningContext(vnode) {
|
|
690
|
-
stack.push(vnode);
|
|
691
|
-
}
|
|
692
|
-
function popWarningContext() {
|
|
693
|
-
stack.pop();
|
|
694
|
-
}
|
|
695
|
-
function warn(msg, ...args) {
|
|
696
|
-
const instance = stack.length ? stack[stack.length - 1].component : null;
|
|
697
|
-
const appWarnHandler = instance && instance.appContext.config.warnHandler;
|
|
698
|
-
const trace = getComponentTrace();
|
|
699
|
-
if (appWarnHandler) {
|
|
700
|
-
callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
|
|
701
|
-
msg + args.join(''),
|
|
702
|
-
instance && instance.proxy,
|
|
703
|
-
trace
|
|
704
|
-
.map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
|
|
705
|
-
.join('\n'),
|
|
706
|
-
trace
|
|
707
|
-
]);
|
|
708
|
-
}
|
|
709
|
-
else {
|
|
710
|
-
const warnArgs = [`[Vue warn]: ${msg}`, ...args];
|
|
711
|
-
/* istanbul ignore if */
|
|
712
|
-
if (trace.length &&
|
|
713
|
-
// avoid spamming console during tests
|
|
714
|
-
!false) {
|
|
715
|
-
warnArgs.push(`\n`, ...formatTrace(trace));
|
|
716
|
-
}
|
|
717
|
-
console.warn(...warnArgs);
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
function getComponentTrace() {
|
|
721
|
-
let currentVNode = stack[stack.length - 1];
|
|
722
|
-
if (!currentVNode) {
|
|
723
|
-
return [];
|
|
724
|
-
}
|
|
725
|
-
// we can't just use the stack because it will be incomplete during updates
|
|
726
|
-
// that did not start from the root. Re-construct the parent chain using
|
|
727
|
-
// instance parent pointers.
|
|
728
|
-
const normalizedStack = [];
|
|
729
|
-
while (currentVNode) {
|
|
730
|
-
const last = normalizedStack[0];
|
|
731
|
-
if (last && last.vnode === currentVNode) {
|
|
732
|
-
last.recurseCount++;
|
|
733
|
-
}
|
|
734
|
-
else {
|
|
735
|
-
normalizedStack.push({
|
|
736
|
-
vnode: currentVNode,
|
|
737
|
-
recurseCount: 0
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
|
-
const parentInstance = currentVNode.component && currentVNode.component.parent;
|
|
741
|
-
currentVNode = parentInstance && parentInstance.vnode;
|
|
742
|
-
}
|
|
743
|
-
return normalizedStack;
|
|
744
|
-
}
|
|
745
|
-
/* istanbul ignore next */
|
|
746
|
-
function formatTrace(trace) {
|
|
747
|
-
const logs = [];
|
|
748
|
-
trace.forEach((entry, i) => {
|
|
749
|
-
logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
|
|
750
|
-
});
|
|
751
|
-
return logs;
|
|
752
|
-
}
|
|
753
|
-
function formatTraceEntry({ vnode, recurseCount }) {
|
|
754
|
-
const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
|
|
755
|
-
const isRoot = vnode.component ? vnode.component.parent == null : false;
|
|
756
|
-
const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
|
|
757
|
-
const close = `>` + postfix;
|
|
758
|
-
return vnode.props
|
|
759
|
-
? [open, ...formatProps(vnode.props), close]
|
|
760
|
-
: [open + close];
|
|
761
|
-
}
|
|
762
|
-
/* istanbul ignore next */
|
|
763
|
-
function formatProps(props) {
|
|
764
|
-
const res = [];
|
|
765
|
-
const keys = Object.keys(props);
|
|
766
|
-
keys.slice(0, 3).forEach(key => {
|
|
767
|
-
res.push(...formatProp(key, props[key]));
|
|
768
|
-
});
|
|
769
|
-
if (keys.length > 3) {
|
|
770
|
-
res.push(` ...`);
|
|
771
|
-
}
|
|
772
|
-
return res;
|
|
773
|
-
}
|
|
774
|
-
/* istanbul ignore next */
|
|
775
|
-
function formatProp(key, value, raw) {
|
|
776
|
-
if (shared.isString(value)) {
|
|
777
|
-
value = JSON.stringify(value);
|
|
778
|
-
return raw ? value : [`${key}=${value}`];
|
|
779
|
-
}
|
|
780
|
-
else if (typeof value === 'number' ||
|
|
781
|
-
typeof value === 'boolean' ||
|
|
782
|
-
value == null) {
|
|
783
|
-
return raw ? value : [`${key}=${value}`];
|
|
784
|
-
}
|
|
785
|
-
else if (isRef(value)) {
|
|
786
|
-
value = formatProp(key, toRaw(value.value), true);
|
|
787
|
-
return raw ? value : [`${key}=Ref<`, value, `>`];
|
|
788
|
-
}
|
|
789
|
-
else if (shared.isFunction(value)) {
|
|
790
|
-
return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
|
|
791
|
-
}
|
|
792
|
-
else {
|
|
793
|
-
value = toRaw(value);
|
|
794
|
-
return raw ? value : [`${key}=`, value];
|
|
795
|
-
}
|
|
688
|
+
const stack = [];
|
|
689
|
+
function pushWarningContext(vnode) {
|
|
690
|
+
stack.push(vnode);
|
|
691
|
+
}
|
|
692
|
+
function popWarningContext() {
|
|
693
|
+
stack.pop();
|
|
694
|
+
}
|
|
695
|
+
function warn(msg, ...args) {
|
|
696
|
+
const instance = stack.length ? stack[stack.length - 1].component : null;
|
|
697
|
+
const appWarnHandler = instance && instance.appContext.config.warnHandler;
|
|
698
|
+
const trace = getComponentTrace();
|
|
699
|
+
if (appWarnHandler) {
|
|
700
|
+
callWithErrorHandling(appWarnHandler, instance, 11 /* ErrorCodes.APP_WARN_HANDLER */, [
|
|
701
|
+
msg + args.join(''),
|
|
702
|
+
instance && instance.proxy,
|
|
703
|
+
trace
|
|
704
|
+
.map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
|
|
705
|
+
.join('\n'),
|
|
706
|
+
trace
|
|
707
|
+
]);
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
const warnArgs = [`[Vue warn]: ${msg}`, ...args];
|
|
711
|
+
/* istanbul ignore if */
|
|
712
|
+
if (trace.length &&
|
|
713
|
+
// avoid spamming console during tests
|
|
714
|
+
!false) {
|
|
715
|
+
warnArgs.push(`\n`, ...formatTrace(trace));
|
|
716
|
+
}
|
|
717
|
+
console.warn(...warnArgs);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function getComponentTrace() {
|
|
721
|
+
let currentVNode = stack[stack.length - 1];
|
|
722
|
+
if (!currentVNode) {
|
|
723
|
+
return [];
|
|
724
|
+
}
|
|
725
|
+
// we can't just use the stack because it will be incomplete during updates
|
|
726
|
+
// that did not start from the root. Re-construct the parent chain using
|
|
727
|
+
// instance parent pointers.
|
|
728
|
+
const normalizedStack = [];
|
|
729
|
+
while (currentVNode) {
|
|
730
|
+
const last = normalizedStack[0];
|
|
731
|
+
if (last && last.vnode === currentVNode) {
|
|
732
|
+
last.recurseCount++;
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
normalizedStack.push({
|
|
736
|
+
vnode: currentVNode,
|
|
737
|
+
recurseCount: 0
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
const parentInstance = currentVNode.component && currentVNode.component.parent;
|
|
741
|
+
currentVNode = parentInstance && parentInstance.vnode;
|
|
742
|
+
}
|
|
743
|
+
return normalizedStack;
|
|
744
|
+
}
|
|
745
|
+
/* istanbul ignore next */
|
|
746
|
+
function formatTrace(trace) {
|
|
747
|
+
const logs = [];
|
|
748
|
+
trace.forEach((entry, i) => {
|
|
749
|
+
logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
|
|
750
|
+
});
|
|
751
|
+
return logs;
|
|
752
|
+
}
|
|
753
|
+
function formatTraceEntry({ vnode, recurseCount }) {
|
|
754
|
+
const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
|
|
755
|
+
const isRoot = vnode.component ? vnode.component.parent == null : false;
|
|
756
|
+
const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
|
|
757
|
+
const close = `>` + postfix;
|
|
758
|
+
return vnode.props
|
|
759
|
+
? [open, ...formatProps(vnode.props), close]
|
|
760
|
+
: [open + close];
|
|
761
|
+
}
|
|
762
|
+
/* istanbul ignore next */
|
|
763
|
+
function formatProps(props) {
|
|
764
|
+
const res = [];
|
|
765
|
+
const keys = Object.keys(props);
|
|
766
|
+
keys.slice(0, 3).forEach(key => {
|
|
767
|
+
res.push(...formatProp(key, props[key]));
|
|
768
|
+
});
|
|
769
|
+
if (keys.length > 3) {
|
|
770
|
+
res.push(` ...`);
|
|
771
|
+
}
|
|
772
|
+
return res;
|
|
773
|
+
}
|
|
774
|
+
/* istanbul ignore next */
|
|
775
|
+
function formatProp(key, value, raw) {
|
|
776
|
+
if (shared.isString(value)) {
|
|
777
|
+
value = JSON.stringify(value);
|
|
778
|
+
return raw ? value : [`${key}=${value}`];
|
|
779
|
+
}
|
|
780
|
+
else if (typeof value === 'number' ||
|
|
781
|
+
typeof value === 'boolean' ||
|
|
782
|
+
value == null) {
|
|
783
|
+
return raw ? value : [`${key}=${value}`];
|
|
784
|
+
}
|
|
785
|
+
else if (isRef(value)) {
|
|
786
|
+
value = formatProp(key, toRaw(value.value), true);
|
|
787
|
+
return raw ? value : [`${key}=Ref<`, value, `>`];
|
|
788
|
+
}
|
|
789
|
+
else if (shared.isFunction(value)) {
|
|
790
|
+
return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
value = toRaw(value);
|
|
794
|
+
return raw ? value : [`${key}=`, value];
|
|
795
|
+
}
|
|
796
796
|
}
|
|
797
797
|
|
|
798
|
-
const ErrorTypeStrings = {
|
|
799
|
-
["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook',
|
|
800
|
-
["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook',
|
|
801
|
-
["c" /* LifecycleHooks.CREATED */]: 'created hook',
|
|
802
|
-
["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook',
|
|
803
|
-
["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook',
|
|
804
|
-
["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook',
|
|
805
|
-
["u" /* LifecycleHooks.UPDATED */]: 'updated',
|
|
806
|
-
["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook',
|
|
807
|
-
["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook',
|
|
808
|
-
["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook',
|
|
809
|
-
["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook',
|
|
810
|
-
["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook',
|
|
811
|
-
["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook',
|
|
812
|
-
["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
|
|
813
|
-
[0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
|
|
814
|
-
[1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
|
|
815
|
-
[2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
|
|
816
|
-
[3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
|
|
817
|
-
[4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
|
|
818
|
-
[5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
|
|
819
|
-
[6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
|
|
820
|
-
[7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
|
|
821
|
-
[8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
|
|
822
|
-
[9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
|
|
823
|
-
[10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
|
|
824
|
-
[11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
|
|
825
|
-
[12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
|
|
826
|
-
[13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
|
|
827
|
-
[14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
|
|
828
|
-
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
|
|
829
|
-
};
|
|
830
|
-
function callWithErrorHandling(fn, instance, type, args) {
|
|
831
|
-
let res;
|
|
832
|
-
try {
|
|
833
|
-
res = args ? fn(...args) : fn();
|
|
834
|
-
}
|
|
835
|
-
catch (err) {
|
|
836
|
-
handleError(err, instance, type);
|
|
837
|
-
}
|
|
838
|
-
return res;
|
|
839
|
-
}
|
|
840
|
-
function handleError(err, instance, type, throwInDev = true) {
|
|
841
|
-
const contextVNode = instance ? instance.vnode : null;
|
|
842
|
-
if (instance) {
|
|
843
|
-
let cur = instance.parent;
|
|
844
|
-
// the exposed instance is the render proxy to keep it consistent with 2.x
|
|
845
|
-
const exposedInstance = instance.proxy;
|
|
846
|
-
// in production the hook receives only the error code
|
|
847
|
-
const errorInfo = ErrorTypeStrings[type] ;
|
|
848
|
-
while (cur) {
|
|
849
|
-
const errorCapturedHooks = cur.ec;
|
|
850
|
-
if (errorCapturedHooks) {
|
|
851
|
-
for (let i = 0; i < errorCapturedHooks.length; i++) {
|
|
852
|
-
if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
cur = cur.parent;
|
|
858
|
-
}
|
|
859
|
-
// app-level handling
|
|
860
|
-
const appErrorHandler = instance.appContext.config.errorHandler;
|
|
861
|
-
if (appErrorHandler) {
|
|
862
|
-
callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
|
|
863
|
-
return;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
logError(err, type, contextVNode, throwInDev);
|
|
867
|
-
}
|
|
868
|
-
function logError(err, type, contextVNode, throwInDev = true) {
|
|
869
|
-
{
|
|
870
|
-
const info = ErrorTypeStrings[type];
|
|
871
|
-
if (contextVNode) {
|
|
872
|
-
pushWarningContext(contextVNode);
|
|
873
|
-
}
|
|
874
|
-
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
|
|
875
|
-
if (contextVNode) {
|
|
876
|
-
popWarningContext();
|
|
877
|
-
}
|
|
878
|
-
// crash in dev by default so it's more noticeable
|
|
879
|
-
if (throwInDev) {
|
|
880
|
-
throw err;
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
console.error(err);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
798
|
+
const ErrorTypeStrings = {
|
|
799
|
+
["sp" /* LifecycleHooks.SERVER_PREFETCH */]: 'serverPrefetch hook',
|
|
800
|
+
["bc" /* LifecycleHooks.BEFORE_CREATE */]: 'beforeCreate hook',
|
|
801
|
+
["c" /* LifecycleHooks.CREATED */]: 'created hook',
|
|
802
|
+
["bm" /* LifecycleHooks.BEFORE_MOUNT */]: 'beforeMount hook',
|
|
803
|
+
["m" /* LifecycleHooks.MOUNTED */]: 'mounted hook',
|
|
804
|
+
["bu" /* LifecycleHooks.BEFORE_UPDATE */]: 'beforeUpdate hook',
|
|
805
|
+
["u" /* LifecycleHooks.UPDATED */]: 'updated',
|
|
806
|
+
["bum" /* LifecycleHooks.BEFORE_UNMOUNT */]: 'beforeUnmount hook',
|
|
807
|
+
["um" /* LifecycleHooks.UNMOUNTED */]: 'unmounted hook',
|
|
808
|
+
["a" /* LifecycleHooks.ACTIVATED */]: 'activated hook',
|
|
809
|
+
["da" /* LifecycleHooks.DEACTIVATED */]: 'deactivated hook',
|
|
810
|
+
["ec" /* LifecycleHooks.ERROR_CAPTURED */]: 'errorCaptured hook',
|
|
811
|
+
["rtc" /* LifecycleHooks.RENDER_TRACKED */]: 'renderTracked hook',
|
|
812
|
+
["rtg" /* LifecycleHooks.RENDER_TRIGGERED */]: 'renderTriggered hook',
|
|
813
|
+
[0 /* ErrorCodes.SETUP_FUNCTION */]: 'setup function',
|
|
814
|
+
[1 /* ErrorCodes.RENDER_FUNCTION */]: 'render function',
|
|
815
|
+
[2 /* ErrorCodes.WATCH_GETTER */]: 'watcher getter',
|
|
816
|
+
[3 /* ErrorCodes.WATCH_CALLBACK */]: 'watcher callback',
|
|
817
|
+
[4 /* ErrorCodes.WATCH_CLEANUP */]: 'watcher cleanup function',
|
|
818
|
+
[5 /* ErrorCodes.NATIVE_EVENT_HANDLER */]: 'native event handler',
|
|
819
|
+
[6 /* ErrorCodes.COMPONENT_EVENT_HANDLER */]: 'component event handler',
|
|
820
|
+
[7 /* ErrorCodes.VNODE_HOOK */]: 'vnode hook',
|
|
821
|
+
[8 /* ErrorCodes.DIRECTIVE_HOOK */]: 'directive hook',
|
|
822
|
+
[9 /* ErrorCodes.TRANSITION_HOOK */]: 'transition hook',
|
|
823
|
+
[10 /* ErrorCodes.APP_ERROR_HANDLER */]: 'app errorHandler',
|
|
824
|
+
[11 /* ErrorCodes.APP_WARN_HANDLER */]: 'app warnHandler',
|
|
825
|
+
[12 /* ErrorCodes.FUNCTION_REF */]: 'ref function',
|
|
826
|
+
[13 /* ErrorCodes.ASYNC_COMPONENT_LOADER */]: 'async component loader',
|
|
827
|
+
[14 /* ErrorCodes.SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
|
|
828
|
+
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core'
|
|
829
|
+
};
|
|
830
|
+
function callWithErrorHandling(fn, instance, type, args) {
|
|
831
|
+
let res;
|
|
832
|
+
try {
|
|
833
|
+
res = args ? fn(...args) : fn();
|
|
834
|
+
}
|
|
835
|
+
catch (err) {
|
|
836
|
+
handleError(err, instance, type);
|
|
837
|
+
}
|
|
838
|
+
return res;
|
|
839
|
+
}
|
|
840
|
+
function handleError(err, instance, type, throwInDev = true) {
|
|
841
|
+
const contextVNode = instance ? instance.vnode : null;
|
|
842
|
+
if (instance) {
|
|
843
|
+
let cur = instance.parent;
|
|
844
|
+
// the exposed instance is the render proxy to keep it consistent with 2.x
|
|
845
|
+
const exposedInstance = instance.proxy;
|
|
846
|
+
// in production the hook receives only the error code
|
|
847
|
+
const errorInfo = ErrorTypeStrings[type] ;
|
|
848
|
+
while (cur) {
|
|
849
|
+
const errorCapturedHooks = cur.ec;
|
|
850
|
+
if (errorCapturedHooks) {
|
|
851
|
+
for (let i = 0; i < errorCapturedHooks.length; i++) {
|
|
852
|
+
if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
cur = cur.parent;
|
|
858
|
+
}
|
|
859
|
+
// app-level handling
|
|
860
|
+
const appErrorHandler = instance.appContext.config.errorHandler;
|
|
861
|
+
if (appErrorHandler) {
|
|
862
|
+
callWithErrorHandling(appErrorHandler, null, 10 /* ErrorCodes.APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
logError(err, type, contextVNode, throwInDev);
|
|
867
|
+
}
|
|
868
|
+
function logError(err, type, contextVNode, throwInDev = true) {
|
|
869
|
+
{
|
|
870
|
+
const info = ErrorTypeStrings[type];
|
|
871
|
+
if (contextVNode) {
|
|
872
|
+
pushWarningContext(contextVNode);
|
|
873
|
+
}
|
|
874
|
+
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
|
|
875
|
+
if (contextVNode) {
|
|
876
|
+
popWarningContext();
|
|
877
|
+
}
|
|
878
|
+
// crash in dev by default so it's more noticeable
|
|
879
|
+
if (throwInDev) {
|
|
880
|
+
throw err;
|
|
881
|
+
}
|
|
882
|
+
else {
|
|
883
|
+
console.error(err);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
886
|
}
|
|
887
887
|
|
|
888
|
-
const classifyRE = /(?:^|[-_])(\w)/g;
|
|
889
|
-
const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
|
|
890
|
-
function getComponentName(Component, includeInferred = true) {
|
|
891
|
-
return shared.isFunction(Component)
|
|
892
|
-
? Component.displayName || Component.name
|
|
893
|
-
: Component.name || (includeInferred && Component.__name);
|
|
894
|
-
}
|
|
895
|
-
/* istanbul ignore next */
|
|
896
|
-
function formatComponentName(instance, Component, isRoot = false) {
|
|
897
|
-
let name = getComponentName(Component);
|
|
898
|
-
if (!name && Component.__file) {
|
|
899
|
-
const match = Component.__file.match(/([^/\\]+)\.\w+$/);
|
|
900
|
-
if (match) {
|
|
901
|
-
name = match[1];
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (!name && instance && instance.parent) {
|
|
905
|
-
// try to infer the name based on reverse resolution
|
|
906
|
-
const inferFromRegistry = (registry) => {
|
|
907
|
-
for (const key in registry) {
|
|
908
|
-
if (registry[key] === Component) {
|
|
909
|
-
return key;
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
name =
|
|
914
|
-
inferFromRegistry(instance.components ||
|
|
915
|
-
instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
|
|
916
|
-
}
|
|
917
|
-
return name ? classify(name) : isRoot ? `App` : `Anonymous`;
|
|
888
|
+
const classifyRE = /(?:^|[-_])(\w)/g;
|
|
889
|
+
const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
|
|
890
|
+
function getComponentName(Component, includeInferred = true) {
|
|
891
|
+
return shared.isFunction(Component)
|
|
892
|
+
? Component.displayName || Component.name
|
|
893
|
+
: Component.name || (includeInferred && Component.__name);
|
|
894
|
+
}
|
|
895
|
+
/* istanbul ignore next */
|
|
896
|
+
function formatComponentName(instance, Component, isRoot = false) {
|
|
897
|
+
let name = getComponentName(Component);
|
|
898
|
+
if (!name && Component.__file) {
|
|
899
|
+
const match = Component.__file.match(/([^/\\]+)\.\w+$/);
|
|
900
|
+
if (match) {
|
|
901
|
+
name = match[1];
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (!name && instance && instance.parent) {
|
|
905
|
+
// try to infer the name based on reverse resolution
|
|
906
|
+
const inferFromRegistry = (registry) => {
|
|
907
|
+
for (const key in registry) {
|
|
908
|
+
if (registry[key] === Component) {
|
|
909
|
+
return key;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
name =
|
|
914
|
+
inferFromRegistry(instance.components ||
|
|
915
|
+
instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
|
|
916
|
+
}
|
|
917
|
+
return name ? classify(name) : isRoot ? `App` : `Anonymous`;
|
|
918
918
|
}
|
|
919
919
|
|
|
920
|
-
function ssrRenderList(source, renderItem) {
|
|
921
|
-
if (shared.isArray(source) || shared.isString(source)) {
|
|
922
|
-
for (let i = 0, l = source.length; i < l; i++) {
|
|
923
|
-
renderItem(source[i], i);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
else if (typeof source === 'number') {
|
|
927
|
-
if (!Number.isInteger(source)) {
|
|
928
|
-
warn(`The v-for range expect an integer value but got ${source}.`);
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
for (let i = 0; i < source; i++) {
|
|
932
|
-
renderItem(i + 1, i);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
else if (shared.isObject(source)) {
|
|
936
|
-
if (source[Symbol.iterator]) {
|
|
937
|
-
const arr = Array.from(source);
|
|
938
|
-
for (let i = 0, l = arr.length; i < l; i++) {
|
|
939
|
-
renderItem(arr[i], i);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
else {
|
|
943
|
-
const keys = Object.keys(source);
|
|
944
|
-
for (let i = 0, l = keys.length; i < l; i++) {
|
|
945
|
-
const key = keys[i];
|
|
946
|
-
renderItem(source[key], key, i);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
920
|
+
function ssrRenderList(source, renderItem) {
|
|
921
|
+
if (shared.isArray(source) || shared.isString(source)) {
|
|
922
|
+
for (let i = 0, l = source.length; i < l; i++) {
|
|
923
|
+
renderItem(source[i], i);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else if (typeof source === 'number') {
|
|
927
|
+
if (!Number.isInteger(source)) {
|
|
928
|
+
warn(`The v-for range expect an integer value but got ${source}.`);
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
for (let i = 0; i < source; i++) {
|
|
932
|
+
renderItem(i + 1, i);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
else if (shared.isObject(source)) {
|
|
936
|
+
if (source[Symbol.iterator]) {
|
|
937
|
+
const arr = Array.from(source);
|
|
938
|
+
for (let i = 0, l = arr.length; i < l; i++) {
|
|
939
|
+
renderItem(arr[i], i);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
const keys = Object.keys(source);
|
|
944
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
945
|
+
const key = keys[i];
|
|
946
|
+
renderItem(source[key], key, i);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
950
|
}
|
|
951
951
|
|
|
952
|
-
async function ssrRenderSuspense(push, { default: renderContent }) {
|
|
953
|
-
if (renderContent) {
|
|
954
|
-
renderContent();
|
|
955
|
-
}
|
|
956
|
-
else {
|
|
957
|
-
push(`<!---->`);
|
|
958
|
-
}
|
|
952
|
+
async function ssrRenderSuspense(push, { default: renderContent }) {
|
|
953
|
+
if (renderContent) {
|
|
954
|
+
renderContent();
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
push(`<!---->`);
|
|
958
|
+
}
|
|
959
959
|
}
|
|
960
960
|
|
|
961
|
-
function ssrGetDirectiveProps(instance, dir, value, arg, modifiers = {}) {
|
|
962
|
-
if (typeof dir !== 'function' && dir.getSSRProps) {
|
|
963
|
-
return (dir.getSSRProps({
|
|
964
|
-
dir,
|
|
965
|
-
instance,
|
|
966
|
-
value,
|
|
967
|
-
oldValue: undefined,
|
|
968
|
-
arg,
|
|
969
|
-
modifiers
|
|
970
|
-
}, null) || {});
|
|
971
|
-
}
|
|
972
|
-
return {};
|
|
961
|
+
function ssrGetDirectiveProps(instance, dir, value, arg, modifiers = {}) {
|
|
962
|
+
if (typeof dir !== 'function' && dir.getSSRProps) {
|
|
963
|
+
return (dir.getSSRProps({
|
|
964
|
+
dir,
|
|
965
|
+
instance,
|
|
966
|
+
value,
|
|
967
|
+
oldValue: undefined,
|
|
968
|
+
arg,
|
|
969
|
+
modifiers
|
|
970
|
+
}, null) || {});
|
|
971
|
+
}
|
|
972
|
+
return {};
|
|
973
973
|
}
|
|
974
974
|
|
|
975
|
-
const ssrLooseEqual = shared.looseEqual;
|
|
976
|
-
function ssrLooseContain(arr, value) {
|
|
977
|
-
return shared.looseIndexOf(arr, value) > -1;
|
|
978
|
-
}
|
|
979
|
-
// for <input :type="type" v-model="model" value="value">
|
|
980
|
-
function ssrRenderDynamicModel(type, model, value) {
|
|
981
|
-
switch (type) {
|
|
982
|
-
case 'radio':
|
|
983
|
-
return shared.looseEqual(model, value) ? ' checked' : '';
|
|
984
|
-
case 'checkbox':
|
|
985
|
-
return (shared.isArray(model) ? ssrLooseContain(model, value) : model)
|
|
986
|
-
? ' checked'
|
|
987
|
-
: '';
|
|
988
|
-
default:
|
|
989
|
-
// text types
|
|
990
|
-
return ssrRenderAttr('value', model);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
// for <input v-bind="obj" v-model="model">
|
|
994
|
-
function ssrGetDynamicModelProps(existingProps = {}, model) {
|
|
995
|
-
const { type, value } = existingProps;
|
|
996
|
-
switch (type) {
|
|
997
|
-
case 'radio':
|
|
998
|
-
return shared.looseEqual(model, value) ? { checked: true } : null;
|
|
999
|
-
case 'checkbox':
|
|
1000
|
-
return (shared.isArray(model) ? ssrLooseContain(model, value) : model)
|
|
1001
|
-
? { checked: true }
|
|
1002
|
-
: null;
|
|
1003
|
-
default:
|
|
1004
|
-
// text types
|
|
1005
|
-
return { value: model };
|
|
1006
|
-
}
|
|
975
|
+
const ssrLooseEqual = shared.looseEqual;
|
|
976
|
+
function ssrLooseContain(arr, value) {
|
|
977
|
+
return shared.looseIndexOf(arr, value) > -1;
|
|
978
|
+
}
|
|
979
|
+
// for <input :type="type" v-model="model" value="value">
|
|
980
|
+
function ssrRenderDynamicModel(type, model, value) {
|
|
981
|
+
switch (type) {
|
|
982
|
+
case 'radio':
|
|
983
|
+
return shared.looseEqual(model, value) ? ' checked' : '';
|
|
984
|
+
case 'checkbox':
|
|
985
|
+
return (shared.isArray(model) ? ssrLooseContain(model, value) : model)
|
|
986
|
+
? ' checked'
|
|
987
|
+
: '';
|
|
988
|
+
default:
|
|
989
|
+
// text types
|
|
990
|
+
return ssrRenderAttr('value', model);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
// for <input v-bind="obj" v-model="model">
|
|
994
|
+
function ssrGetDynamicModelProps(existingProps = {}, model) {
|
|
995
|
+
const { type, value } = existingProps;
|
|
996
|
+
switch (type) {
|
|
997
|
+
case 'radio':
|
|
998
|
+
return shared.looseEqual(model, value) ? { checked: true } : null;
|
|
999
|
+
case 'checkbox':
|
|
1000
|
+
return (shared.isArray(model) ? ssrLooseContain(model, value) : model)
|
|
1001
|
+
? { checked: true }
|
|
1002
|
+
: null;
|
|
1003
|
+
default:
|
|
1004
|
+
// text types
|
|
1005
|
+
return { value: model };
|
|
1006
|
+
}
|
|
1007
1007
|
}
|
|
1008
1008
|
|
|
1009
1009
|
vue.initDirectivesForSSR();
|