vike 0.4.267 → 0.4.268-commit-ca58695

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 (204) hide show
  1. package/RenderErrorPage.js +2 -2
  2. package/abort.js +2 -2
  3. package/dist/client/__internal/index.d.ts +3 -0
  4. package/dist/client/__internal/index.js +4 -0
  5. package/dist/client/runtime-client-routing/createPageContextClient.d.ts +5 -0
  6. package/dist/client/runtime-client-routing/getGlobalContextClientInternal.d.ts +5 -0
  7. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +28 -2
  8. package/dist/client/runtime-client-routing/getPageContextFromHooks.js +5 -5
  9. package/dist/client/runtime-client-routing/renderPageClient.d.ts +490 -10
  10. package/dist/client/runtime-client-routing/renderPageClient.js +149 -43
  11. package/dist/client/runtime-client-routing/streamedValues.d.ts +5 -0
  12. package/dist/client/runtime-client-routing/streamedValues.js +23 -0
  13. package/dist/client/runtime-server-routing/createPageContextClient.d.ts +5 -0
  14. package/dist/client/runtime-server-routing/entry.js +1 -1
  15. package/dist/client/runtime-server-routing/getGlobalContextClientInternal.d.ts +5 -0
  16. package/dist/client/shared/getGlobalContextClientInternalShared.d.ts +5 -0
  17. package/dist/client/shared/getGlobalContextClientInternalShared.js +2 -0
  18. package/dist/client/shared/getJsonSerializedInHtml.d.ts +2 -2
  19. package/dist/client/shared/getJsonSerializedInHtml.js +9 -6
  20. package/dist/client/shared/loadPageConfigsLazyClientSide.js +0 -4
  21. package/dist/client/shared/removeFoucBuster.js +14 -3
  22. package/dist/client/shared/streamedValues/asyncIterable.d.ts +4 -0
  23. package/dist/client/shared/streamedValues/asyncIterable.js +26 -0
  24. package/dist/client/shared/streamedValues/lines.d.ts +11 -0
  25. package/dist/client/shared/streamedValues/lines.js +19 -0
  26. package/dist/client/shared/streamedValues/promise.d.ts +4 -0
  27. package/dist/client/shared/streamedValues/promise.js +19 -0
  28. package/dist/client/shared/streamedValues/readableStream.d.ts +4 -0
  29. package/dist/client/shared/streamedValues/readableStream.js +44 -0
  30. package/dist/client/shared/streamedValues/registry.d.ts +21 -0
  31. package/dist/client/shared/streamedValues/registry.js +40 -0
  32. package/dist/client/shared/streamedValues.d.ts +7 -0
  33. package/dist/client/shared/streamedValues.js +82 -0
  34. package/dist/node/api/dev.js +15 -1
  35. package/dist/node/api/resolveViteConfigUser.js +2 -2
  36. package/dist/node/api/serverEntryDev.d.ts +10 -0
  37. package/dist/node/api/serverEntryDev.js +125 -0
  38. package/dist/node/createDevMiddleware.js +12 -0
  39. package/dist/node/prerender/resolvePrerenderConfig.d.ts +1 -1
  40. package/dist/node/prerender/resolvePrerenderConfig.js +4 -1
  41. package/dist/node/prerender/runPrerender.d.ts +18 -18
  42. package/dist/node/prerender/runPrerender.js +61 -16
  43. package/dist/node/vite/assertEnvVite.js +1 -1
  44. package/dist/node/vite/index.js +2 -0
  45. package/dist/node/vite/plugins/build/handleAssetsManifest.js +6 -2
  46. package/dist/node/vite/plugins/build/pluginBuildApp.js +25 -26
  47. package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +2 -2
  48. package/dist/node/vite/plugins/build/pluginBuildConfig.js +25 -17
  49. package/dist/node/vite/plugins/build/pluginDistFileNames.js +70 -50
  50. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.d.ts +6 -0
  51. package/dist/node/vite/plugins/build/pluginEnvironmentEntries.js +71 -0
  52. package/dist/node/vite/plugins/build/pluginSuppressRollupWarning.js +19 -17
  53. package/dist/node/vite/plugins/pluginCommon.js +10 -7
  54. package/dist/node/vite/plugins/pluginDev/optimizeDeps.d.ts +2 -2
  55. package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +6 -2
  56. package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +6 -4
  57. package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.d.ts +3 -0
  58. package/dist/node/vite/plugins/pluginUniversalDeploy/getServerConfig.js +28 -2
  59. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.d.ts +1 -1
  60. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginServerEntryAlias.js +22 -11
  61. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.d.ts +4 -0
  62. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginWrapServerFile.js +29 -0
  63. package/dist/node/vite/plugins/pluginUniversalDeploy.js +29 -5
  64. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.d.ts +2 -1
  65. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +29 -12
  66. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -2
  67. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +7 -7
  68. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +10 -6
  69. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js +5 -11
  70. package/dist/node/vite/plugins/pluginVirtualFiles.js +20 -0
  71. package/dist/node/vite/shared/addSsrMiddleware.js +11 -27
  72. package/dist/node/vite/shared/findPageFiles.d.ts +1 -1
  73. package/dist/node/vite/shared/findPageFiles.js +1 -11
  74. package/dist/node/vite/shared/getAssetsDir.d.ts +3 -2
  75. package/dist/node/vite/shared/getAssetsDir.js +3 -3
  76. package/dist/node/vite/shared/isViteCli.d.ts +3 -3
  77. package/dist/node/vite/shared/isViteCli.js +80 -84
  78. package/dist/node/vite/shared/isViteServerSide.js +2 -7
  79. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +6 -4
  80. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +17 -6
  81. package/dist/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +9 -2
  82. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +5 -1
  83. package/dist/node/vite/shared/resolveVikeConfigInternal.js +86 -13
  84. package/dist/server/__internal/fetch-deprecated.d.ts +2 -0
  85. package/dist/server/__internal/fetch-deprecated.js +6 -0
  86. package/dist/server/__internal/fetch.d.ts +9 -0
  87. package/dist/server/__internal/fetch.js +5 -0
  88. package/dist/server/__internal/index.d.ts +4 -0
  89. package/dist/server/__internal/index.js +8 -0
  90. package/dist/server/createPageRenderer.d.ts +2 -2
  91. package/dist/server/createPageRenderer.js +2 -2
  92. package/dist/server/runtime/createDevMiddleware.js +3 -1
  93. package/dist/server/runtime/globalContext.d.ts +69 -10
  94. package/dist/server/runtime/globalContext.js +35 -2
  95. package/dist/server/runtime/index.d.ts +1 -1
  96. package/dist/server/runtime/index.js +1 -1
  97. package/dist/server/runtime/renderPageServer/analyzePage.js +3 -3
  98. package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +20 -9
  99. package/dist/server/runtime/renderPageServer/createHttpResponse.js +34 -21
  100. package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +13 -23
  101. package/dist/server/runtime/renderPageServer/csp.d.ts +2 -1
  102. package/dist/server/runtime/renderPageServer/csp.js +2 -1
  103. package/dist/server/runtime/renderPageServer/execHookOnError.js +1 -1
  104. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.d.ts +9 -0
  105. package/dist/server/runtime/renderPageServer/execHookOnRenderHtml.js +21 -9
  106. package/dist/server/runtime/renderPageServer/getHttpResponseBody.d.ts +2 -2
  107. package/dist/server/runtime/renderPageServer/getHttpResponseBody.js +19 -12
  108. package/dist/server/runtime/renderPageServer/getPageContextJson.d.ts +8 -0
  109. package/dist/server/runtime/renderPageServer/getPageContextJson.js +47 -0
  110. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +2 -0
  111. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +1 -1
  112. package/dist/server/runtime/renderPageServer/handlePageContextRequestUrl.js +2 -2
  113. package/dist/server/runtime/renderPageServer/headersResponse.d.ts +11 -2
  114. package/dist/server/runtime/renderPageServer/headersResponse.js +22 -2
  115. package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +5 -4
  116. package/dist/server/runtime/renderPageServer/html/injectAssets.d.ts +3 -2
  117. package/dist/server/runtime/renderPageServer/html/injectAssets.js +7 -1
  118. package/dist/server/runtime/renderPageServer/html/renderHtml.js +4 -2
  119. package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +5 -1
  120. package/dist/server/runtime/renderPageServer/html/serializeContext.js +12 -9
  121. package/dist/server/runtime/renderPageServer/html/stream.d.ts +13 -6
  122. package/dist/server/runtime/renderPageServer/html/stream.js +135 -32
  123. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.d.ts +30 -0
  124. package/dist/server/runtime/renderPageServer/html/streamedValuesHtml.js +92 -0
  125. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +10 -14
  126. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.js +5 -1
  127. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.d.ts +15 -0
  128. package/dist/server/runtime/renderPageServer/loadPageContextEnvironments.js +61 -0
  129. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +320 -55
  130. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +21 -12
  131. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.d.ts +4 -0
  132. package/dist/server/runtime/renderPageServer/streamedValues/asyncIterable.js +12 -0
  133. package/dist/server/runtime/renderPageServer/streamedValues/lines.d.ts +10 -0
  134. package/dist/server/runtime/renderPageServer/streamedValues/lines.js +49 -0
  135. package/dist/server/runtime/renderPageServer/streamedValues/promise.d.ts +4 -0
  136. package/dist/server/runtime/renderPageServer/streamedValues/promise.js +14 -0
  137. package/dist/server/runtime/renderPageServer/streamedValues/pump.d.ts +10 -0
  138. package/dist/server/runtime/renderPageServer/streamedValues/pump.js +67 -0
  139. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.d.ts +4 -0
  140. package/dist/server/runtime/renderPageServer/streamedValues/readableStream.js +12 -0
  141. package/dist/server/runtime/renderPageServer/streamedValues/registry.d.ts +28 -0
  142. package/dist/server/runtime/renderPageServer/streamedValues/registry.js +33 -0
  143. package/dist/server/runtime/renderPageServer.d.ts +65 -18
  144. package/dist/server/runtime/renderPageServer.js +33 -62
  145. package/dist/server/runtime/universal-middleware/core.d.ts +25 -0
  146. package/dist/server/runtime/universal-middleware/core.js +167 -0
  147. package/dist/server/runtime/universal-middleware/deprecated-export.d.ts +3 -0
  148. package/dist/server/runtime/universal-middleware/deprecated-export.js +10 -0
  149. package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.d.ts +15 -0
  150. package/dist/server/runtime/universal-middleware/getMiddlewaresPipe.js +51 -0
  151. package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.d.ts +9 -0
  152. package/dist/server/runtime/universal-middleware/vikeUniversalMiddleware.js +22 -0
  153. package/dist/shared-server-client/createGlobalContextShared.d.ts +8 -0
  154. package/dist/shared-server-client/createGlobalContextShared.js +2 -1
  155. package/dist/shared-server-client/getPageContextPublicShared.js +1 -3
  156. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.d.ts +8 -0
  157. package/dist/shared-server-client/getPageFiles/parseVirtualFileExportsGlobalEntry.js +17 -7
  158. package/dist/shared-server-client/hooks/execHook.d.ts +1 -1
  159. package/dist/shared-server-client/hooks/execHook.js +2 -2
  160. package/dist/shared-server-client/page-configs/serialize/serializeConfigValues.js +2 -0
  161. package/dist/shared-server-client/route/abort.d.ts +1 -1
  162. package/dist/shared-server-client/route/abort.js +4 -2
  163. package/dist/shared-server-client/streamedValues.d.ts +22 -0
  164. package/dist/shared-server-client/streamedValues.js +24 -0
  165. package/dist/shared-server-node/vike-environments.d.ts +4 -0
  166. package/dist/shared-server-node/vike-environments.js +10 -0
  167. package/dist/shared-server-node/virtualFileId.d.ts +7 -5
  168. package/dist/shared-server-node/virtualFileId.js +42 -42
  169. package/dist/types/Config.d.ts +11 -3
  170. package/dist/types/GlobalContext.d.ts +3 -3
  171. package/dist/types/PageConfig.d.ts +13 -5
  172. package/dist/types/PageContext.d.ts +18 -10
  173. package/dist/types/PageContext.js +1 -0
  174. package/dist/types/Server.d.ts +1 -1
  175. package/dist/types/VikeNamespace.d.ts +1 -1
  176. package/dist/types/index.d.ts +1 -0
  177. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  178. package/dist/utils/PROJECT_VERSION.js +1 -1
  179. package/dist/utils/assertViteVersion.d.ts +1 -3
  180. package/dist/utils/assertViteVersion.js +6 -9
  181. package/dist/utils/catchInfiniteLoop.js +33 -11
  182. package/dist/utils/deepEqual.d.ts +2 -1
  183. package/dist/utils/deepEqual.js +21 -6
  184. package/dist/utils/getContentTypeFromUrl.d.ts +2 -0
  185. package/dist/utils/getContentTypeFromUrl.js +39 -0
  186. package/dist/utils/injectRollupInputs.d.ts +2 -2
  187. package/dist/utils/injectRollupInputs.js +2 -2
  188. package/dist/utils/installUncaughtErrorHandlers.js +9 -0
  189. package/dist/utils/isDev.js +2 -7
  190. package/dist/utils/parseUrl-extras.js +4 -0
  191. package/fetch.js +2 -2
  192. package/modifyUrl.js +2 -2
  193. package/package.json +42 -26
  194. package/routing.js +2 -2
  195. package/universal-middleware.js +2 -2
  196. package/vike-server.d.ts +14 -0
  197. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.d.ts +0 -4
  198. package/dist/node/vite/plugins/pluginUniversalDeploy/pluginUnwrapProdOptions.js +0 -22
  199. package/dist/server/runtime/fetch.d.ts +0 -10
  200. package/dist/server/runtime/fetch.js +0 -5
  201. package/dist/server/runtime/universal-middleware.d.ts +0 -10
  202. package/dist/server/runtime/universal-middleware.js +0 -27
  203. package/dist/shared-server-client/addIs404ToPageProps.d.ts +0 -2
  204. package/dist/shared-server-client/addIs404ToPageProps.js +0 -17
