vike 0.4.240 → 0.4.241-commit-60b0676

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 (99) 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/api/build.js +6 -6
  9. package/dist/esm/node/api/dev.js +2 -2
  10. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -9
  11. package/dist/esm/node/api/prepareViteApiCall.js +4 -156
  12. package/dist/esm/node/api/prerender.js +2 -2
  13. package/dist/esm/node/api/preview.js +2 -2
  14. package/dist/esm/node/api/resolveViteConfigFromUser.d.ts +20 -0
  15. package/dist/esm/node/api/resolveViteConfigFromUser.js +207 -0
  16. package/dist/esm/node/cli/parseCli.js +10 -6
  17. package/dist/esm/node/prerender/runPrerender.js +2 -1
  18. package/dist/esm/node/prerender/runPrerenderEntry.js +4 -4
  19. package/dist/esm/node/runtime/globalContext.d.ts +92 -0
  20. package/dist/esm/node/runtime/globalContext.js +12 -3
  21. package/dist/esm/node/runtime/logErrorServer.d.ts +2 -0
  22. package/dist/esm/node/runtime/logErrorServer.js +18 -0
  23. package/dist/esm/node/runtime/renderPage/execHookOnError.d.ts +2 -0
  24. package/dist/esm/node/runtime/renderPage/execHookOnError.js +26 -0
  25. package/dist/esm/node/runtime/renderPage/execHookServer.d.ts +1 -1
  26. package/dist/esm/node/runtime/renderPage/loggerProd.js +3 -5
  27. package/dist/esm/node/runtime/renderPage.js +8 -7
  28. package/dist/esm/node/runtime-dev/createDevMiddleware.js +2 -2
  29. package/dist/esm/node/vite/index.d.ts +1 -1
  30. package/dist/esm/node/vite/index.js +55 -24
  31. package/dist/esm/node/vite/onLoad.js +3 -8
  32. package/dist/esm/node/vite/plugins/build/handleAssetsManifest.js +0 -1
  33. package/dist/esm/node/vite/plugins/build/pluginBuildApp.js +6 -6
  34. package/dist/esm/node/vite/plugins/build/pluginDistFileNames.js +2 -2
  35. package/dist/esm/node/vite/plugins/pluginCommon.d.ts +1 -1
  36. package/dist/esm/node/vite/plugins/pluginCommon.js +22 -9
  37. package/dist/esm/node/vite/plugins/pluginFileEnv.js +9 -6
  38. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.d.ts +3 -0
  39. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.js +129 -0
  40. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.d.ts +10 -0
  41. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +77 -0
  42. package/dist/esm/node/vite/plugins/pluginReplaceConstantsPageContext.d.ts +3 -0
  43. package/dist/esm/node/vite/plugins/{pluginReplaceIsClientSide.js → pluginReplaceConstantsPageContext.js} +5 -3
  44. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +7 -1
  45. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -0
  46. package/dist/esm/node/vite/plugins/pluginVirtualFiles.js +2 -2
  47. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.d.ts +3 -0
  48. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.js +32 -0
  49. package/dist/esm/node/vite/shared/getFilePath.d.ts +4 -6
  50. package/dist/esm/node/vite/shared/getFilePath.js +6 -11
  51. package/dist/esm/node/vite/shared/isViteCli.d.ts +13 -0
  52. package/dist/esm/node/vite/shared/isViteCli.js +143 -0
  53. package/dist/esm/node/vite/shared/isViteServerSide.d.ts +6 -3
  54. package/dist/esm/node/vite/shared/isViteServerSide.js +13 -4
  55. package/dist/esm/node/vite/shared/loggerNotProd/errorWithCodeSnippet.js +2 -2
  56. package/dist/esm/node/vite/shared/loggerNotProd/log.js +8 -2
  57. package/dist/esm/node/vite/shared/loggerNotProd.d.ts +1 -1
  58. package/dist/esm/node/vite/shared/loggerNotProd.js +11 -11
  59. package/dist/esm/node/vite/shared/loggerVite.js +4 -2
  60. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +12 -2
  61. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +12 -8
  62. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.d.ts +2 -0
  63. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.js +4 -0
  64. package/dist/esm/node/vite/utils.d.ts +1 -0
  65. package/dist/esm/node/vite/utils.js +1 -0
  66. package/dist/esm/shared/createGlobalContextShared.d.ts +2 -1
  67. package/dist/esm/shared/createGlobalContextShared.js +1 -1
  68. package/dist/esm/shared/hooks/execHook.d.ts +1 -1
  69. package/dist/esm/shared/hooks/getHook.d.ts +5 -4
  70. package/dist/esm/shared/route/abort.d.ts +1 -0
  71. package/dist/esm/shared/route/abort.js +12 -4
  72. package/dist/esm/shared/route/index.js +13 -4
  73. package/dist/esm/shared/route/utils.d.ts +1 -0
  74. package/dist/esm/shared/route/utils.js +1 -0
  75. package/dist/esm/types/Config.d.ts +14 -3
  76. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  77. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  78. package/dist/esm/utils/assert.js +1 -0
  79. package/dist/esm/utils/assertNodeVersion.js +1 -1
  80. package/dist/esm/utils/assertViteVersion.d.ts +2 -0
  81. package/dist/esm/utils/assertViteVersion.js +11 -0
  82. package/dist/esm/utils/debug.d.ts +5 -3
  83. package/dist/esm/utils/debug.js +20 -16
  84. package/dist/esm/utils/getGlobalObject.d.ts +5 -1
  85. package/dist/esm/utils/getGlobalObject.js +5 -1
  86. package/dist/esm/utils/isExactlyOneTruthy.d.ts +1 -0
  87. package/dist/esm/utils/isExactlyOneTruthy.js +4 -0
  88. package/dist/esm/utils/isVikeReactApp.js +2 -1
  89. package/dist/esm/utils/requireResolve.js +1 -1
  90. package/package.json +3 -3
  91. package/dist/esm/node/vite/plugins/pluginEnvVars.d.ts +0 -3
  92. package/dist/esm/node/vite/plugins/pluginEnvVars.js +0 -110
  93. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.d.ts +0 -9
  94. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.js +0 -45
  95. package/dist/esm/node/vite/plugins/pluginReplaceIsClientSide.d.ts +0 -3
  96. package/dist/esm/node/vite/shared/isViteCliCall.d.ts +0 -10
  97. package/dist/esm/node/vite/shared/isViteCliCall.js +0 -81
  98. package/dist/esm/shared/route/debug.d.ts +0 -6
  99. 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';
