vike 0.4.240 → 0.4.241

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.
Files changed (74) hide show
  1. package/dist/esm/client/runtime-client-routing/getPageContextFromHooks.d.ts +1 -1
  2. package/dist/esm/client/runtime-client-routing/getPageContextFromHooks.js +1 -1
  3. package/dist/esm/client/runtime-client-routing/logErrorClient.d.ts +2 -0
  4. package/dist/esm/client/runtime-client-routing/logErrorClient.js +11 -0
  5. package/dist/esm/client/runtime-client-routing/renderPageClientSide.js +95 -84
  6. package/dist/esm/client/runtime-client-routing/utils.d.ts +0 -1
  7. package/dist/esm/client/runtime-client-routing/utils.js +0 -1
  8. package/dist/esm/node/cli/parseCli.js +10 -6
  9. package/dist/esm/node/prerender/runPrerender.js +2 -1
  10. package/dist/esm/node/runtime/globalContext.d.ts +92 -0
  11. package/dist/esm/node/runtime/globalContext.js +12 -3
  12. package/dist/esm/node/runtime/logErrorServer.d.ts +2 -0
  13. package/dist/esm/node/runtime/logErrorServer.js +11 -0
  14. package/dist/esm/node/runtime/renderPage/execHookOnError.d.ts +2 -0
  15. package/dist/esm/node/runtime/renderPage/execHookOnError.js +26 -0
  16. package/dist/esm/node/runtime/renderPage/execHookServer.d.ts +1 -1
  17. package/dist/esm/node/runtime/renderPage/loggerProd.js +3 -5
  18. package/dist/esm/node/runtime/renderPage.js +8 -7
  19. package/dist/esm/node/vite/index.js +6 -6
  20. package/dist/esm/node/vite/onLoad.js +3 -8
  21. package/dist/esm/node/vite/plugins/build/handleAssetsManifest.js +0 -1
  22. package/dist/esm/node/vite/plugins/build/pluginDistFileNames.js +2 -2
  23. package/dist/esm/node/vite/plugins/pluginCommon.js +13 -2
  24. package/dist/esm/node/vite/plugins/pluginFileEnv.js +9 -6
  25. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.d.ts +3 -0
  26. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.js +129 -0
  27. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.d.ts +10 -0
  28. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +77 -0
  29. package/dist/esm/node/vite/plugins/pluginReplaceConstantsPageContext.d.ts +3 -0
  30. package/dist/esm/node/vite/plugins/{pluginReplaceIsClientSide.js → pluginReplaceConstantsPageContext.js} +5 -3
  31. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +7 -1
  32. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -0
  33. package/dist/esm/node/vite/plugins/pluginVirtualFiles.js +2 -2
  34. package/dist/esm/node/vite/shared/getFilePath.d.ts +4 -6
  35. package/dist/esm/node/vite/shared/getFilePath.js +6 -11
  36. package/dist/esm/node/vite/shared/isViteServerSide.d.ts +6 -3
  37. package/dist/esm/node/vite/shared/isViteServerSide.js +13 -4
  38. package/dist/esm/node/vite/shared/loggerNotProd/errorWithCodeSnippet.js +2 -2
  39. package/dist/esm/node/vite/shared/loggerNotProd/log.js +8 -2
  40. package/dist/esm/node/vite/shared/loggerNotProd.d.ts +1 -1
  41. package/dist/esm/node/vite/shared/loggerNotProd.js +11 -11
  42. package/dist/esm/node/vite/shared/loggerVite.js +4 -2
  43. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +12 -2
  44. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +1 -6
  45. package/dist/esm/shared/createGlobalContextShared.d.ts +2 -1
  46. package/dist/esm/shared/createGlobalContextShared.js +1 -1
  47. package/dist/esm/shared/hooks/execHook.d.ts +1 -1
  48. package/dist/esm/shared/hooks/getHook.d.ts +5 -4
  49. package/dist/esm/shared/route/abort.d.ts +1 -0
  50. package/dist/esm/shared/route/abort.js +12 -4
  51. package/dist/esm/shared/route/index.js +13 -4
  52. package/dist/esm/shared/route/utils.d.ts +1 -0
  53. package/dist/esm/shared/route/utils.js +1 -0
  54. package/dist/esm/types/Config.d.ts +14 -3
  55. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  56. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  57. package/dist/esm/utils/assert.js +1 -0
  58. package/dist/esm/utils/assertNodeVersion.js +1 -1
  59. package/dist/esm/utils/assertViteVersion.d.ts +2 -0
  60. package/dist/esm/utils/assertViteVersion.js +11 -0
  61. package/dist/esm/utils/debug.d.ts +5 -3
  62. package/dist/esm/utils/debug.js +20 -16
  63. package/dist/esm/utils/getGlobalObject.d.ts +5 -1
  64. package/dist/esm/utils/getGlobalObject.js +5 -1
  65. package/dist/esm/utils/isVikeReactApp.js +2 -1
  66. package/dist/esm/utils/requireResolve.js +1 -1
  67. package/package.json +3 -3
  68. package/dist/esm/node/vite/plugins/pluginEnvVars.d.ts +0 -3
  69. package/dist/esm/node/vite/plugins/pluginEnvVars.js +0 -110
  70. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.d.ts +0 -9
  71. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.js +0 -45
  72. package/dist/esm/node/vite/plugins/pluginReplaceIsClientSide.d.ts +0 -3
  73. package/dist/esm/shared/route/debug.d.ts +0 -6
  74. package/dist/esm/shared/route/debug.js +0 -21