@@ -21,6 +21,7 @@ import { preservePropertyGetters } from '../../utils/preservePropertyGetters.js'
21
21
  import { assertPosixPath } from '../../utils/path.js';
22
22
  import { urlToFile } from '../../utils/urlToFile.js';
23
23
  import { prependBase } from '../../utils/parseUrl-extras.js';
24
+ import { parseUrl } from '../../utils/parseUrl.js';
24
25
  import { prerenderPage } from '../../server/runtime/renderPageServer/renderPageServerAfterRoute.js';
25
26
  import { createPageContextServer } from '../../server/runtime/renderPageServer/createPageContextServer.js';
26
27
  import pc from '@brillout/picocolors';
@@ -43,6 +44,8 @@ import { resolvePrerenderConfigGlobal, resolvePrerenderConfigLocal, isDistServer
43
44
  import { getOutDirsAllFromRootNormalized } from '../vite/shared/getOutDirs.js';
44
45
  import fs from 'node:fs';
45
46
  import { getPublicProxy } from '../../shared-server-client/getPublicProxy.js';
47
+ import { getPageContextPublicServer } from '../../server/runtime/renderPageServer/getPageContextPublicServer.js';
48
+ import { isObject } from '../../utils/isObject.js';
46
49
  import { getStaticRedirectsForPrerender } from '../../server/runtime/renderPageServer/resolveRedirects.js';
47
50
  import { updateType } from '../../utils/updateType.js';
48
51
  const docLink = 'https://vike.dev/i18n#pre-rendering';
@@ -139,7 +142,7 @@ async function runPrerender(options = {}, trigger) {
139
142
  const prerenderContextPublic = getPrerenderContextPublic(prerenderContext);
140
143
  objectAssign(vikeConfig.prerenderContext, prerenderContextPublic, true);
141
144
  setGlobalContext_prerenderContext(prerenderContextPublic);
142
- if (isDistServerRemoved(prerenderConfigGlobal)) {
145
+ if (isDistServerRemoved(prerenderConfigGlobal, vikeConfig)) {
143
146
  fs.rmSync(outDirServer, { recursive: true });
144
147
  }
145
148
  }
@@ -482,6 +485,7 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext, concurr
482
485
  });