@@ -7,16 +7,16 @@ import { createBuilder } from 'vite';
7
7
  * https://vike.dev/api#build
8
8
  */
9
9
  async function build(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'build');
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'build');
11
11
  // Pass it to vike:build:pluginBuildApp
12
- if (viteConfigFromUserEnhanced)
13
- viteConfigFromUserEnhanced._viteConfigFromUserEnhanced = viteConfigFromUserEnhanced;
14
- const builder = await createBuilder(viteConfigFromUserEnhanced);
12
+ if (viteConfigFromUserResolved)
13
+ viteConfigFromUserResolved._viteConfigFromUserResolved = viteConfigFromUserResolved;
14
+ const builder = await createBuilder(viteConfigFromUserResolved);
15
15
  // buildApp() is implemented by vike:build:pluginBuildApp
16
16
  await builder.buildApp();
17
17
  return {
18
- /* We don't return `viteConfig` because `viteConfigFromUserEnhanced` is `InlineConfig` not `ResolvedConfig`
19
- viteConfig: viteConfigFromUserEnhanced,
18
+ /* We don't return `viteConfig` because `viteConfigFromUserResolved` is `InlineConfig` not `ResolvedConfig`
19
+ viteConfig: viteConfigFromUserResolved,
20
20
  */
21
21
  };
22
22
  }
@@ -7,8 +7,8 @@ import { createServer } from 'vite';
7
7
  * https://vike.dev/api#dev
8
8
  */
9
9
  async function dev(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'dev');