@@ -445,7 +445,7 @@ declare function getPageContextFromClientHooks(pageContext: {
445
445
  }>;
446
446
  type PageContextExecHookClient = PageContextConfig & PageContextForPublicUsageClient;
447
447
  declare function execHookClient(hookName: HookName, pageContext: PageContextExecHookClient): Promise<(import("../../shared/hooks/getHook.js").HookLoc & {
448
- hookFn: (arg: import("../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum | import("../../shared/prepareGlobalContextForPublicUsage.js").GlobalContextPrepareMinimum) => unknown;
448
+ hookFn: (arg: import("../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum) => unknown;
449
449
  hookTimeout: import("../../shared/hooks/getHook.js").HookTimeout;
450
450
  } & {
451
451
  hookReturn: unknown;
@@ -168,7 +168,7 @@ function hasServerOnlyHook(pageContext) {
168
168
  if (isOldDesign(pageContext))
169
169
  return false;
170
170
  const pageConfig = getPageConfig(pageContext.pageId, pageContext._globalContext._pageConfigs);
171
- const val = getConfigValueRuntime(pageConfig, `serverOnlyHooks`)?.value;
171
+ const val = getConfigValueRuntime(pageConfig, `hasServerOnlyHook`)?.value;
172
172
  assert(val === true || val === false);
173
173
  return val;
174
174
  }
@@ -0,0 +1,2 @@
1
+ export { logErrorClient };
2
+ declare function logErrorClient(err: unknown): void;
@@ -0,0 +1,11 @@
1
+ export { logErrorClient };
2
+ import { isObject } from './utils.js';
3
+ function logErrorClient(err) {
4
+ if (isObject(err) &&
5
+ // Set by vike-react
6
+ // https://github.com/vikejs/vike-react/blob/195a208c6b77e7f34496e1f637278a36c60fbe07/packages/vike-react/src/integration/onRenderClient.tsx#L109
7
+ err.isAlreadyLogged) {
8
+ return;
9
+ }
10
+ console.error(err);
11
+ }
@@ -3,7 +3,7 @@ export { getRenderCount };
3
3
  export { disableClientRouting };
4
4
  export { firstRenderStartPromise };
5
5
  export { getPageContextClient };
6
- import { assert, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, hasProp, updateType, genPromise, isCallable, catchInfiniteLoop, } from './utils.js';
6
+ import { assert, objectAssign, redirectHard, getGlobalObject, hasProp, updateType, genPromise, isCallable, catchInfiniteLoop, } from './utils.js';
7
7
  import { getPageContextFromClientHooks, getPageContextFromServerHooks, getPageContextFromHooks_isHydration, getPageContextFromHooks_serialized, setPageContextInitIsPassedToClient, } from './getPageContextFromHooks.js';
8
8
  import { createPageContextClientSide } from './createPageContextClientSide.js';
9
9
  import { addLinkPrefetchHandlers, addLinkPrefetchHandlers_unwatch, addLinkPrefetchHandlers_watch, getPageContextPrefetched, populatePageContextPrefetchCache, } from './prefetch.js';
@@ -24,6 +24,7 @@ import { execHookDirect, execHook } from '../../shared/hooks/execHook.js';
24
24
  import { preparePageContextForPublicUsageClient, } from './preparePageContextForPublicUsageClient.js';
25
25
  import { getHookFromPageContextNew } from '../../shared/hooks/getHook.js';
26
26
  import { preparePageContextForPublicUsageClientMinimal } from '../shared/preparePageContextForPublicUsageClientShared.js';
27
+ import { logErrorClient } from './logErrorClient.js';
27
28
  const globalObject = getGlobalObject('runtime-client-routing/renderPageClientSide.ts', (() => {
28
29
  const { promise: firstRenderStartPromise, resolve: firstRenderStartPromiseResolve } = genPromise();
29
30
  return {
@@ -60,7 +61,7 @@ async function renderPageClientSide(renderArgs) {
60
61
  return;
61
62
  async function renderPageNominal() {
62
63
  const onError = async (err) => {
63
- await renderPageOnError({ err });
64
+ await handleError({ err });
64
65
  };
65
66
  const pageContext = await getPageContextBegin(false, pageContextBeginArgs);
66
67
  if (isRenderOutdated())
@@ -229,96 +230,68 @@ async function renderPageClientSide(renderArgs) {
229
230
  await renderPageView(pageContext);
230
231
  }
231
232
  }
232
- // When the normal page threw an error
233
+ // When the normal page threw an error:
233
234
  // - Can be a URL rewrite upon `throw render('/some-url')`
234
235
  // - Can be rendering the error page
235
236
  // - Can be rendering Vike's generic error page (if no error page is defined, or if the error page throws an error)
236
- async function renderPageOnError(args) {
237
- const onError = (err) => {
238
- if (!isSameErrorMessage(err, args.err)) {
239
- /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
240
- - We risk running into an infinite loop of reloads which would overload the server.
241
- - An infinite reloading page is a even worse UX than a blank page.
242
- redirectHard(urlOriginal)
243
- */
244
- console.error(err);
245
- }
246
- };
247
- if ('err' in args) {
248
- const { err } = args;
249
- assert(err);
250
- if (!isAbortError(err)) {
251
- // We don't swallow 404 errors:
252
- // - 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.)
253
- // - On the client-side, if the user navigates to a 404 then it means that the UI has a broken link. (It isn't expected that users can go to some random URL using the client-side router, as it would require, for example, the user to manually change the URL of a link by manually manipulating the DOM which highly unlikely.)
254
- console.error(err);
255
- }
256
- else {
257
- // We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
258
- // We handle the abort error down below.
259
- }
237
+ async function handleError(args) {
238
+ const { err } = args;
239
+ assert(err);
240
+ // Logging
241
+ if (!isAbortError(err)) {
242
+ // We don't swallow 404 errors:
243
+ // - 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.)
244
+ // - On the client-side, if the user navigates to a 404 then it means that the UI has a broken link. (It isn't expected that users can go to some random URL using the client-side router, as it would require, for example, the user to manually change the URL of a link by manually manipulating the DOM which highly unlikely.)
245
+ logErrorClient(err);
246
+ }
247
+ else {
248
+ // We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
249
+ // We handle the abort error down below.
260
250
  }
251
+ // pageContext
261
252
  const pageContext = await getPageContextBegin(true, pageContextBeginArgs);
262
253
  if (isRenderOutdated())
263
254
  return;
264
- objectAssign(pageContext, { routeParams: {} });
265
- if (args.pageContextError)
266
- objectAssign(pageContext, args.pageContextError);
267
- if ('err' in args) {
268
- const { err } = args;
269
- assert(!('errorWhileRendering' in pageContext));
270
- objectAssign(pageContext, { errorWhileRendering: err });
271
- if (isAbortError(err)) {
272
- const errAbort = err;
273
- logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
274
- const pageContextAbort = errAbort._pageContextAbort;
275
- // throw render('/some-url')
276
- if (pageContextAbort._urlRewrite) {
277
- await renderPageClientSide({
278
- ...renderArgs,
279
- scrollTarget: undefined,
280
- pageContextsFromRewrite: [...pageContextsFromRewrite, pageContextAbort],
281
- });
282
- return;
283
- }
284
- // throw redirect('/some-url')
285
- if (pageContextAbort._urlRedirect) {
286
- const urlRedirect = pageContextAbort._urlRedirect.url;
287
- if (!urlRedirect.startsWith('/')) {
288
- // External redirection
289
- redirectHard(urlRedirect);
290
- return;
291
- }
292
- else {
293
- await renderPageClientSide({
294
- ...renderArgs,
295
- scrollTarget: undefined,
296
- urlOriginal: urlRedirect,
297
- overwriteLastHistoryEntry: false,
298
- isBackwardNavigation: false,
299
- redirectCount: redirectCount + 1,
300
- });
301
- }
302
- return;
303
- }
304
- // throw render(statusCode)
305
- assert(pageContextAbort.abortStatusCode);
306
- assert(!('urlOriginal' in pageContextAbort));
307
- objectAssign(pageContext, pageContextAbort);
308
- if (pageContextAbort.abortStatusCode === 404) {
309
- objectAssign(pageContext, { is404: true });
310
- }
311
- }
312
- else {
313
- objectAssign(pageContext, { is404: false });
314
- }
255
+ objectAssign(pageContext, {
256
+ errorWhileRendering: err,
257
+ });
258
+ // throw redirect()/render()
259
+ let pageContextAbort;
260
+ if (isAbortError(err)) {
261
+ const res = await handleAbortError(err, pageContext);
262
+ if (res.skip)
263
+ return;
264
+ pageContextAbort = res.pageContextAbort;
315
265
  }
266
+ // Render error page
267
+ await renderErrorPage(pageContext, args, pageContextAbort);
268
+ }
269
+ async function renderErrorPage(pageContext, args, pageContextAbort) {
270
+ const onError = (err) => {
271
+ /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
272
+ - We risk running into an infinite loop of reloads which would overload the server.
273
+ - An infinite reloading page is a even worse UX than a blank page.
274
+ redirectHard(urlOriginal)
275
+ */
276
+ logErrorClient(err);
277
+ };
316
278
  const errorPageId = getErrorPageId(pageContext._pageFilesAll, pageContext._globalContext._pageConfigs);
317
279
  if (!errorPageId)
318
280
  throw new Error('No error page defined.');
319
281
  objectAssign(pageContext, {
320
282
  pageId: errorPageId,
283
+ routeParams: {},
321
284
  });
285
+ // throw render(statusCode)
286
+ if (pageContextAbort) {
287
+ assert(pageContextAbort.abortStatusCode);
288
+ assert(!('urlOriginal' in pageContextAbort));
289
+ objectAssign(pageContext, pageContextAbort);
290
+ objectAssign(pageContext, { is404: pageContextAbort.abortStatusCode === 404 });
291
+ }
292
+ else {
293
+ objectAssign(pageContext, { is404: false });
294
+ }
322
295
  const isClientRoutable = await isClientSideRoutable(pageContext.pageId, pageContext);
323
296
  if (isRenderOutdated())
324
297
  return;
@@ -326,6 +299,9 @@ async function renderPageClientSide(renderArgs) {
326
299
  redirectHard(urlOriginal);
327
300
  return;
328
301
  }
302
+ if (import.meta.env.DEV || globalThis.__VIKE__IS_DEBUG) {
303
+ assertInfo(false, `Rendering error page ${errorPageId}`, { onlyOnce: false });
304
+ }
329
305
  const res = await loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRender, isRenderOutdated);
330
306
  /* Already called inside loadPageConfigsLazyClientSideAndExecHook()
331
307
  if (isRenderOutdated()) return
@@ -367,15 +343,49 @@ async function renderPageClientSide(renderArgs) {
367
343
  updateType(pageContext, pageContextFromClientHooks);
368
344
  await renderPageView(pageContext, args);
369
345
  }
346
+ async function handleAbortError(err, pageContext) {
347
+ const errAbort = err;
348
+ logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
349
+ const pageContextAbort = errAbort._pageContextAbort;
350
+ // throw render('/some-url')
351
+ if (pageContextAbort._urlRewrite) {
352
+ await renderPageClientSide({
353
+ ...renderArgs,
354
+ scrollTarget: undefined,
355
+ pageContextsFromRewrite: [...pageContextsFromRewrite, pageContextAbort],
356
+ });
357
+ return { skip: true };
358
+ }
359
+ // throw redirect('/some-url')
360
+ if (pageContextAbort._urlRedirect) {
361
+ const urlRedirect = pageContextAbort._urlRedirect.url;
362
+ if (!urlRedirect.startsWith('/')) {
363
+ // External redirection
364
+ redirectHard(urlRedirect);
365
+ return { skip: true };
366
+ }
367
+ else {
368
+ await renderPageClientSide({
369
+ ...renderArgs,
370
+ scrollTarget: undefined,
371
+ urlOriginal: urlRedirect,
372
+ overwriteLastHistoryEntry: false,
373
+ isBackwardNavigation: false,
374
+ redirectCount: redirectCount + 1,
375
+ });
376
+ }
377
+ return { skip: true };
378
+ }
379
+ // throw render(statusCode)
380
+ return { pageContextAbort };
381
+ }
370
382
  async function renderPageView(pageContext, isErrorPage) {
371
383
  const onError = async (err) => {
372
384
  if (!isErrorPage) {
373
- await renderPageOnError({ err });
385
+ await handleError({ err });
374
386
  }
375
387
  else {
376
- if (!isSameErrorMessage(err, isErrorPage.err)) {
377
- console.error(err);
378
- }
388
+ logErrorClient(err);
379
389
  }
380
390
  };
381
391
  // We use globalObject.onRenderClientPreviousPromise in order to ensure that there is never two concurrent onRenderClient() calls
@@ -395,6 +405,7 @@ async function renderPageClientSide(renderArgs) {
395
405
  await execHookOnRenderClient(pageContext, preparePageContextForPublicUsageClient);
396
406
  }
397
407
  catch (err) {
408
+ assert(err);
398
409
  onRenderClientError = err;
399
410
  }
400
411
  globalObject.onRenderClientPreviousPromise = undefined;
@@ -505,10 +516,10 @@ function changeUrl(url, overwriteLastHistoryEntry) {
505
516
  pushHistoryState(url, overwriteLastHistoryEntry);
506
517
  }
507
518
  function disableClientRouting(err, log) {
508
- assert(isErrorFetchingStaticAssets(err));
509
519
  globalObject.clientRoutingIsDisabled = true;
520
+ assert(isErrorFetchingStaticAssets(err));
510
521
  if (log) {
511
- // We don't use console.error() to avoid flooding error trackers such as Sentry
522
+ // We purposely don't use console.error() to avoid flooding error trackers such as Sentry
512
523
  console.log(err);
513
524
  }
514
525
  assertInfo(false, [
@@ -7,7 +7,6 @@ export * from '../../utils/isCallable.js';
7
7
  export * from '../../utils/isObject.js';
8
8
  export * from '../../utils/isPlainObject.js';
9
9
  export * from '../../utils/isReact.js';
10
- export * from '../../utils/isSameErrorMessage.js';
11
10
  export * from '../../utils/objectAssign.js';
12
11
  export * from '../../utils/parseUrl.js';
13
12
  export * from '../../utils/PromiseType.js';
@@ -11,7 +11,6 @@ export * from '../../utils/isCallable.js';
11
11
  export * from '../../utils/isObject.js';
12
12
  export * from '../../utils/isPlainObject.js';
13
13
  export * from '../../utils/isReact.js';
14
- export * from '../../utils/isSameErrorMessage.js';
15
14
  export * from '../../utils/objectAssign.js';
16
15
  export * from '../../utils/parseUrl.js';
17
16
  export * from '../../utils/PromiseType.js';
@@ -5,8 +5,8 @@ import { parseJson5 } from '../vite/shared/getEnvVarObject.js';
5
5
  const commands = [
6
6
  { name: 'dev', desc: 'Start development server' },
7
7
  { name: 'build', desc: 'Build for production' },
8
- { name: 'preview', desc: 'Start preview server using production build (only works for SSG apps)' },
9
- { name: 'prerender', desc: 'Pre-render pages (only needed when prerender.disableAutoRun is true)' },
8
+ { name: 'preview', desc: 'Start preview server using production build' },
9
+ { name: 'prerender', desc: 'Pre-render pages (only needed when +prerender.disableAutoRun is true)' },
10
10
  ];
11
11
  function parseCli() {
12
12
  const command = getCommand();
@@ -51,7 +51,7 @@ function getCliOptions() {
51
51
  return cliOptions;
52
52
  }
53
53
  function showHelp() {
54
- const TAB = ' '.repeat(3);
54
+ const TAB = ' '.repeat(2);
55
55
  const nameMaxLength = Math.max(...commands.map((c) => c.name.length));
56
56
  console.log([
57
57
  `vike@${PROJECT_VERSION}`,
@@ -60,13 +60,17 @@ function showHelp() {
60
60
  ...[...commands, { name: '-v', desc: "Print Vike's installed version" }].map((c) => ` ${pc.dim('$')} vike ${c.name.startsWith('-') ? pc.cyan(`${c.name}`) : pc.bold(`${c.name}`)}${' '.repeat(nameMaxLength - c.name.length)}${TAB}${pc.dim(`# ${c.desc}`)}`),
61
61
  '',
62
62
  'Common CLI options:',
63
- [`vike dev ${pc.cyan('--host')}`, `vike dev ${pc.cyan('--port')} 80`, `vike build ${pc.cyan('--mode')} staging`]
63
+ [
64
+ `vike dev ${pc.cyan('--host')} ${TAB}${pc.dim('# Make server available over LAN and public addresses')}`,
65
+ `vike dev ${pc.cyan('--port')} 80 ${TAB}${pc.dim('# Change the server port')}`,
66
+ `vike build ${pc.cyan('--mode')} staging${TAB}${pc.dim('# Set the mode to run in')}`,
67
+ `vike dev ${pc.cyan('--force')} ${TAB}${pc.dim("# Disable Vite's cache")}`,
68
+ ]
64
69
  .map((o) => ` ${pc.dim('$')} ${o}`)
65
70
  .join('\n'),
66
71
  '',
67
- `More Vike settings can be passed over the ${pc.cyan('VIKE_CONFIG')} environment variable or as ${pc.cyan('CLI options')}.`,
72
+ `More Vike settings can be passed over the ${pc.cyan('VIKE_CONFIG')} environment variable or as ${pc.cyan('CLI option')}.`,
68
73
  `More Vite settings can be passed over the ${pc.cyan('VITE_CONFIG')} environment variable.`,
69
- ``,
70
74
  `See ${pc.underline('https://vike.dev/cli')} for more information.`,
71
75
  ].join('\n'));
72
76
  process.exit(1);
@@ -539,7 +539,7 @@ async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPre
539
539
  .filter((pageId) => !isErrorPage(pageId, globalContext._pageConfigs))
540
540
  .forEach((pageId) => {
541
541
  const pageAt = isV1 ? pageId : `\`${pageId}.page.*\``;
542
- assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while there isn't any ${hookName}() hook returning an URL matching the page's route. You must use a ${hookName}() hook (https://vike.dev/${hookName}) for providing the list of URLs to be pre-rendered for that page. If you want to skip pre-rendering that page, you can remove this warning by setting +prerender to false at ${pageAt} (https://vike.dev/prerender#toggle) or by setting +prerender.partial to true (https://vike.dev/prerender#partial).`, { onlyOnce: true });
542
+ assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while there isn't any ${hookName}() hook returning an URL matching the page's route. You must use a ${hookName}() hook (https://vike.dev/${hookName}) for providing the list of URLs to be pre-rendered for that page. If you want to skip pre-rendering that page, you can remove this warning by setting +prerender to false at ${pageAt} (https://vike.dev/pre-rendering#partial) or by setting +prerender.partial to true (https://vike.dev/prerender#partial).`, { onlyOnce: true });
543
543
  });
544
544
  }
545
545
  async function writeFiles({ pageContext, htmlString, pageContextSerialized }, viteConfig, onPagePrerender, prerenderContext, logLevel) {
@@ -690,6 +690,7 @@ function preparePrerenderContextForPublicUsage(prerenderContext) {
690
690
  });
691
691
  return prerenderContext.pageContexts;
692
692
  },
693
+ configurable: true,
693
694
  });
694
695
  }
695
696
  // Required because of https://vike.dev/i18n#pre-rendering
@@ -2,6 +2,7 @@ export { getGlobalContext };
2
2
  export { getGlobalContextSync };
3
3
  export { getGlobalContextAsync };
4
4
  export { getGlobalContextServerInternal };
5
+ export { getGlobalContextServerInternalOptional };
5
6
  export { getViteDevServer };
6
7
  export { getViteConfig };
7
8
  export { initGlobalContext_renderPage };
@@ -246,6 +247,97 @@ declare function getGlobalContextServerInternal(): Promise<{
246
247
  prerenderContext: PrerenderContext | undefined;
247
248
  });
248
249
  }>;
250
+ declare function getGlobalContextServerInternalOptional(): (Record<string, unknown> & (({
251
+ _globalConfigPublic: {
252
+ pages: {
253
+ [k: string]: {
254
+ config: import("../../types/index.js").ConfigResolved;
255
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
256
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
257
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
258
+ } & ({
259
+ route: import("../../types/Config.js").Route;
260
+ isErrorPage?: undefined;
261
+ } | {
262
+ route?: undefined;
263
+ isErrorPage: true;
264
+ });
265
+ };
266
+ config: import("../../types/index.js").ConfigResolved;
267
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
268
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
269
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
270
+ };
271
+ pages: {
272
+ [k: string]: {
273
+ config: import("../../types/index.js").ConfigResolved;
274
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
275
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
276
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
277
+ } & ({
278
+ route: import("../../types/Config.js").Route;
279
+ isErrorPage?: undefined;
280
+ } | {
281
+ route?: undefined;
282
+ isErrorPage: true;
283
+ });
284
+ };
285
+ config: import("../../types/index.js").ConfigResolved;
286
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
287
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
288
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
289
+ isGlobalContext: true;
290
+ _isOriginalObject: true;
291
+ _virtualFileExportsGlobalEntry: unknown;
292
+ _pageFilesAll: import("../../shared/getPageFiles.js").PageFile[];
293
+ _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
294
+ _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
295
+ _allPageIds: string[];
296
+ } & (({
297
+ _isProduction: false;
298
+ _isPrerendering: false;
299
+ assetsManifest: null;
300
+ _viteDevServer: ViteDevServer | undefined;
301
+ viteConfig: ResolvedConfig | undefined;
302
+ isClientSide: false;
303
+ _pageRoutes: PageRoutes;
304
+ _onBeforeRouteHook: Hook | null;
305
+ } | {
306
+ _isPrerendering: true;
307
+ viteConfig: ResolvedConfig;
308
+ _isProduction: true;
309
+ assetsManifest: ViteManifest;
310
+ _viteDevServer: null;
311
+ _usesClientRouter: boolean;
312
+ isClientSide: false;
313
+ _pageRoutes: PageRoutes;
314
+ _onBeforeRouteHook: Hook | null;
315
+ } | {
316
+ _isPrerendering: false;
317
+ viteConfig: null;
318
+ _isProduction: true;
319
+ assetsManifest: ViteManifest;
320
+ _viteDevServer: null;
321
+ _usesClientRouter: boolean;
322
+ isClientSide: false;
323
+ _pageRoutes: PageRoutes;
324
+ _onBeforeRouteHook: Hook | null;
325
+ }) & {
326
+ baseServer: string;
327
+ baseAssets: string;
328
+ viteConfigRuntime: {
329
+ root: string;
330
+ build: {
331
+ outDir: string;
332
+ };
333
+ _baseViteOriginal: string;
334
+ vitePluginServerEntry: {
335
+ inject: boolean | undefined;
336
+ };
337
+ };
338
+ })) & {
339
+ prerenderContext: PrerenderContext | undefined;
340
+ })) | null;
249
341
  /**
250
342
  * Get runtime information about your app.
251
343
  *
@@ -4,6 +4,7 @@ export { getGlobalContextSync };
4
4
  export { getGlobalContextAsync };
5
5
  // Internal use
6
6
  export { getGlobalContextServerInternal };
7
+ export { getGlobalContextServerInternalOptional };
7
8
  export { getViteDevServer };
8
9
  export { getViteConfig };
9
10
  export { initGlobalContext_renderPage };
@@ -58,6 +59,12 @@ async function getGlobalContextServerInternal() {
58
59
  assertIsDefined(globalContext);
59
60
  return { globalContext };
60
61
  }
62
+ function getGlobalContextServerInternalOptional() {
63
+ const { globalContext } = globalObjectTyped;
64
+ if (!globalContext)
65
+ return null;
66
+ return globalContext;
67
+ }
61
68
  function assertIsDefined(globalContext) {
62
69
  if (!globalContext) {
63
70
  debug('globalContext', globalContext);
@@ -556,7 +563,8 @@ function isProdOptional() {
556
563
  const yes5 = globalObject.isProductionAccordingToUser === true;
557
564
  // vite-plugin-vercel
558
565
  const yes6 = globalObject.isProductionAccordingToPhotonVercel === true;
559
- const yes = yes1 || yes2 || yes3 || yes4 || yes5 || yes6;
566
+ const yes7 = globalThis.__VIKE__IS_DEV === false;
567
+ const yes = yes1 || yes2 || yes3 || yes4 || yes5 || yes6 || yes7;
560
568
  const no1 = !!globalObject.viteDevServer;
561
569
  // Vike CLI & Vike API
562
570
  const no2 = vikeApiOperation === 'dev';
@@ -566,8 +574,9 @@ function isProdOptional() {
566
574
  const no4 = globalObject.isProductionAccordingToUser === false;
567
575
  // @cloudflare/vite-plugin
568
576
  const no5 = isNonRunnableDev();
569
- const no = no1 || no2 || no3 || no4 || no5;
570
- const debug = { yes1, yes2, yes3, yes4, yes5, yes6, no1, no2, no3, no4, no5 };
577
+ const no6 = globalThis.__VIKE__IS_DEV === true;
578
+ const no = no1 || no2 || no3 || no4 || no5 || no6;
579
+ const debug = { yes1, yes2, yes3, yes4, yes5, yes6, yes7, no1, no2, no3, no4, no5, no6 };
571
580
  assert(typeof yes === 'boolean', debug);
572
581
  assert(typeof no === 'boolean', debug);
573
582
  if (yes) {
@@ -0,0 +1,2 @@
1
+ export { logErrorServer };
2
+ declare function logErrorServer(err: unknown): void;
@@ -0,0 +1,11 @@
1
+ export { logErrorServer };
2
+ import pc from '@brillout/picocolors';
3
+ import { isObject } from './utils.js';
4
+ import { execHookOnError } from './renderPage/execHookOnError.js';
5
+ function logErrorServer(err) {
6
+ execHookOnError(err);
7
+ // We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
8
+ // - TO-DO/eventually: is that still true? Let's eventually remove it and see if it crashes Cloudflare.
9
+ const errStr = isObject(err) && 'stack' in err ? String(err.stack) : String(err);
10
+ console.error(pc.red(errStr));
11
+ }
@@ -0,0 +1,2 @@
1
+ export { execHookOnError };
2
+ declare function execHookOnError(err: unknown): void;
@@ -0,0 +1,26 @@
1
+ export { execHookOnError };
2
+ import { isObject, getGlobalObject } from '../utils.js';
3
+ import { getGlobalContextServerInternalOptional } from '../globalContext.js';
4
+ import { getHookFromPageConfigGlobalCumulative } from '../../../shared/hooks/getHook.js';
5
+ const globalObject = getGlobalObject('renderPage/execHookOnError.ts', {
6
+ seen: new WeakSet(),
7
+ });
8
+ function execHookOnError(err) {
9
+ if (isObject(err)) {
10
+ if (globalObject.seen.has(err))
11
+ return;
12
+ globalObject.seen.add(err);
13
+ }
14
+ const globalContext = getGlobalContextServerInternalOptional();
15
+ if (!globalContext)
16
+ return;
17
+ const hooks = getHookFromPageConfigGlobalCumulative(globalContext._pageConfigGlobal, 'onError');
18
+ for (const hook of hooks) {
19
+ try {
20
+ hook.hookFn(err);
21
+ }
22
+ catch (hookErr) {
23
+ console.error(hookErr);
24
+ }
25
+ }
26
+ }
@@ -5,7 +5,7 @@ import type { PageContextConfig } from '../../../shared/getPageFiles.js';
5
5
  import type { HookName } from '../../../types/Config.js';
6
6
  type PageContextExecHookServer = PageContextConfig & PageContextForPublicUsageServer;
7
7
  declare function execHookServer(hookName: HookName, pageContext: PageContextExecHookServer): Promise<(import("../../../shared/hooks/getHook.js").HookLoc & {
8
- hookFn: (arg: import("../../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum | import("../../../shared/prepareGlobalContextForPublicUsage.js").GlobalContextPrepareMinimum) => unknown;
8
+ hookFn: (arg: import("../../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum) => unknown;
9
9
  hookTimeout: import("../../../shared/hooks/getHook.js").HookTimeout;
10
10
  } & {
11
11
  hookReturn: unknown;
@@ -4,18 +4,16 @@ export { logErrorProd };
4
4
  export { onRuntimeError };
5
5
  import { isAbortError } from '../../../shared/route/abort.js';
6
6
  import { setAlreadyLogged } from './isNewError.js';
7
- import { isObject, warnIfErrorIsNotObject } from '../utils.js';
8
- import pc from '@brillout/picocolors';
7
+ import { warnIfErrorIsNotObject } from '../utils.js';
9
8
  import { logErrorHint } from './logErrorHint.js';
9
+ import { logErrorServer } from '../logErrorServer.js';
10
10
  function logErrorProd(err, _httpRequestId) {
11
11
  warnIfErrorIsNotObject(err);
12
12
  setAlreadyLogged(err);
13
13
  if (isAbortError(err)) {
14
14
  return;
15
15
  }
16
- // We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
17
- const errStr = isObject(err) && 'stack' in err ? String(err.stack) : String(err);
18
- console.error(pc.red(errStr));
16
+ logErrorServer(err);
19
17
  // Needs to be called after logging the error.
20
18
  onRuntimeError(err);
21
19
  }
@@ -64,11 +64,12 @@ async function renderPagePrepare(pageContextInit, httpRequestId) {
64
64
  await initGlobalContext_renderPage();
65
65
  }
66
66
  catch (err) {
67
- // Errors are expected since assertUsage() is used in initGlobalContext_renderPage() such as:
68
- // ```bash
69
- // Re-build your app (you're using 1.2.3 but your app was built with 1.2.2)
70
- // ```
71
- // initGlobalContext_renderPage() doesn't call any user hook => err isn't thrown from user code.
67
+ // Errors are expected:
68
+ // - assertUsage() such as:
69
+ // ```bash
70
+ // Re-build your app (you're using 1.2.3 but your app was built with 1.2.2)
71
+ // ```
72
+ // - initGlobalContext_renderPage() depends on +onCreateGlobalContext hooks
72
73
  assert(!isAbortError(err));
73
74
  logRuntimeError(err, httpRequestId);
74
75
  const pageContextWithError = getPageContextHttpResponseErrorWithoutGlobalContext(err, pageContextInit);
@@ -245,7 +246,7 @@ function logHttpResponse(urlOriginalPretty, httpRequestId, pageContextReturn) {
245
246
  msg = `HTTP ${type} ${prettyUrl(urlOriginalPretty)} ${color(statusCode ?? 'ERR')}`;
246
247
  }
247
248
  }
248
- logRuntimeInfo?.(msg, httpRequestId, isNominal ? 'info' : 'error');
249
+ logRuntimeInfo?.(msg, httpRequestId, isNominal ? 'info' : 'error-note');
249
250
  }
250
251
  function prettyUrl(url) {
251
252
  try {
@@ -485,7 +486,7 @@ function getPageContextSkipRequest(pageContextInit) {
485
486
  return pageContext;
486
487
  }
487
488
  function getPageContextInvalidVikeConfig(err, pageContextInit, httpRequestId) {
488
- logRuntimeInfo?.(pc.bold(pc.red('Error loading Vike config — see error above')), httpRequestId, 'error');
489
+ logRuntimeInfo?.(pc.bold(pc.red('Error loading Vike config — see error above')), httpRequestId, 'error-note');
489
490
  const pageContextWithError = getPageContextHttpResponseErrorWithoutGlobalContext(err, pageContextInit);
490
491
  return pageContextWithError;
491
492
  }