483
486
  const prerenderContextPublic = getPrerenderContextPublic(prerenderContext);
484
487
  let result = await execHookSingleWithoutPageContext(onPrerenderStartHook, globalContext, () => hookFn(prerenderContextPublic));
488
+ prerenderContext.pageContexts = prerenderContext.pageContexts.map(getPageContextOriginal);
485
489
  // Before applying result
486
490
  prerenderContext.pageContexts.forEach((pageContext) => {
487
491
  ;
@@ -507,7 +511,7 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext, concurr
507
511
  assertUsage(isObjectWithKeys(result, ['prerenderContext']) &&
508
512
  hasProp(result, 'prerenderContext', 'object') &&
509
513
  hasProp(result.prerenderContext, 'pageContexts', 'array'), rightUsage);
510
- prerenderContext.pageContexts = result.prerenderContext.pageContexts;
514
+ prerenderContext.pageContexts = result.prerenderContext.pageContexts.map(getPageContextOriginal);
511
515
  prerenderContext.pageContexts.forEach((pageContext) => {
512
516
  // TO-DO/next-major-release: remove
513
517
  if (pageContext.url && !isPropertyGetter(pageContext, 'url')) {
@@ -546,11 +550,12 @@ async function prerenderPages(prerenderContext, concurrencyLimit, onComplete) {
546
550
  assertIsNotAbort(err, pc.cyan(pageContextBeforeRender.urlOriginal));
547
551
  throw err;
548
552
  }
549
- const { documentHtml, pageContext } = res;
553
+ const { documentHtml, content, pageContext } = res;
550
554
  const pageContextSerialized = pageContext.is404 ? null : res.pageContextSerialized;
551
555
  await onComplete({
552
556
  pageContext,
553
557
  htmlString: documentHtml,
558
+ content,
554
559
  pageContextSerialized,
555
560
  });
556
561
  })));
@@ -579,7 +584,13 @@ async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPre
579
584
  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 });