11
- const server = await createServer(viteConfigFromUserEnhanced);
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'dev');
11
+ const server = await createServer(viteConfigFromUserResolved);
12
12
  return {
13
13
  viteServer: server,
14
14
  viteConfig: server.config,
@@ -1,13 +1,6 @@
1
1
  export { prepareViteApiCall };
2
- export { getViteRoot };
3
- export { assertViteRoot };
4
- export { normalizeViteRoot };
5
- import type { InlineConfig, ResolvedConfig } from 'vite';
6
2
  import type { ApiOptions, ApiOperation } from './types.js';
7
3
  declare function prepareViteApiCall(options: ApiOptions, operation: ApiOperation): Promise<{
8
- viteConfigResolved: ResolvedConfig;
9
- viteConfigFromUserEnhanced: InlineConfig | undefined;
4
+ viteConfigResolved: import("vite").ResolvedConfig;
5
+ viteConfigFromUserResolved: import("vite").InlineConfig | undefined;
10
6
  }>;
11
- declare function getViteRoot(operation: ApiOperation): Promise<string>;
12
- declare function normalizeViteRoot(root: string): string;
13
- declare function assertViteRoot(root: string, config: ResolvedConfig): void;
@@ -1,168 +1,16 @@
1
1
  export { prepareViteApiCall };
2
- export { getViteRoot };
3
- export { assertViteRoot };
4
- export { normalizeViteRoot };
5
- import { loadConfigFromFile, mergeConfig, resolveConfig } from 'vite';
6
2
  import { clearContextVikeApiOperation, setContextVikeApiOperation } from './context.js';
7
- import { getVikeConfigInternal, getVikeConfigFromCliOrEnv, setVikeConfigContext, } from '../vite/shared/resolveVikeConfigInternal.js';
8
- import path from 'node:path';
9
- import { assert, assertUsage, getGlobalObject, isObject, pick, toPosixPath } from './utils.js';
10
- import pc from '@brillout/picocolors';
11
3
  import { clearGlobalContext } from '../runtime/globalContext.js';
12
- import { getEnvVarObject } from '../vite/shared/getEnvVarObject.js';
13
- const globalObject = getGlobalObject('api/prepareViteApiCall.ts', {});
4
+ import { getViteContextWithOperation, resolveViteConfigFromUser } from './resolveViteConfigFromUser.js';
14
5
  async function prepareViteApiCall(options, operation) {
15
6
  clear();
16
7
  setContextVikeApiOperation(operation, options);
17
- const viteConfigFromUserApiOptions = options.viteConfig;
18
- return resolveConfigs(viteConfigFromUserApiOptions, operation);
8
+ const viteConfigFromUserVikeApiOptions = options.viteConfig;
9
+ const viteContext = getViteContextWithOperation(operation);
10
+ return resolveViteConfigFromUser(viteConfigFromUserVikeApiOptions, viteContext);
19
11
  }
20
12
  // For subsequent API calls, e.g. calling prerender() after build()
21
13
  function clear() {
22
14
  clearContextVikeApiOperation();
23
15
  clearGlobalContext();
24
16
  }
25
- async function resolveConfigs(viteConfigFromUserApiOptions, operation) {
26
- const viteInfo = await getViteInfo(viteConfigFromUserApiOptions, operation);
27
- setVikeConfigContext({
28
- userRootDir: viteInfo.root,
29
- isDev: operation === 'dev',
30
- vikeVitePluginOptions: viteInfo.vikeVitePluginOptions,
31
- });
32
- const vikeConfig = await getVikeConfigInternal();
33
- const viteConfigFromUserEnhanced = applyVikeViteConfig(viteInfo.viteConfigFromUserEnhanced, vikeConfig);
34
- const { viteConfigResolved } = await assertViteRoot2(viteInfo.root, viteConfigFromUserEnhanced, operation);
35
- return {
36
- viteConfigResolved, // ONLY USE if strictly necessary. (We plan to remove assertViteRoot2() as explained in the comments of that function.)
37
- viteConfigFromUserEnhanced,
38
- };
39
- }
40
- // Apply +vite
41
- // - For example, Vike extensions adding Vite plugins
42
- function applyVikeViteConfig(viteConfigFromUserEnhanced, vikeConfig) {
43
- const viteConfigs = vikeConfig._from.configsCumulative.vite;
44
- if (!viteConfigs)
45
- return viteConfigFromUserEnhanced;
46
- viteConfigs.values.forEach((v) => {
47
- assertUsage(isObject(v.value), `${v.definedAt} should be an object`);
48
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, v.value);
49
- assertUsage(!findVikeVitePlugin(v.value), "Using the +vite setting to add Vike's Vite plugin is forbidden");
50
- });
51
- return viteConfigFromUserEnhanced;
52
- }
53
- async function getViteRoot(operation) {
54
- if (!globalObject.root)
55
- await getViteInfo(undefined, operation);
56
- assert(globalObject.root);
57
- return globalObject.root;
58
- }
59
- async function getViteInfo(viteConfigFromUserApiOptions, operation) {
60
- let viteConfigFromUserEnhanced = viteConfigFromUserApiOptions;
61
- // Precedence:
62
- // 1) viteConfigFromUserEnvVar (highest precedence)
63
- // 2) viteConfigFromUserVikeConfig
64
- // 2) viteConfigFromUserApiOptions
65
- // 3) viteConfigFromUserViteFile (lowest precedence)
66
- // Resolve Vike's +mode setting
67
- {
68
- const viteConfigFromUserVikeConfig = pick(getVikeConfigFromCliOrEnv().vikeConfigFromCliOrEnv, ['mode']);
69
- if (Object.keys(viteConfigFromUserVikeConfig).length > 0) {
70
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserVikeConfig);
71
- }
72
- }
73
- // Resolve VITE_CONFIG
74
- const viteConfigFromUserEnvVar = getEnvVarObject('VITE_CONFIG');
75
- if (viteConfigFromUserEnvVar) {
76
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserEnvVar);
77
- }
78
- // Resolve vite.config.js
79
- const viteConfigFromUserViteFile = await loadViteConfigFile(viteConfigFromUserEnhanced, operation);
80
- // Correct precedence, replicates Vite:
81
- // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
82
- const viteConfigResolved = mergeConfig(viteConfigFromUserViteFile ?? {}, viteConfigFromUserEnhanced ?? {});
83
- const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
84
- globalObject.root = root;
85
- // - Find options `vike(options)` set in vite.config.js
86
- // - TO-DO/next-major-release: remove
87
- // - Add Vike's Vite plugin if missing
88
- let vikeVitePluginOptions;
89
- const found = findVikeVitePlugin(viteConfigResolved);
90
- if (found) {
91
- vikeVitePluginOptions = found.vikeVitePluginOptions;
92
- }
93
- else {
94
- // Add Vike to plugins if not present.
95
- // Using a dynamic import because the script calling the Vike API may not live in the same place as vite.config.js, thus vike/plugin may resolved to two different node_modules/vike directories.
96
- const { plugin: vikePlugin } = await import('../vite/index.js');
97
- viteConfigFromUserEnhanced = {
98
- ...viteConfigFromUserEnhanced,
99
- plugins: [...(viteConfigFromUserEnhanced?.plugins ?? []), vikePlugin()],
100
- };
101
- const res = findVikeVitePlugin(viteConfigFromUserEnhanced);
102
- assert(res);
103
- vikeVitePluginOptions = res.vikeVitePluginOptions;
104
- }
105
- assert(vikeVitePluginOptions);
106
- return { root, vikeVitePluginOptions, viteConfigFromUserEnhanced };
107
- }
108
- function findVikeVitePlugin(viteConfig) {
109
- let vikeVitePluginOptions;
110
- let vikeVitePuginFound = false;
111
- viteConfig?.plugins?.forEach((p) => {
112
- if (p && '_vikeVitePluginOptions' in p) {
113
- vikeVitePuginFound = true;
114
- const options = p._vikeVitePluginOptions;
115
- vikeVitePluginOptions ?? (vikeVitePluginOptions = {});
116
- Object.assign(vikeVitePluginOptions, options);
117
- }
118
- });
119
- if (!vikeVitePuginFound)
120
- return null;
121
- return { vikeVitePluginOptions };
122
- }
123
- // Copied from https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L961-L1005
124
- async function loadViteConfigFile(viteConfigFromUserApiOptions, operation) {
125
- const [inlineConfig, command, defaultMode, _defaultNodeEnv, isPreview] = getResolveConfigArgs(viteConfigFromUserApiOptions, operation);
126
- let config = inlineConfig;
127
- let mode = inlineConfig.mode || defaultMode;
128
- const configEnv = {
129
- mode,
130
- command,
131
- isSsrBuild: command === 'build' && !!config.build?.ssr,
132
- isPreview,
133
- };
134
- let { configFile } = config;
135
- if (configFile !== false) {
136
- const loadResult = await loadConfigFromFile(configEnv, configFile, config.root, config.logLevel, config.customLogger);
137
- return loadResult?.config;
138
- }
139
- return null;
140
- }
141
- function getResolveConfigArgs(viteConfig = {}, operation) {
142
- const inlineConfig = viteConfig;
143
- const command = operation === 'build' || operation === 'prerender' ? 'build' : 'serve';
144
- const defaultMode = operation === 'dev' ? 'development' : 'production';
145
- const defaultNodeEnv = defaultMode;
146
- const isPreview = operation === 'preview';
147
- return [inlineConfig, command, defaultMode, defaultNodeEnv, isPreview];
148
- }
149
- function normalizeViteRoot(root) {
150
- // `path.resolve(viteConfigFromUserViteFile.configFile, root)` could be more intuitive than `path.resolve(process.cwd(), root)` but we replicate Vite's behavior (`vite.config.js` should follow Vite's API), see:
151
- // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1063
152
- return toPosixPath(
153
- // Equivalent to `path.resolve(process.cwd(), root)`
154
- path.resolve(root));
155
- }
156
- const errMsg = `A Vite plugin is modifying Vite's setting ${pc.cyan('root')} which is forbidden`;
157
- async function assertViteRoot2(root, viteConfigFromUserEnhanced, operation) {
158
- const args = getResolveConfigArgs(viteConfigFromUserEnhanced, operation);
159
- // We can eventually remove this resolveConfig() call (along with removing the whole assertViteRoot2() function which is redundant with the assertViteRoot() function) so that Vike doesn't make any resolveConfig() (except for pre-rendering and preview which is required). But let's keep it for now, just to see whether calling resolveConfig() can be problematic.
160
- const viteConfigResolved = await resolveConfig(...args);
161
- assertUsage(normalizeViteRoot(viteConfigResolved.root) === normalizeViteRoot(root), errMsg);
162
- return { viteConfigResolved };
163
- }
164
- function assertViteRoot(root, config) {
165
- if (globalObject.root)
166
- assert(normalizeViteRoot(globalObject.root) === normalizeViteRoot(root));
167
- assertUsage(normalizeViteRoot(root) === normalizeViteRoot(config.root), errMsg);
168
- }
@@ -7,8 +7,8 @@ import { prepareViteApiCall } from './prepareViteApiCall.js';
7
7
  * https://vike.dev/api#prerender
