vike 0.4.156 → 0.4.158
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/cjs/node/plugin/plugins/commonConfig.js +21 -2
- package/dist/cjs/node/plugin/plugins/distFileNames.js +3 -3
- package/dist/cjs/node/plugin/plugins/importBuild/index.js +1 -1
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -1
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +2 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +2 -0
- package/dist/cjs/node/plugin/shared/loggerNotProd/errorWithCodeSnippet/fixture-errors/errMdx.js +1 -1
- package/dist/cjs/node/prerender/runPrerender.js +2 -0
- package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +2 -2
- package/dist/cjs/node/runtime/html/injectAssets/inferHtmlTags.js +1 -1
- package/dist/cjs/node/runtime/html/serializePageContextClientSide.js +2 -2
- package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +8 -1
- package/dist/cjs/node/runtime/renderPage/isNewError.js +3 -1
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -3
- package/dist/cjs/node/runtime/renderPage.js +8 -10
- package/dist/cjs/node/shared/extractAssetsQuery.js +7 -6
- package/dist/cjs/shared/addUrlComputedProps.js +22 -2
- package/dist/cjs/shared/hooks/executeHook.js +1 -1
- package/dist/cjs/shared/misc/isServerSideError.js +4 -0
- package/dist/cjs/shared/route/abort.js +19 -8
- package/dist/cjs/shared/route/index.js +3 -1
- package/dist/cjs/shared/route/resolveRedirects.js +2 -3
- package/dist/cjs/utils/assert.js +1 -1
- package/dist/cjs/utils/debug.js +2 -1
- package/dist/cjs/utils/parseUrl-extras.js +1 -6
- package/dist/cjs/utils/parseUrl.js +6 -1
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.d.ts +12 -11
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +16 -32
- package/dist/esm/client/client-routing-runtime/prefetch.js +1 -1
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +65 -60
- package/dist/esm/client/shared/loadUserFilesClientSide.js +3 -1
- package/dist/esm/node/plugin/plugins/commonConfig.js +21 -2
- package/dist/esm/node/plugin/plugins/distFileNames.js +3 -3
- package/dist/esm/node/plugin/plugins/importBuild/index.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +2 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +2 -0
- package/dist/esm/node/plugin/shared/loggerNotProd/errorWithCodeSnippet/fixture-errors/errMdx.js +1 -1
- package/dist/esm/node/prerender/runPrerender.js +2 -0
- package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +2 -2
- package/dist/esm/node/runtime/html/injectAssets/inferHtmlTags.js +1 -1
- package/dist/esm/node/runtime/html/serializePageContextClientSide.js +2 -2
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.d.ts +1 -0
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +8 -1
- package/dist/esm/node/runtime/renderPage/isNewError.js +3 -1
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -3
- package/dist/esm/node/runtime/renderPage.js +8 -10
- package/dist/esm/node/shared/extractAssetsQuery.js +7 -6
- package/dist/esm/shared/addUrlComputedProps.js +22 -2
- package/dist/esm/shared/hooks/executeHook.js +1 -1
- package/dist/esm/shared/misc/isServerSideError.d.ts +1 -0
- package/dist/esm/shared/misc/isServerSideError.js +1 -0
- package/dist/esm/shared/page-configs/Config.d.ts +2 -2
- package/dist/esm/shared/route/abort.d.ts +6 -1
- package/dist/esm/shared/route/abort.js +20 -9
- package/dist/esm/shared/route/index.js +3 -1
- package/dist/esm/shared/route/resolveRedirects.js +1 -2
- package/dist/esm/utils/assert.js +1 -1
- package/dist/esm/utils/debug.js +2 -1
- package/dist/esm/utils/parseUrl-extras.d.ts +0 -2
- package/dist/esm/utils/parseUrl-extras.js +0 -5
- package/dist/esm/utils/parseUrl.d.ts +2 -0
- package/dist/esm/utils/parseUrl.js +5 -0
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +2 -2
- package/dist/cjs/shared/misc/isRenderFailure.js +0 -4
- package/dist/esm/shared/misc/isRenderFailure.d.ts +0 -1
- package/dist/esm/shared/misc/isRenderFailure.js +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export { getPageContextFromHooks_isHydration };
|
|
2
2
|
export { getPageContextFromHooks_isNotHydration };
|
|
3
3
|
export { getPageContextFromHooks_serialized };
|
|
4
|
-
export { isServerSideRouted };
|
|
5
4
|
import { assert, assertUsage, hasProp, objectAssign, getProjectError, serverSideRouteTo, executeHook, isObject, getGlobalObject } from './utils.js';
|
|
6
5
|
import { parse } from '@brillout/json-serializer/parse';
|
|
7
6
|
import { getPageContextSerializedInHtml } from '../shared/getPageContextSerializedInHtml.js';
|
|
@@ -15,7 +14,7 @@ import { assertOnBeforeRenderHookReturn } from '../../shared/assertOnBeforeRende
|
|
|
15
14
|
import { executeGuardHook } from '../../shared/route/executeGuardHook.js';
|
|
16
15
|
import { AbortRender, isAbortPageContext } from '../../shared/route/abort.js';
|
|
17
16
|
import { pageContextInitIsPassedToClient } from '../../shared/misc/pageContextInitIsPassedToClient.js';
|
|
18
|
-
import {
|
|
17
|
+
import { isServerSideError } from '../../shared/misc/isServerSideError.js';
|
|
19
18
|
const globalObject = getGlobalObject('router/getPageContext.ts', {});
|
|
20
19
|
function getPageContextFromHooks_serialized() {
|
|
21
20
|
const pageContextSerialized = getPageContextSerializedInHtml();
|
|
@@ -54,23 +53,15 @@ async function getPageContextFromHooks_isNotHydration(pageContext, isErrorPage)
|
|
|
54
53
|
!isErrorPage &&
|
|
55
54
|
// true if pageContextInit has some client data or at least one of the data() and onBeforeRender() hooks is server-side only:
|
|
56
55
|
(await hasPageContextServer({ ...pageContext, ...pageContextFromHooks }))) {
|
|
57
|
-
const
|
|
56
|
+
const res = await fetchPageContextFromServer(pageContext);
|
|
57
|
+
if ('is404ServerSideRouted' in res)
|
|
58
|
+
return { is404ServerSideRouted: true };
|
|
59
|
+
const { pageContextFromServer } = res;
|
|
58
60
|
hasPageContextFromServer = true;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// When the user hasn't define a `_error.page.js` file: the mechanism with `serverSideError: true` is used instead
|
|
64
|
-
assert(!('serverSideError' in pageContextFromServer));
|
|
65
|
-
assert(hasProp(pageContextFromServer, 'is404', 'boolean'));
|
|
66
|
-
assert(hasProp(pageContextFromServer, 'pageProps', 'object'));
|
|
67
|
-
assert(hasProp(pageContextFromServer.pageProps, 'is404', 'boolean'));
|
|
68
|
-
objectAssign(pageContextFromServer, {
|
|
69
|
-
_hasPageContextFromServer: true,
|
|
70
|
-
_hasPageContextFromClient: false
|
|
71
|
-
});
|
|
72
|
-
return pageContextFromServer;
|
|
73
|
-
}
|
|
61
|
+
// Already handled
|
|
62
|
+
assert(!(isServerSideError in pageContextFromServer));
|
|
63
|
+
assert(!('serverSideError' in pageContextFromServer));
|
|
64
|
+
objectAssign(pageContextFromHooks, pageContextFromServer);
|
|
74
65
|
}
|
|
75
66
|
// At this point, we need to call the client-side guard(), data() and onBeforeRender() hooks, if they exist on client
|
|
76
67
|
// env. However if we have fetched pageContext from the server, some of them might have run already on the
|
|
@@ -107,7 +98,7 @@ async function getPageContextFromHooks_isNotHydration(pageContext, isErrorPage)
|
|
|
107
98
|
objectAssign(pageContextFromHooks, {
|
|
108
99
|
_hasPageContextFromServer: hasPageContextFromServer
|
|
109
100
|
});
|
|
110
|
-
return pageContextFromHooks;
|
|
101
|
+
return { pageContextFromHooks };
|
|
111
102
|
}
|
|
112
103
|
async function executeHookClientSide(hookName, pageContext) {
|
|
113
104
|
const hook = getHook(pageContext, hookName);
|
|
@@ -217,32 +208,25 @@ async function fetchPageContextFromServer(pageContext) {
|
|
|
217
208
|
// Static hosts + page doesn't exist
|
|
218
209
|
if (!isCorrect && response.status === 404) {
|
|
219
210
|
serverSideRouteTo(pageContext.urlOriginal);
|
|
220
|
-
|
|
211
|
+
return { is404ServerSideRouted: true };
|
|
221
212
|
}
|
|
222
213
|
assertUsage(isCorrect, `Wrong Content-Type for ${pageContextUrl}: it should be ${contentTypeCorrect} but it's ${contentType} instead. Make sure to properly use pageContext.httpResponse.headers, see https://vike.dev/renderPage`);
|
|
223
214
|
}
|
|
224
215
|
const responseText = await response.text();
|
|
225
216
|
const pageContextFromServer = parse(responseText);
|
|
226
217
|
assert(isObject(pageContextFromServer));
|
|
227
|
-
if ('serverSideError' in pageContextFromServer) {
|
|
228
|
-
throw getProjectError(`The pageContext object couldn't be fetched from the server as an error occurred on the server-side. Check your server logs.`);
|
|
229
|
-
}
|
|
230
218
|
if (isAbortPageContext(pageContextFromServer)) {
|
|
231
219
|
throw AbortRender(pageContextFromServer);
|
|
232
220
|
}
|
|
221
|
+
// Is there a reason for having two different properties? Can't we use only one property? I guess/think the isServerSideError property was an attempt (a bad idea really) for rendering the error page even though an error occured on the server-side (which is a bad idea because the added complexity is non-negligible while the added value is minuscule since the error page usually doesn't have any (meaningful / server-side) hooks).
|
|
222
|
+
if ('serverSideError' in pageContextFromServer || isServerSideError in pageContextFromServer) {
|
|
223
|
+
throw getProjectError(`The pageContext object couldn't be fetched from the server as an error occurred on the server-side. Check your server logs.`);
|
|
224
|
+
}
|
|
233
225
|
assert(hasProp(pageContextFromServer, '_pageId', 'string'));
|
|
234
226
|
processPageContextFromServer(pageContextFromServer);
|
|
235
|
-
return pageContextFromServer;
|
|
227
|
+
return { pageContextFromServer };
|
|
236
228
|
}
|
|
237
229
|
function processPageContextFromServer(pageContextFromServer) {
|
|
238
230
|
setPageContextInitIsPassedToClient(pageContextFromServer);
|
|
239
231
|
removeBuiltInOverrides(pageContextFromServer);
|
|
240
232
|
}
|
|
241
|
-
function isServerSideRouted(err) {
|
|
242
|
-
return isObject(err) && !!err._alreadyServerSideRouted;
|
|
243
|
-
}
|
|
244
|
-
function ServerSideRouted() {
|
|
245
|
-
const err = new Error("Page doesn't exist");
|
|
246
|
-
Object.assign(err, { _alreadyServerSideRouted: true });
|
|
247
|
-
return err;
|
|
248
|
-
}
|
|
@@ -11,7 +11,7 @@ import { createPageContext } from './createPageContext.js';
|
|
|
11
11
|
import { route } from '../../shared/route/index.js';
|
|
12
12
|
import { noRouteMatch } from '../../shared/route/noRouteMatch.js';
|
|
13
13
|
assertClientRouting();
|
|
14
|
-
const globalObject = getGlobalObject('prefetch.ts', { linkPrefetchHandlerAdded: new
|
|
14
|
+
const globalObject = getGlobalObject('prefetch.ts', { linkPrefetchHandlerAdded: new WeakMap() });
|
|
15
15
|
async function prefetchAssets(pageId, pageContext) {
|
|
16
16
|
try {
|
|
17
17
|
await loadUserFilesClientSide(pageId, pageContext._pageFilesAll, pageContext._pageConfigs);
|
|
@@ -2,7 +2,7 @@ export { renderPageClientSide };
|
|
|
2
2
|
export { getRenderCount };
|
|
3
3
|
export { disableClientRouting };
|
|
4
4
|
import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, serverSideRouteTo, getGlobalObject, executeHook, hasProp } from './utils.js';
|
|
5
|
-
import { getPageContextFromHooks_isHydration, getPageContextFromHooks_isNotHydration, getPageContextFromHooks_serialized
|
|
5
|
+
import { getPageContextFromHooks_isHydration, getPageContextFromHooks_isNotHydration, getPageContextFromHooks_serialized } from './getPageContextFromHooks.js';
|
|
6
6
|
import { createPageContext } from './createPageContext.js';
|
|
7
7
|
import { addLinkPrefetchHandlers } from './prefetch.js';
|
|
8
8
|
import { assertInfo, assertWarning, isReact } from './utils.js';
|
|
@@ -17,7 +17,6 @@ import { setScrollPosition } from './setScrollPosition.js';
|
|
|
17
17
|
import { updateState } from './onBrowserHistoryNavigation.js';
|
|
18
18
|
import { browserNativeScrollRestoration_disable, setInitialRenderIsDone } from './scrollRestoration.js';
|
|
19
19
|
import { getErrorPageId } from '../../shared/error-page.js';
|
|
20
|
-
import { isRenderFailure } from '../../shared/misc/isRenderFailure.js';
|
|
21
20
|
const globalObject = getGlobalObject('renderPageClientSide.ts', { renderCounter: 0 });
|
|
22
21
|
async function renderPageClientSide(renderArgs) {
|
|
23
22
|
const { scrollTarget, urlOriginal = getCurrentUrl(), overwriteLastHistoryEntry = false, isBackwardNavigation, pageContextsFromRewrite = [], redirectCount = 0, isUserLandPushStateNavigation, isClientSideNavigation = true } = renderArgs;
|
|
@@ -32,6 +31,9 @@ async function renderPageClientSide(renderArgs) {
|
|
|
32
31
|
await renderPageNominal();
|
|
33
32
|
return;
|
|
34
33
|
async function renderPageNominal() {
|
|
34
|
+
const onError = async (err) => {
|
|
35
|
+
await renderErrorPage({ err });
|
|
36
|
+
};
|
|
35
37
|
const pageContext = await getPageContextBegin();
|
|
36
38
|
if (isRenderOutdated())
|
|
37
39
|
return;
|
|
@@ -47,7 +49,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
47
49
|
pageContextFromRoute = await route(pageContext);
|
|
48
50
|
}
|
|
49
51
|
catch (err) {
|
|
50
|
-
await
|
|
52
|
+
await onError(err);
|
|
51
53
|
return;
|
|
52
54
|
}
|
|
53
55
|
if (isRenderOutdated())
|
|
@@ -85,7 +87,9 @@ async function renderPageClientSide(renderArgs) {
|
|
|
85
87
|
return;
|
|
86
88
|
}
|
|
87
89
|
else {
|
|
88
|
-
|
|
90
|
+
// A user file has a syntax error
|
|
91
|
+
await onError(err);
|
|
92
|
+
return;
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
if (isRenderOutdated())
|
|
@@ -113,7 +117,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
113
117
|
await executeHook(() => hookFn(pageContext), hook);
|
|
114
118
|
}
|
|
115
119
|
catch (err) {
|
|
116
|
-
await
|
|
120
|
+
await onError(err);
|
|
117
121
|
return;
|
|
118
122
|
}
|
|
119
123
|
if (isRenderOutdated())
|
|
@@ -129,7 +133,7 @@ async function renderPageClientSide(renderArgs) {
|
|
|
129
133
|
pageContextFromHooks = await getPageContextFromHooks_isHydration(pageContext);
|
|
130
134
|
}
|
|
131
135
|
catch (err) {
|
|
132
|
-
await
|
|
136
|
+
await onError(err);
|
|
133
137
|
return;
|
|
134
138
|
}
|
|
135
139
|
if (isRenderOutdated())
|
|
@@ -140,20 +144,19 @@ async function renderPageClientSide(renderArgs) {
|
|
|
140
144
|
await renderPageView(pageContext);
|
|
141
145
|
}
|
|
142
146
|
else {
|
|
143
|
-
let
|
|
147
|
+
let res;
|
|
144
148
|
try {
|
|
145
|
-
|
|
149
|
+
res = await getPageContextFromHooks_isNotHydration(pageContext, false);
|
|
146
150
|
}
|
|
147
151
|
catch (err) {
|
|
148
|
-
await
|
|
152
|
+
await onError(err);
|
|
149
153
|
return;
|
|
150
154
|
}
|
|
151
155
|
if (isRenderOutdated())
|
|
152
156
|
return;
|
|
153
|
-
if (
|
|
154
|
-
await renderErrorPage({ pageContextError: pageContextFromHooks });
|
|
157
|
+
if ('is404ServerSideRouted' in res)
|
|
155
158
|
return;
|
|
156
|
-
|
|
159
|
+
const pageContextFromHooks = res.pageContextFromHooks;
|
|
157
160
|
assert(!('urlOriginal' in pageContextFromHooks));
|
|
158
161
|
objectAssign(pageContext, pageContextFromHooks);
|
|
159
162
|
// Render page view
|
|
@@ -174,19 +177,19 @@ async function renderPageClientSide(renderArgs) {
|
|
|
174
177
|
return pageContext;
|
|
175
178
|
}
|
|
176
179
|
async function renderErrorPage(args) {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
const onError = (err) => {
|
|
181
|
+
if (!isSameErrorMessage(err, args.err)) {
|
|
182
|
+
/* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
|
|
183
|
+
- We risk running into an infinite loop of reloads which would overload the server.
|
|
184
|
+
- An infinite reloading page is a even worse UX than a blank page.
|
|
185
|
+
serverSideRouteTo(urlOriginal)
|
|
186
|
+
*/
|
|
187
|
+
console.error(err);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
183
190
|
if ('err' in args) {
|
|
184
191
|
const { err } = args;
|
|
185
192
|
assert(err);
|
|
186
|
-
assert(!('errorWhileRendering' in pageContext));
|
|
187
|
-
pageContext.errorWhileRendering = err;
|
|
188
|
-
if (shouldSwallowAndInterrupt(err))
|
|
189
|
-
return;
|
|
190
193
|
if (!isAbortError(err)) {
|
|
191
194
|
// We don't swallow 404 errors:
|
|
192
195
|
// - On the server-side, Vike swallows / doesn't show any 404 error log because it's expected that a user may go to some random non-existent URL. (We don't want to flood the app's error tracking with 404 logs.)
|
|
@@ -197,6 +200,17 @@ async function renderPageClientSide(renderArgs) {
|
|
|
197
200
|
// We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
|
|
198
201
|
// We handle the abort error down below.
|
|
199
202
|
}
|
|
203
|
+
}
|
|
204
|
+
const pageContext = await getPageContextBegin();
|
|
205
|
+
if (isRenderOutdated())
|
|
206
|
+
return;
|
|
207
|
+
if (args.pageContextError) {
|
|
208
|
+
objectAssign(pageContext, args.pageContextError);
|
|
209
|
+
}
|
|
210
|
+
if ('err' in args) {
|
|
211
|
+
const { err } = args;
|
|
212
|
+
assert(!('errorWhileRendering' in pageContext));
|
|
213
|
+
pageContext.errorWhileRendering = err;
|
|
200
214
|
if (isAbortError(err)) {
|
|
201
215
|
const errAbort = err;
|
|
202
216
|
logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
|
|
@@ -256,38 +270,44 @@ async function renderPageClientSide(renderArgs) {
|
|
|
256
270
|
return;
|
|
257
271
|
}
|
|
258
272
|
else {
|
|
259
|
-
|
|
273
|
+
// A user file has a syntax error
|
|
274
|
+
onError(err);
|
|
275
|
+
return;
|
|
260
276
|
}
|
|
261
277
|
}
|
|
262
278
|
if (isRenderOutdated())
|
|
263
279
|
return;
|
|
264
|
-
let
|
|
280
|
+
let res;
|
|
265
281
|
try {
|
|
266
|
-
|
|
282
|
+
res = await getPageContextFromHooks_isNotHydration(pageContext, true);
|
|
267
283
|
}
|
|
268
|
-
catch (
|
|
284
|
+
catch (err) {
|
|
269
285
|
// - When user hasn't defined a `_error.page.js` file
|
|
270
286
|
// - Some Vike unpexected internal error
|
|
271
|
-
|
|
272
|
-
return;
|
|
273
|
-
if (!isSameErrorMessage(args.err, errErrorPage)) {
|
|
274
|
-
/* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
|
|
275
|
-
- We risk running into an infinite loop of reloads which would overload the server.
|
|
276
|
-
- An infinite reloading page is a even worse UX than a blank page.
|
|
277
|
-
serverSideRouteTo(urlOriginal)
|
|
278
|
-
*/
|
|
279
|
-
console.error(errErrorPage);
|
|
280
|
-
}
|
|
287
|
+
onError(err);
|
|
281
288
|
return;
|
|
282
289
|
}
|
|
283
290
|
if (isRenderOutdated())
|
|
284
291
|
return;
|
|
292
|
+
if ('is404ServerSideRouted' in res)
|
|
293
|
+
return;
|
|
294
|
+
const pageContextFromHooks = res.pageContextFromHooks;
|
|
285
295
|
assert(pageContextFromHooks);
|
|
286
296
|
assert(!('urlOriginal' in pageContextFromHooks));
|
|
287
297
|
objectAssign(pageContext, pageContextFromHooks);
|
|
288
|
-
await renderPageView(pageContext,
|
|
298
|
+
await renderPageView(pageContext, args);
|
|
289
299
|
}
|
|
290
300
|
async function renderPageView(pageContext, isErrorPage) {
|
|
301
|
+
const onError = async (err) => {
|
|
302
|
+
if (!isErrorPage) {
|
|
303
|
+
await renderErrorPage({ err });
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
if (!isSameErrorMessage(err, isErrorPage.err)) {
|
|
307
|
+
console.error(err);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
291
311
|
// We use globalObject.renderPromise in order to ensure that there is never two concurrent onRenderClient() calls
|
|
292
312
|
if (globalObject.renderPromise) {
|
|
293
313
|
// Make sure that the previous render has finished
|
|
@@ -304,12 +324,8 @@ async function renderPageClientSide(renderArgs) {
|
|
|
304
324
|
await executeOnRenderClientHook(pageContext, true);
|
|
305
325
|
}
|
|
306
326
|
catch (err) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
throw err;
|
|
312
|
-
}
|
|
327
|
+
await onError(err);
|
|
328
|
+
return;
|
|
313
329
|
}
|
|
314
330
|
addLinkPrefetchHandlers(pageContext);
|
|
315
331
|
globalObject.renderPromise = undefined;
|
|
@@ -329,12 +345,9 @@ async function renderPageClientSide(renderArgs) {
|
|
|
329
345
|
await executeHook(() => hookFn(pageContext), hook);
|
|
330
346
|
}
|
|
331
347
|
catch (err) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
else {
|
|
336
|
-
throw err;
|
|
337
|
-
}
|
|
348
|
+
await onError(err);
|
|
349
|
+
if (!isErrorPage)
|
|
350
|
+
return;
|
|
338
351
|
}
|
|
339
352
|
if (isRenderOutdated(true))
|
|
340
353
|
return;
|
|
@@ -354,12 +367,9 @@ async function renderPageClientSide(renderArgs) {
|
|
|
354
367
|
await executeHook(() => hookFn(pageContext), hook);
|
|
355
368
|
}
|
|
356
369
|
catch (err) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
else {
|
|
361
|
-
throw err;
|
|
362
|
-
}
|
|
370
|
+
await onError(err);
|
|
371
|
+
if (!isErrorPage)
|
|
372
|
+
return;
|
|
363
373
|
}
|
|
364
374
|
if (isRenderOutdated(true))
|
|
365
375
|
return;
|
|
@@ -378,11 +388,6 @@ function changeUrl(url, overwriteLastHistoryEntry) {
|
|
|
378
388
|
pushHistory(url, overwriteLastHistoryEntry);
|
|
379
389
|
updateState();
|
|
380
390
|
}
|
|
381
|
-
function shouldSwallowAndInterrupt(err) {
|
|
382
|
-
if (isServerSideRouted(err))
|
|
383
|
-
return true;
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
391
|
function handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender) {
|
|
387
392
|
if (!isErrorFetchingStaticAssets(err)) {
|
|
388
393
|
return false;
|
|
@@ -19,10 +19,12 @@ async function loadUserFilesClientSide(pageId, pageFilesAll, pageConfigs) {
|
|
|
19
19
|
pageConfigLoaded = result[0];
|
|
20
20
|
}
|
|
21
21
|
catch (err) {
|
|
22
|
-
// To trigger this catch: add `throw new Error()` in the global scope of +onRenderClient.js
|
|
23
22
|
if (isFetchError(err)) {
|
|
24
23
|
Object.assign(err, { [stamp]: true });
|
|
25
24
|
}
|
|
25
|
+
else {
|
|
26
|
+
// A user file has a syntax error
|
|
27
|
+
}
|
|
26
28
|
throw err;
|
|
27
29
|
}
|
|
28
30
|
const { config, configEntries, exports, exportsAll, pageExports } = getExports(pageFilesClientSide, pageConfigLoaded);
|
|
@@ -23,7 +23,10 @@ function commonConfig() {
|
|
|
23
23
|
configResolved: {
|
|
24
24
|
order: 'post',
|
|
25
25
|
handler(config) {
|
|
26
|
-
|
|
26
|
+
overrideViteDefaultPort(config);
|
|
27
|
+
/* TODO: do this after implementing vike.config.js and new setting transformLinkedDependencies (or probably a better name like transpileLinkedDependencies/bundleLinkedDependencies or something else)
|
|
28
|
+
overrideViteDefaultSsrExternal(config)
|
|
29
|
+
*/
|
|
27
30
|
workaroundCI(config);
|
|
28
31
|
assertRollupInput(config);
|
|
29
32
|
assertResolveAlias(config);
|
|
@@ -33,7 +36,7 @@ function commonConfig() {
|
|
|
33
36
|
}
|
|
34
37
|
];
|
|
35
38
|
}
|
|
36
|
-
function
|
|
39
|
+
function overrideViteDefaultPort(config) {
|
|
37
40
|
var _a, _b;
|
|
38
41
|
// @ts-ignore
|
|
39
42
|
config.server ?? (config.server = {});
|
|
@@ -42,6 +45,22 @@ function setDefaultPort(config) {
|
|
|
42
45
|
config.preview ?? (config.preview = {});
|
|
43
46
|
(_b = config.preview).port ?? (_b.port = 3000);
|
|
44
47
|
}
|
|
48
|
+
/*
|
|
49
|
+
function overrideViteDefaultSsrExternal(config: ResolvedConfig) {
|
|
50
|
+
if (!isViteVersionWithSsrExternalTrue()) return
|
|
51
|
+
// @ts-ignore Not released yet: https://github.com/vitejs/vite/pull/10939/files#diff-5a3d42620df2c6b17e25f440ffdb67683dee7ef57317674d19f41d5f30502310L5
|
|
52
|
+
config.ssr.external ??= true
|
|
53
|
+
}
|
|
54
|
+
import { version } from 'vite'
|
|
55
|
+
function isViteVersionWithSsrExternalTrue(): boolean {
|
|
56
|
+
const versionParts = version.split('.').map((s) => parseInt(s, 10)) as [number, number, number]
|
|
57
|
+
assert(versionParts.length === 3)
|
|
58
|
+
if (versionParts[0] > 5) return true
|
|
59
|
+
if (versionParts[1] > 0) return true
|
|
60
|
+
if (versionParts[2] >= 12) return true
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
*/
|
|
45
64
|
// Workaround GitHub Action failing to access the server
|
|
46
65
|
function workaroundCI(config) {
|
|
47
66
|
var _a, _b;
|
|
@@ -13,13 +13,13 @@ function distFileNames() {
|
|
|
13
13
|
const rollupOutputs = getRollupOutputs(config);
|
|
14
14
|
// We need to support multiple outputs: @vite/plugin-legacy adds an ouput, see https://github.com/vikejs/vike/issues/477#issuecomment-1406434802
|
|
15
15
|
rollupOutputs.forEach((rollupOutput) => {
|
|
16
|
-
if (!rollupOutput
|
|
16
|
+
if (!('entryFileNames' in rollupOutput)) {
|
|
17
17
|
rollupOutput.entryFileNames = (chunkInfo) => getEntryFileName(chunkInfo, config, true);
|
|
18
18
|
}
|
|
19
|
-
if (!rollupOutput
|
|
19
|
+
if (!('chunkFileNames' in rollupOutput)) {
|
|
20
20
|
rollupOutput.chunkFileNames = (chunkInfo) => getChunkFileName(chunkInfo, config);
|
|
21
21
|
}
|
|
22
|
-
if (!rollupOutput
|
|
22
|
+
if (!('assertUsage' in rollupOutput)) {
|
|
23
23
|
rollupOutput.assetFileNames = (chunkInfo) => getAssetFileName(chunkInfo, config);
|
|
24
24
|
}
|
|
25
25
|
});
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js
CHANGED
|
@@ -139,6 +139,8 @@ async function isGitMissing(userRootDir) {
|
|
|
139
139
|
}
|
|
140
140
|
async function runCmd(cmd, cwd) {
|
|
141
141
|
const res = await execA(cmd, { cwd });
|
|
142
|
-
|
|
142
|
+
/* Not always true: https://github.com/vikejs/vike/issues/1440#issuecomment-1892831303
|
|
143
|
+
assert(res.stderr === '')
|
|
144
|
+
*/
|
|
143
145
|
return res.stdout.toString().split('\n').filter(Boolean);
|
|
144
146
|
}
|
|
@@ -836,6 +836,7 @@ function getConfigName(filePath) {
|
|
|
836
836
|
}
|
|
837
837
|
else {
|
|
838
838
|
const configName = basename.slice(1);
|
|
839
|
+
assertUsage(configName !== '', `${filePath} Invalid filename ${fileName}`);
|
|
839
840
|
return configName;
|
|
840
841
|
}
|
|
841
842
|
}
|
|
@@ -1028,6 +1029,7 @@ function resolveImportPath(importData, importerFilePath) {
|
|
|
1028
1029
|
const importerFilePathAbsolute = importerFilePath.filePathAbsoluteFilesystem;
|
|
1029
1030
|
assertPosixPath(importerFilePathAbsolute);
|
|
1030
1031
|
const cwd = path.posix.dirname(importerFilePathAbsolute);
|
|
1032
|
+
// We can't use import.meta.resolve() as of Junary 2023 (and probably for a lot longer): https://stackoverflow.com/questions/54977743/do-require-resolve-for-es-modules#comment137174954_62272600:~:text=But%20the%20argument%20parent%20(aka%20cwd)%20still%20requires%20a%20flag
|
|
1031
1033
|
// filePathAbsoluteFilesystem is expected to be null when importData.importPath is a Vite path alias
|
|
1032
1034
|
const filePathAbsoluteFilesystem = requireResolve(importData.importPath, cwd);
|
|
1033
1035
|
return filePathAbsoluteFilesystem;
|
|
@@ -49,6 +49,8 @@ function getCodePageConfigsSerialized(pageConfigs, isForClientSide, isClientRout
|
|
|
49
49
|
assert(configValueSource);
|
|
50
50
|
if (!configValueSource.configEnv.eager)
|
|
51
51
|
return;
|
|
52
|
+
if (!isRuntimeEnvMatch(configValueSource.configEnv, { isForClientSide, isClientRouting, isEager: true }))
|
|
53
|
+
return;
|
|
52
54
|
lines.push(...serializeConfigValueImported(configValueSource, configName, whitespace, varCounterContainer, importStatements));
|
|
53
55
|
});
|
|
54
56
|
lines.push(`${whitespace}],`);
|
package/dist/esm/node/plugin/shared/loggerNotProd/errorWithCodeSnippet/fixture-errors/errMdx.js
CHANGED
|
@@ -12,7 +12,7 @@ export const errMdx = {
|
|
|
12
12
|
ruleId: 'unexpected-closing-slash',
|
|
13
13
|
plugin: '@mdx-js/rollup',
|
|
14
14
|
id: '/home/rom/code/vike/docs/pages/dynamic-import.page.server.mdx',
|
|
15
|
-
pluginCode: 'import { Link, Note } from \'@brillout/docpress\'\n\nPage moved to <Link href="/
|
|
15
|
+
pluginCode: 'import { Link, Note } from \'@brillout/docpress\'\n\nPage moved to <Link href="/ClientOnly" />.\n\n </Note>\n\n\nexport const headings = [];\n',
|
|
16
16
|
loc: {
|
|
17
17
|
file: '/home/rom/code/vike/docs/pages/dynamic-import.page.server.mdx',
|
|
18
18
|
start: { line: 5, column: 5, offset: 109, _index: 6, _bufferIndex: 4 },
|
|
@@ -29,6 +29,8 @@ import { getVikeConfig } from '../plugin/plugins/importUserCode/v1-design/getVik
|
|
|
29
29
|
import { logHintForCjsEsmError } from '../runtime/renderPage/logHintForCjsEsmError.js';
|
|
30
30
|
async function runPrerenderFromAPI(options = {}) {
|
|
31
31
|
await runPrerender(options, 'prerender()');
|
|
32
|
+
// - We purposely propagate the error to the user land, so that the error interrupts the user land. It's also, I guess, a nice-to-have that the user has control over the error.
|
|
33
|
+
// - We don't use logHintForCjsEsmError() because we don't have control over what happens with the error. For example, if the user land purposely swallows the error then the hint shouldn't be logged. Also, it's best if the hint is shown to the user *after* the error, but we cannot do/guarentee that.
|
|
32
34
|
}
|
|
33
35
|
async function runPrerenderFromCLI(options) {
|
|
34
36
|
try {
|
|
@@ -85,12 +85,12 @@ async function getHtmlTags(pageContext, injectToStream, injectFilter) {
|
|
|
85
85
|
// See https://github.com/vikejs/vike/pull/1271
|
|
86
86
|
const positionJavaScriptEntry = (() => {
|
|
87
87
|
if (pageContext._pageContextPromise) {
|
|
88
|
-
assertWarning(!injectToStream, "[getHtmlTags()] We recommend against using streaming and a pageContext promise at the same time as
|
|
88
|
+
assertWarning(!injectToStream, "[getHtmlTags()] We recommend against using streaming and a pageContext promise at the same time as progressive hydration won't work", { onlyOnce: true });
|
|
89
89
|
// If there is a pageContext._pageContextPromise (which is resolved after the stream has ended) then the pageContext JSON data needs to await for it: https://vike.dev/stream#initial-data-after-stream-end
|
|
90
90
|
return 'HTML_END';
|
|
91
91
|
}
|
|
92
92
|
if (injectToStream) {
|
|
93
|
-
// If there is a stream then, in order to support
|
|
93
|
+
// If there is a stream then, in order to support progressive hydration, inject the JavaScript during the stream after React(/Vue/Solid/...) resolved the first suspense boundary
|
|
94
94
|
return 'STREAM';
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
@@ -3,7 +3,7 @@ export { inferPreloadTag };
|
|
|
3
3
|
export { inferEarlyHintLink };
|
|
4
4
|
export { scriptAttrs };
|
|
5
5
|
import { assert } from '../../utils.js';
|
|
6
|
-
// We can't use `defer` here. With `defer`, the entry script won't start before `</body>` has been parsed, preventing
|
|
6
|
+
// We can't use `defer` here. With `defer`, the entry script won't start before `</body>` has been parsed, preventing progressive hydration during SSR streaming, see https://github.com/vikejs/vike/pull/1271
|
|
7
7
|
const scriptAttrs = 'type="module" async';
|
|
8
8
|
function inferPreloadTag(pageAsset) {
|
|
9
9
|
const { src, assetType, mediaType } = pageAsset;
|
|
@@ -7,7 +7,7 @@ import { addIs404ToPageProps } from '../../../shared/addIs404ToPageProps.js';
|
|
|
7
7
|
import pc from '@brillout/picocolors';
|
|
8
8
|
import { notSerializable } from '../../../shared/notSerializable.js';
|
|
9
9
|
import { pageContextInitIsPassedToClient } from '../../../shared/misc/pageContextInitIsPassedToClient.js';
|
|
10
|
-
import {
|
|
10
|
+
import { isServerSideError } from '../../../shared/misc/isServerSideError.js';
|
|
11
11
|
const PASS_TO_CLIENT = [
|
|
12
12
|
'abortReason',
|
|
13
13
|
'_urlRewrite',
|
|
@@ -21,7 +21,7 @@ const PASS_TO_CLIENT = [
|
|
|
21
21
|
'_pageId',
|
|
22
22
|
'data' // for data() hook
|
|
23
23
|
];
|
|
24
|
-
const PASS_TO_CLIENT_ERROR_PAGE = ['pageProps', 'is404',
|
|
24
|
+
const PASS_TO_CLIENT_ERROR_PAGE = ['pageProps', 'is404', isServerSideError];
|
|
25
25
|
function serializePageContextClientSide(pageContext) {
|
|
26
26
|
const passToClient = getPassToClient(pageContext);
|
|
27
27
|
const pageContextClient = {};
|
|
@@ -24,6 +24,7 @@ declare function getHttpResponseBodyStreamHandlers(htmlRender: HtmlRender, rende
|
|
|
24
24
|
getBody(): Promise<string>;
|
|
25
25
|
getNodeStream(): Promise<import("stream").Readable>;
|
|
26
26
|
getWebStream(): StreamReadableWeb;
|
|
27
|
+
getReadableNodeStream(): Promise<import("stream").Readable>;
|
|
27
28
|
getReadableWebStream(): StreamReadableWeb;
|
|
28
29
|
pipeToWebWritable(writable: StreamWritableWeb): void;
|
|
29
30
|
pipeToNodeWritable(writable: StreamWritableNode): void;
|
|
@@ -20,7 +20,7 @@ function getHttpResponseBodyStreamHandlers(htmlRender, renderHook) {
|
|
|
20
20
|
},
|
|
21
21
|
// TODO/v1-release: remove
|
|
22
22
|
async getNodeStream() {
|
|
23
|
-
assertWarning(false, '`pageContext.httpResponse.getNodeStream()` is outdated, use `pageContext.httpResponse.
|
|
23
|
+
assertWarning(false, '`pageContext.httpResponse.getNodeStream()` is outdated, use `pageContext.httpResponse.getReadableNodeStream()` instead. ' +
|
|
24
24
|
streamDocs, { onlyOnce: true, showStackTrace: true });
|
|
25
25
|
const nodeStream = await getStreamReadableNode(htmlRender);
|
|
26
26
|
if (nodeStream === null) {
|
|
@@ -38,6 +38,13 @@ function getHttpResponseBodyStreamHandlers(htmlRender, renderHook) {
|
|
|
38
38
|
}
|
|
39
39
|
return webStream;
|
|
40
40
|
},
|
|
41
|
+
async getReadableNodeStream() {
|
|
42
|
+
const nodeStream = await getStreamReadableNode(htmlRender);
|
|
43
|
+
if (nodeStream === null) {
|
|
44
|
+
assertUsage(false, getErrMsg(htmlRender, renderHook, 'getReadableNodeStream()', getFixMsg('readable', 'node')));
|
|
45
|
+
}
|
|
46
|
+
return nodeStream;
|
|
47
|
+
},
|
|
41
48
|
getReadableWebStream() {
|
|
42
49
|
const webStream = getStreamReadableWeb(htmlRender);
|
|
43
50
|
if (webStream === null) {
|
|
@@ -6,7 +6,9 @@ const globalObject = getGlobalObject('runtime/renderPage/isNewError.ts', {
|
|
|
6
6
|
});
|
|
7
7
|
function isNewError(errErrorPage, errNominalPage) {
|
|
8
8
|
warnIfErrorIsNotObject(errErrorPage);
|
|
9
|
-
return !isSameErrorMessage(errNominalPage, errErrorPage) ||
|
|
9
|
+
return (!isSameErrorMessage(errNominalPage, errErrorPage) ||
|
|
10
|
+
// Isn't this redudant/superfluous? I think we can remove this entire file and only use isSameErrorMessage() instead.
|
|
11
|
+
!hasAlreadyLogged(errNominalPage));
|
|
10
12
|
}
|
|
11
13
|
function hasAlreadyLogged(err) {
|
|
12
14
|
if (!isObject(err))
|
|
@@ -21,7 +21,7 @@ import { executeGuardHook } from '../../../shared/route/executeGuardHook.js';
|
|
|
21
21
|
import { loadPageRoutes } from '../../../shared/route/loadPageRoutes.js';
|
|
22
22
|
import pc from '@brillout/picocolors';
|
|
23
23
|
import { getConfigValueFilePathToShowToUser } from '../../../shared/page-configs/helpers.js';
|
|
24
|
-
import {
|
|
24
|
+
import { isServerSideError } from '../../../shared/misc/isServerSideError.js';
|
|
25
25
|
async function renderPageAlreadyRouted(pageContext) {
|
|
26
26
|
// pageContext._pageId can either be the:
|
|
27
27
|
// - ID of the page matching the routing, or the
|
|
@@ -48,7 +48,7 @@ async function renderPageAlreadyRouted(pageContext) {
|
|
|
48
48
|
}
|
|
49
49
|
if (pageContext.isClientSideNavigation) {
|
|
50
50
|
if (isError) {
|
|
51
|
-
objectAssign(pageContext, { [
|
|
51
|
+
objectAssign(pageContext, { [isServerSideError]: true });
|
|
52
52
|
}
|
|
53
53
|
const pageContextSerialized = serializePageContextClientSide(pageContext);
|
|
54
54
|
const httpResponse = await createHttpResponsePageContextJson(pageContextSerialized);
|
|
@@ -181,5 +181,5 @@ function assertV1Design(pageFilesAll, pageConfigs) {
|
|
|
181
181
|
...pageFilesAll.map((p) => indent + p.filePath)
|
|
182
182
|
].join('\n'));
|
|
183
183
|
}
|
|
184
|
-
assertWarning(!isDesignOld,
|
|
184
|
+
assertWarning(!isDesignOld, "You are using Vike's deprecated design. Update to the new V1 design, see https://vike.dev/migration/v1-design for how to migrate.", { onlyOnce: true });
|
|
185
185
|
}
|