580
585
  });
581
586
  }
582
- async function writeFiles({ pageContext, htmlString, pageContextSerialized }, prerenderContext, onPagePrerender, logLevel) {
587
+ async function writeFiles({ pageContext, htmlString, content, pageContextSerialized }, prerenderContext, onPagePrerender, logLevel) {
588
+ if (content !== null) {
589
+ assert(htmlString === null && pageContextSerialized === null);
590
+ await write(pageContext, 'CONTENT', content, onPagePrerender, prerenderContext, logLevel);
591
+ return;
592
+ }
593
+ assert(htmlString !== null);
583
594
  const writeJobs = [write(pageContext, 'HTML', htmlString, onPagePrerender, prerenderContext, logLevel)];
584
595
  if (pageContextSerialized !== null) {
585
596
  writeJobs.push(write(pageContext, 'JSON', pageContextSerialized, onPagePrerender, prerenderContext, logLevel));
@@ -594,10 +605,13 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
594
605
  const doNotCreateExtraDirectory = prerenderContext._noExtraDir ?? pageContext.is404;
595
606
  fileUrl = urlToFile(urlOriginal, '.html', doNotCreateExtraDirectory);
596
607
  }
597
- else {
598
- assert(fileType === 'JSON');
608
+ else if (fileType === 'JSON') {
599
609
  fileUrl = getPageContextRequestUrl(urlOriginal);
600
610
  }
611
+ else {
612
+ assert(fileType === 'CONTENT');
613
+ fileUrl = getContentFileUrl(pageContext);
614
+ }
601
615
  assertPosixPath(fileUrl);
602
616
  assert(fileUrl.startsWith('/'));
603
617
  const filePathRelative = fileUrl.slice(1);
@@ -614,14 +628,15 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
614
628
  fileContent,
615
629
  },
616
630
  });
617
- prerenderContext.output.push({
618
- filePath,
619
- fileType,
620
- fileContent,
621
- pageContext,
622
- });
631
+ if (fileType === 'CONTENT') {
632
+ prerenderContext.output.push({ filePath, fileType, fileContent, pageContext });
633
+ }
634
+ else {
635
+ assert(typeof fileContent === 'string');
636
+ prerenderContext.output.push({ filePath, fileType, fileContent, pageContext });
637
+ }
623
638
  if (onPagePrerender) {
624
- await onPagePrerender(pageContext);
639
+ await onPagePrerender(getPageContextPublicPrerendered(pageContext));
625
640
  }
626
641
  else {
627
642
  const { promises } = await import('node:fs');
@@ -640,6 +655,18 @@ async function write(pageContext, fileType, fileContent, onPagePrerender, preren
640
655
  }
641
656
  }
642
657
  }
658
+ // With `pageContext.content` the URL is the file path: `/feed.atom` => `dist/client/feed.atom`
659
+ function getContentFileUrl(pageContext) {
660
+ const { urlOriginal } = pageContext;
661
+ // The query string and the hash are ignored: a static host serves the file at the pathname
662
+ const { pathnameOriginal } = parseUrl(urlOriginal, '/');
663
+ const errPrefix = `Cannot pre-render ${pc.cyan(urlOriginal)} with ${pc.code('pageContext.content')}`;
664
+ const errSuffix = "pre-rendering writes the content to the file at the URL's pathname (e.g. /feed.atom => dist/client/feed.atom)";
665
+ assertUsage(!pageContext.is404, `${errPrefix} because it's the 404 page`);
666
+ const segments = pathnameOriginal.split('/').slice(1);
667
+ assertUsage(segments.every((s) => s !== '' && s !== '.' && s !== '..'), `${errPrefix} because the URL's pathname isn't a file path: ${errSuffix}`);
668
+ return pathnameOriginal;
669
+ }
643
670
  function normalizeOnPrerenderHookResult(prerenderResult, prerenderHookFile, hookName) {
644
671
  if (isArray(prerenderResult)) {
645
672
  return prerenderResult.map(normalize);
@@ -730,14 +757,31 @@ function getPrerenderContextPublic(prerenderContext) {
730
757
  configurable: true,
731
758
  });
732
759
  }