8
8
  */
9
9
  async function prerender(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'prerender');
11
- options.viteConfig = viteConfigFromUserEnhanced;
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'prerender');
11
+ options.viteConfig = viteConfigFromUserResolved;
12
12
  const { viteConfig } = await runPrerenderFromAPI(options);
13
13
  return {
14
14
  viteConfig,
@@ -13,7 +13,7 @@ import path from 'node:path';
13
13
  */
14
14
  async function preview(options = {}) {
15
15
  onSetupPreview();
16
- const { viteConfigFromUserEnhanced, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
16
+ const { viteConfigFromUserResolved, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
17
17
  if (viteConfigResolved.vitePluginServerEntry?.inject) {
18
18
  const outDir = getOutDirs(viteConfigResolved, undefined).outDirRoot;
19
19
  const { outServerIndex } = await importServerProductionIndex({ outDir });
@@ -24,7 +24,7 @@ async function preview(options = {}) {
24
24
  };
25
25
  }
26
26
  else {
27
- const server = await previewVite(viteConfigFromUserEnhanced);
27
+ const server = await previewVite(viteConfigFromUserResolved);
28
28
  return {
29
29
  viteServer: server,
30
30
  viteConfig: server.config,
@@ -0,0 +1,20 @@
1
+ export { resolveViteConfigFromUser };
2
+ export { isOnlyResolvingUserConfig };
3
+ export { getVikeConfigInternalEarly };
4
+ export { getViteContextWithOperation };
5
+ export { getViteRoot };
6
+ export { assertViteRoot };
7
+ export { normalizeViteRoot };
8
+ import type { InlineConfig, ResolvedConfig } from 'vite';
9
+ import type { ApiOperation } from './types.js';
10
+ declare function resolveViteConfigFromUser(viteConfigFromUserVikeApiOptions: InlineConfig | undefined, viteContext: ViteContext): Promise<{
11
+ viteConfigResolved: ResolvedConfig;
12
+ viteConfigFromUserResolved: InlineConfig | undefined;
13
+ }>;
14
+ declare function getVikeConfigInternalEarly(): Promise<import("../vite/shared/resolveVikeConfigInternal.js").VikeConfigInternal>;
15
+ declare function isOnlyResolvingUserConfig(): boolean | undefined;
16
+ declare function getViteRoot(viteContext: ViteContext): Promise<string>;
17
+ type ViteContext = 'build' | 'preview' | 'dev';
18
+ declare function getViteContextWithOperation(operation: ApiOperation): ViteContext;
19
+ declare function normalizeViteRoot(root: string): string;
20
+ declare function assertViteRoot(root: string, config: ResolvedConfig): void;