733
- // Required because of https://vike.dev/i18n#pre-rendering
734
- // - Thus, we have to let users access the original pageContext object => we cannot use ES proxies and we cannot use getPageContextPublicShared()
735
- prerenderContext.pageContexts.forEach((pageContext) => {
760
+ prerenderContext.pageContexts = prerenderContext.pageContexts.map((pageContext) => {
761
+ // Required because of https://vike.dev/i18n#pre-rendering
762
+ // - Users copy pageContext, e.g. `{ ...pageContext, locale }`, and Vike renders the copies => the copies need to be original objects
736
763
  changeEnumerable(pageContext, '_isOriginalObject', true);
764
+ return getPageContextPublicServer(pageContext);
765
+ });
766
+ prerenderContext.output.forEach((file) => {
767
+ file.pageContext = getPageContextPublicPrerendered(file.pageContext);
737
768
  });
738
769
  const prerenderContextPublic = getPublicProxy(prerenderContext, 'prerenderContext');
739
770
  return prerenderContextPublic;
740
771
  }
772
+ // The user may return the public pageContext objects passed to +onPrerenderStart
773
+ function getPageContextOriginal(pageContext) {
774
+ const obj = pageContext;
775
+ if (isObject(obj) && obj._isProxyObject)
776
+ return obj._originalObject;
777
+ return pageContext;
778
+ }
779
+ function getPageContextPublicPrerendered(pageContext) {
780
+ // Pre-rendered redirects don't have any real pageContext object, but only a plain object `{ urlOriginal, pageId: null, is404: false, isRedirect: true }` which we cannot pass to getPageContextPublicServer() as it only accepts real pageContext objects (it asserts pageContext._isOriginalObject)
781
+ if (pageContext.isRedirect)
782
+ return pageContext;
783
+ return getPageContextPublicServer(pageContext);
784
+ }
741
785
  async function prerenderRedirects(globalContext, onComplete, showWarningUponDynamicRedirects) {
742
786
  const redirects = globalContext.config.redirects ?? [];
743
787
  const redirectsStatic = getStaticRedirectsForPrerender(redirects, showWarningUponDynamicRedirects);
@@ -748,6 +792,7 @@ async function prerenderRedirects(globalContext, onComplete, showWarningUponDyna
748
792
  await onComplete({
749
793
  pageContext: { urlOriginal, pageId: null, is404: false, isRedirect: true },
750
794
  htmlString,
795
+ content: null,
751
796
  pageContextSerialized: null,
752
797
  });
753
798
  }
@@ -11,7 +11,7 @@ function assertEnvVite() {
11
11
  markSetup_vikeVitePlugin();
12
12
  assertIsNotBrowser();
13
13
  assertNodeVersion();
14
- assertViteVersion(viteVersion);
14
+ assertViteVersion(viteVersion); // Early check — more reliable check using `this.meta.viteVersion` later
15
15
  assertIsNotProductionRuntime(); // Don't bloat server with heavy dependencies like Vite
16
16
  }
17
17
  function onLoad() {
@@ -32,6 +32,7 @@ import { pluginSuppressRollupWarning } from './plugins/build/pluginSuppressRollu
32
32
  import { pluginDistFileNames } from './plugins/build/pluginDistFileNames.js';
33
33
  import { pluginProdBuildEntry } from './plugins/build/pluginProdBuildEntry.js';
34
34
  import { pluginBuildConfig } from './plugins/build/pluginBuildConfig.js';
35
+ import { pluginEnvironmentEntries } from './plugins/build/pluginEnvironmentEntries.js';
35
36
  import { pluginModuleBanner } from './plugins/build/pluginModuleBanner.js';
36
37
  import { pluginReplaceConstantsNonRunnableDev } from './plugins/non-runnable-dev/pluginReplaceConstantsNonRunnableDev.js';
37
38
  import { isVikeCliOrApi } from '../../shared-server-node/api-context.js';
@@ -83,6 +84,7 @@ function plugin(vikeVitePluginOptions = {}) {
83
84
  function pluginBuild() {
84
85
  return [
85
86
  ...pluginBuildConfig(),
87
+ ...pluginEnvironmentEntries(),
86
88
  ...pluginBuildApp(),
87
89
  ...pluginProdBuildEntry(),
88
90
  ...pluginDistPackageJsonFile(),
@@ -45,7 +45,7 @@ async function fixServerAssets(config) {
45
45
  }
46
46
  async function copyAssets(filesToMove, filesToRemove, config) {
47
47
  const { outDirClient, outDirServer } = getOutDirs(config, undefined);
48
- const assetsDir = getAssetsDir(config);
48
+ const assetsDir = getAssetsDir(config.environments.ssr.build);
49
49
  const assetsDirServer = path.posix.join(outDirServer, assetsDir);
50
50
  if (!filesToMove.length && !filesToRemove.length && !existsSync(assetsDirServer))
51
51
  return;
@@ -180,7 +180,11 @@ function getPageId(key) {
180
180
  // to:
181
181
  // virtual:vike:page-entry:client:/pages/index
182
182
  // (This seems to be needed only for vitest tests that use Vite's build() API with an inline config.)
183
- key = key.substring(key.indexOf('virtual:vike'));
183
+ const prefix = key.split('virtual:vike')[0];
184
+ // Skip virtual modules wrapping a Vike virtual module, e.g. virtual:vite-rsc/client-references/group/facade:virtual:vike:page-entry:client:/pages/index
185
+ if (prefix && !prefix.endsWith('/'))
186
+ return null;
187
+ key = key.substring(prefix.length);
184
188
  const result = parseVirtualFileId(key);
185
189
  return result && result.type === 'page-entry' ? result.pageId : null;
186
190
  }
@@ -5,14 +5,12 @@ import { assert, assertWarning } from '../../../../utils/assert.js';
5
5
  import { onSetupBuild } from '../../../../utils/assertSetup.js';
6
6
  import { getGlobalObject } from '../../../../utils/getGlobalObject.js';
7
7
  import { isPrerenderAutoRunEnabled, wasPrerenderRun } from '../../../prerender/context.js';
8
- import { isViteCli, getViteBuildCliArgs } from '../../shared/isViteCli.js';
8
+ import { isViteCli, getViteCliArgs } from '../../shared/isViteCli.js';
9
9
  import pc from '@brillout/picocolors';
10
10
  import { getVikeConfigInternal } from '../../shared/resolveVikeConfigInternal.js';
11
11
  import { isVikeCliOrApi } from '../../../../shared-server-node/api-context.js';
12
12
  import { handleAssetsManifest, handleAssetsManifest_assertUsageCssTarget } from './handleAssetsManifest.js';
13
- import { isViteServerSide_onlySsrEnv } from '../../shared/isViteServerSide.js';
14
13
  import { runPrerenderFromAutoRun } from '../../../prerender/runPrerenderEntry.js';
15
- import { getManifestFilePathRelative } from '../../shared/getManifestFilePathRelative.js';
16
14
  import { logErrorServer } from '../../../../server/runtime/logErrorServer.js';
17
15
  import '../../assertEnvVite.js';
18
16
  const globalObject = getGlobalObject('build/pluginBuildApp.ts', {
@@ -20,7 +18,6 @@ const globalObject = getGlobalObject('build/pluginBuildApp.ts', {
20
18
  });
21
19
  function pluginBuildApp() {
22
20
  let config;
23
- let alreadyBuilt = false;
24
21
  return [
25
22
  {
26
23
  name: 'vike:build:pluginBuildApp:pre',
@@ -33,18 +30,15 @@ function pluginBuildApp() {
33
30
  builder: {
34
31
  // Can be overridden by another plugin e.g vike-vercel https://github.com/vikejs/vike/pull/2184#issuecomment-2659425195
35
32
  async buildApp(builder) {
36
- if (alreadyBuilt)
37
- return;
38
- alreadyBuilt = true;
39
33
  assert(builder.environments.client);
40
34
  assert(builder.environments.ssr);
35
+ // The additional environments (e.g. `rsc`)
36
+ const { _additionalEnvironmentNames: additionalEnvironmentNames } = await getVikeConfigInternal();
37
+ for (const name of additionalEnvironmentNames) {
38
+ await builder.build(builder.environments[name]);
39
+ }
41
40
  await builder.build(builder.environments.client);
42
41
  await builder.build(builder.environments.ssr);
43
- if (isPrerenderForceExit()) {
44
- await builder.buildApp();
45
- runPrerender_forceExit();
46
- assert(false);
47
- }
48
42
  },
49
43
  },
50
44
  };
@@ -88,8 +82,14 @@ function pluginBuildApp() {
88
82
  await abortViteBuildSsr();
89
83
  },
90
84
  },
91
- // TO-DO/eventually: stop using this writeBundle() hack and, instead, use the buildApp() implementation above.
92
- // - Could it cause issues if a tool uses the writeBundle() hack together with getVikeConfig() ?
85
+ // Pre-render after all builds, e.g. after @vitejs/plugin-rsc moved its `rsc` build back into dist/server/
86
+ // - Before the `order: 'post'` buildApp() hooks of non-`enforce: 'pre'` plugins, e.g. vite-plugin-vercel copies dist/client/
87
+ buildApp: {
88
+ order: 'post',
89
+ async handler(builder) {
90
+ await triggerPrerendering(builder.config);
91
+ },
92
+ },
93
93
  writeBundle: {
94
94
  /* We can't use this because it breaks Vite's logging. TO-DO/eventually: try again with latest Vite version.
95
95
  sequential: true,
@@ -99,7 +99,6 @@ function pluginBuildApp() {
99
99
  try {
100
100
  handleAssetsManifest_assertUsageCssTarget(config, this.environment);
101
101
  await handleAssetsManifest(config, this.environment, options, bundle);
102
- await triggerPrerendering(config, this.environment, bundle);
103
102
  }
104
103
  catch (err) {
105
104
  // We use try-catch also because:
@@ -115,6 +114,14 @@ function pluginBuildApp() {
115
114
  name: 'vike:build:pluginBuildApp:autoFullBuild:post',
116
115
  apply: 'build',
117
116
  enforce: 'post',
117
+ // After the buildApp() hooks of other plugins, e.g. vite-plugin-vercel
118
+ buildApp: {
119
+ order: 'post',
120
+ async handler() {
121
+ if (isPrerenderForceExit())
122
+ runPrerender_forceExit();
123
+ },
124
+ },
118
125
  closeBundle: {
119
126
  sequential: true,
120
127
  order: 'post',
@@ -125,18 +132,10 @@ function pluginBuildApp() {
125
132
  },
126
133
  ];
127
134
  }
128
- async function triggerPrerendering(config, viteEnv, bundle) {
135
+ async function triggerPrerendering(config) {
129
136
  const vikeConfig = await getVikeConfigInternal();
130
- if (!isViteServerSide_onlySsrEnv(config, viteEnv))
131
- return;
132
137
  if (isDisabled(vikeConfig))
133
138
  return;
134
- // Workaround for @vitejs/plugin-legacy
135
- // - The legacy plugin triggers its own Rollup build for the client-side.
136
- // - The legacy plugin doesn't generate a manifest => we can use that to detect the legacy plugin build.
137
- // - Issue & reproduction: https://github.com/vikejs/vike/issues/1154#issuecomment-1965954636
138
- if (!bundle[getManifestFilePathRelative(config.build.manifest)])
139
- return;
140
139
  if (!(await isPrerenderAutoRunEnabled(vikeConfig)))
141
140
  return;
142
141
  const configInline = getFullBuildInlineConfig(config);
@@ -146,7 +145,7 @@ async function triggerPrerendering(config, viteEnv, bundle) {
146
145
  }
147
146
  async function abortViteBuildSsr() {
148
147
  const vikeConfig = await getVikeConfigInternal();
149
- if (vikeConfig.config.disableAutoFullBuild !== true && isViteCli() && getViteBuildCliArgs()?.build.ssr) {
148
+ if (vikeConfig.config.disableAutoFullBuild !== true && isViteCli() && getViteCliArgs()?.build.ssr) {
150
149
  assertWarning(false, `The CLI call ${pc.cyan('$ vite build --ssr')} is superfluous since ${pc.cyan('$ vite build')} also builds the server-side. If you want two separate build steps then use https://vike.dev/disableAutoFullBuild or use Vite's ${pc.cyan('build()')} API.`, { onlyOnce: true });
151
150
  process.exit(0);
152
151
  }
@@ -165,7 +164,7 @@ function isPrerenderForceExit() {
165
164
  return globalObject.forceExit;
166
165
  }
167
166
  function getFullBuildInlineConfig(config) {
168
- const configFromCli = !isViteCli() ? null : getViteBuildCliArgs();
167
+ const configFromCli = !isViteCli() ? null : getViteCliArgs();
169
168
  if (config._viteConfigUser) {
170
169
  return config._viteConfigUser;
171
170
  }
@@ -1,7 +1,7 @@
1
1
  export { pluginBuildConfig };
2
2
  export { assertRollupInput };
3
3
  export { analyzeClientEntries };
4
- import type { ResolvedConfig, Plugin } from 'vite';
4
+ import type { ResolvedConfig, Plugin, Rollup } from 'vite';
5
5
  import type { PageConfigBuildTime } from '../../../../types/PageConfig.js';
6
6
  import type { FilePath } from '../../../../types/FilePath.js';
7
7
  import '../../assertEnvVite.js';
@@ -15,4 +15,4 @@ declare function analyzeClientEntries(pageConfigs: PageConfigBuildTime[], config
15
15
  hasServerRouting: boolean;
16
16
  clientEntries: Record<string, ClientEntry>;
17
17
  };
18
- declare function assertRollupInput(config: ResolvedConfig): void;
18
+ declare function assertRollupInput(input: Rollup.InputOption | undefined): void;
@@ -16,7 +16,7 @@ import { extractAssetsAddQuery } from '../../../../shared-server-node/extractAss
16
16
  import { prependEntriesDir } from '../../../../shared-server-node/prependEntriesDir.js';
17
17
  import { getFilePathResolved, getFilePathUnresolved } from '../../shared/getFilePath.js';
18
18
  import { getConfigValueBuildTime } from '../../../../shared-server-client/page-configs/getConfigValueBuildTime.js';
19
- import { isViteServerSide_viteEnvOptional } from '../../shared/isViteServerSide.js';
19
+ import { isViteServerSide_configEnvironment } from '../../shared/isViteServerSide.js';
20
20
  import { handleAssetsManifest_assertUsageCssCodeSplit, handleAssetsManifest_getBuildConfig, handleAssetsManifest_alignCssTarget, } from './handleAssetsManifest.js';
21
21
  import { resolveIncludeAssetsImportedByServer } from '../../../../server/runtime/renderPageServer/getPageAssets/retrievePageAssetsProd.js';
22
22
  import '../../assertEnvVite.js';
@@ -31,10 +31,18 @@ function pluginBuildConfig() {
31
31
  async handler(config) {
32
32
  handleAssetsManifest_alignCssTarget(config);
33
33
  onSetupBuild();
34
- assertRollupInput(config);
35
- const entries = await getEntries(config);
36
- assert(Object.keys(entries).length > 0);
37
- config.build.rollupOptions.input = injectRollupInputs(entries, config);
34
+ const { _additionalEnvironmentNames: additionalEnvironmentNames } = await getVikeConfigInternal();
35
+ const entriesClient = await getEntries(config, false);
36
+ const entriesServer = await getEntries(config, true);
37
+ for (const [envName, envConfig] of Object.entries(config.environments)) {
38
+ // Additional environments (e.g. `rsc`) only get Vike's `entry-environment.mjs`, see pluginEnvironmentEntries.ts
39
+ if (additionalEnvironmentNames.includes(envName))
40
+ continue;
41
+ const entries = isViteServerSide_configEnvironment(envName, envConfig) ? entriesServer : entriesClient;
42
+ assert(Object.keys(entries).length > 0);
43
+ assertRollupInput(envConfig.build.rollupOptions.input);
44
+ envConfig.build.rollupOptions.input = injectRollupInputs(entries, envConfig.build.rollupOptions.input);
45
+ }
38
46
  addLogHook();
39
47
  handleAssetsManifest_assertUsageCssCodeSplit(config);
40
48
  },
@@ -55,13 +63,13 @@ function pluginBuildConfig() {
55
63
  },
56
64
  ];
57
65
  }
58
- async function getEntries(config) {
66
+ async function getEntries(config, isServerSide) {
59
67
  const vikeConfig = await getVikeConfigInternal();
60
68
  const { _pageConfigs: pageConfigs } = vikeConfig;
61
69
  // TO-DO/next-major-release: remove
62
- const pageFileEntries = await getPageFileEntries(config, resolveIncludeAssetsImportedByServer(vikeConfig.config));
70
+ const pageFileEntries = await getPageFileEntries(config, resolveIncludeAssetsImportedByServer(vikeConfig.config), isServerSide);
63
71
  assertUsage(Object.keys(pageFileEntries).length !== 0 || pageConfigs.length !== 0, 'At least one page should be defined, see https://vike.dev/add');
64
- if (isViteServerSide_viteEnvOptional(config)) {
72
+ if (isServerSide) {
65
73
  const pageEntries = getPageEntries(pageConfigs);
66
74
  const entries = {
67
75
  ...pageFileEntries,
@@ -94,7 +102,7 @@ async function getEntries(config) {
94
102
  function getPageEntries(pageConfigs) {
95
103
  const pageEntries = {};
96
104
  pageConfigs.forEach((pageConfig) => {
97
- const { entryName, entryTarget } = getEntryFromPageConfig(pageConfig, false);
105
+ const { entryName, entryTarget } = getEntryFromPageConfig(pageConfig, 'server');
98
106
  pageEntries[entryName] = entryTarget;
99
107
  });
100
108
  return pageEntries;
@@ -114,7 +122,7 @@ function analyzeClientEntries(pageConfigs, config) {
114
122
  }
115
123
  {
116
124
  // Ensure Rollup generates a bundle per page: https://github.com/vikejs/vike/issues/349#issuecomment-1166247275
117
- const { entryName, entryTarget, entryFilePath } = getEntryFromPageConfig(pageConfig, true);
125
+ const { entryName, entryTarget, entryFilePath } = getEntryFromPageConfig(pageConfig, 'client');
118
126
  clientEntries[entryName] = { entryTarget, entryFilePath };
119
127
  }
120
128
  {
@@ -133,13 +141,13 @@ function analyzeClientEntries(pageConfigs, config) {
133
141
  }
134
142
  // Ensure Rollup creates entries for each page file, see https://github.com/vikejs/vike/issues/350
135
143
  // (Otherwise the page files may be missing in the client manifest.json)
136
- async function getPageFileEntries(config, includeAssetsImportedByServer) {
137
- const isForClientSide = !isViteServerSide_viteEnvOptional(config);
144
+ async function getPageFileEntries(config, includeAssetsImportedByServer, isServerSide) {
145
+ const isForClientSide = !isServerSide;
138
146
  const fileTypes = isForClientSide ? ['.page', '.page.client'] : ['.page', '.page.server'];
139
147
  if (isForClientSide && includeAssetsImportedByServer) {
140
148
  fileTypes.push('.page.server');
141
149
  }
142
- let pageFiles = await findPageFiles(config, fileTypes, false);
150
+ let pageFiles = await findPageFiles(config, fileTypes);
143
151
  const pageFileEntries = {};
144
152
  pageFiles = unique(pageFiles);
145
153
  pageFiles.forEach((pageFile) => {
@@ -177,9 +185,9 @@ function getEntryFromClientEntry(clientEntry, config, addExtractAssetsQuery) {
177
185
  entryName = prependEntriesDir(entryName);
178
186
  return { entryName, entryTarget, entryFilePath: filePath };
179
187
  }
180
- function getEntryFromPageConfig(pageConfig, isForClientSide) {
188
+ function getEntryFromPageConfig(pageConfig, environmentName) {
181
189
  let { pageId } = pageConfig;
182
- const entryTarget = generateVirtualFileId({ type: 'page-entry', pageId, isForClientSide });
190
+ const entryTarget = generateVirtualFileId({ type: 'page-entry', pageId, environmentName });
183
191
  let entryName = pageId;
184
192
  // Avoid:
185
193
  // ```
@@ -220,8 +228,8 @@ function addLogHook() {
220
228
  }
221
229
  });
222
230
  }
223
- function assertRollupInput(config) {
224
- const userInputs = normalizeRollupInput(config.build.rollupOptions.input);
231
+ function assertRollupInput(input) {
232
+ const userInputs = normalizeRollupInput(input);
225
233
  const htmlInputs = Object.values(userInputs).filter((entry) => entry.endsWith('.html') || entry.endsWith('.htm'));
226
234
  const htmlInput = htmlInputs[0];
227
235
  assertUsage(htmlInput === undefined, `The entry ${htmlInput} of config build.rollupOptions.input is an HTML entry which is forbidden when using Vike, instead follow https://vike.dev/add`);