vike 0.4.227-commit-e36b916 → 0.4.227-commit-710dcb6

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 (35) hide show
  1. package/dist/cjs/node/plugin/plugins/build/pluginBuildConfig.js +2 -2
  2. package/dist/cjs/node/plugin/plugins/build/pluginBuildEntry.js +2 -2
  3. package/dist/cjs/node/plugin/plugins/commonConfig.js +2 -1
  4. package/dist/cjs/node/plugin/plugins/devConfig/determineFsAllowList.js +2 -2
  5. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +2 -2
  6. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -0
  7. package/dist/cjs/node/plugin/shared/resolveClientEntriesDev.js +5 -7
  8. package/dist/cjs/node/prerender/runPrerender.js +168 -150
  9. package/dist/cjs/node/prerender/utils.js +1 -1
  10. package/dist/cjs/node/runtime/renderPage/analyzePage.js +1 -0
  11. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +0 -23
  12. package/dist/cjs/shared/route/index.js +13 -11
  13. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  14. package/dist/cjs/utils/findPackageJson.js +2 -2
  15. package/dist/cjs/utils/preservePropertyGetters.js +30 -0
  16. package/dist/cjs/utils/requireResolve.js +57 -13
  17. package/dist/esm/node/plugin/plugins/commonConfig.js +2 -1
  18. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -0
  19. package/dist/esm/node/plugin/shared/resolveClientEntriesDev.js +4 -6
  20. package/dist/esm/node/prerender/runPrerender.d.ts +2 -0
  21. package/dist/esm/node/prerender/runPrerender.js +171 -153
  22. package/dist/esm/node/prerender/utils.d.ts +1 -1
  23. package/dist/esm/node/prerender/utils.js +1 -1
  24. package/dist/esm/node/runtime/renderPage/analyzePage.js +1 -0
  25. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +0 -182
  26. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +0 -23
  27. package/dist/esm/shared/route/index.d.ts +1 -1
  28. package/dist/esm/shared/route/index.js +13 -11
  29. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  30. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  31. package/dist/esm/utils/preservePropertyGetters.d.ts +2 -0
  32. package/dist/esm/utils/preservePropertyGetters.js +28 -0
  33. package/dist/esm/utils/requireResolve.d.ts +4 -0
  34. package/dist/esm/utils/requireResolve.js +51 -10
  35. package/package.json +1 -1
@@ -16,8 +16,8 @@ const getConfigValueBuildTime_js_1 = require("../../../../shared/page-configs/ge
16
16
  const isViteServerBuild_js_1 = require("../../shared/isViteServerBuild.js");
17
17
  const getOutDirs_js_1 = require("../../shared/getOutDirs.js");
18
18
  const handleAssetsManifest_js_1 = require("./handleAssetsManifest.js");
19
- // @ts-ignore `file://${__filename}` is shimmed at dist/cjs by dist-cjs-fixup.js.
20
- const importMetaUrl = `file://${__filename}`;
19
+ // @ts-ignore `file://${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js.
20
+ const importMetaUrl = `file://${__filename.split('\\').join('/')}`;
21
21
  const require_ = (0, module_1.createRequire)(importMetaUrl);
22
22
  const manifestTempFile = '_temp_manifest.json';
23
23
  exports.manifestTempFile = manifestTempFile;
@@ -11,8 +11,8 @@ const utils_js_1 = require("../../utils.js");
11
11
  const promises_1 = __importDefault(require("fs/promises"));
12
12
  const path_1 = __importDefault(require("path"));
13
13
  const module_1 = require("module");
14
- // @ts-ignore `file://${__filename}` is shimmed at dist/cjs by dist-cjs-fixup.js.
15
- const importMetaUrl = `file://${__filename}`;
14
+ // @ts-ignore `file://${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js.
15
+ const importMetaUrl = `file://${__filename.split('\\').join('/')}`;
16
16
  const require_ = (0, module_1.createRequire)(importMetaUrl);
17
17
  const extractExportNamesPlugin_js_1 = require("../extractExportNamesPlugin.js");
18
18
  const globalContext_js_1 = require("../../../runtime/globalContext.js");
@@ -38,7 +38,8 @@ function commonConfig(vikeVitePluginOptions) {
38
38
  isPrerenderingEnabled,
39
39
  isPrerenderingEnabledForAllPages,
40
40
  output: null,
41
- pageContexts: null
41
+ pageContexts: null,
42
+ pageContexts404: null
42
43
  });
43
44
  (0, utils_js_1.assert)(prerenderContext.isPrerenderingEnabled === isPrerenderingEnabled);
44
45
  (0, utils_js_1.assert)(prerenderContext.isPrerenderingEnabledForAllPages === isPrerenderingEnabledForAllPages);
@@ -10,8 +10,8 @@ const utils_js_1 = require("../../utils.js");
10
10
  const module_1 = require("module");
11
11
  const path_2 = require("path");
12
12
  const url_1 = require("url");
13
- // @ts-ignore `file://${__filename}` is shimmed at dist/cjs by dist-cjs-fixup.js.
14
- const importMetaUrl = `file://${__filename}`;
13
+ // @ts-ignore `file://${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js.
14
+ const importMetaUrl = `file://${__filename.split('\\').join('/')}`;
15
15
  const require_ = (0, module_1.createRequire)(importMetaUrl);
16
16
  const __dirname_ = (0, path_2.dirname)((0, url_1.fileURLToPath)(importMetaUrl));
17
17
  async function determineFsAllowList(config) {
@@ -17,8 +17,8 @@ const transformPointerImports_js_1 = require("./transformPointerImports.js");
17
17
  const source_map_support_1 = __importDefault(require("source-map-support"));
18
18
  const getFilePath_js_1 = require("../../../../shared/getFilePath.js");
19
19
  const module_1 = require("module");
20
- // @ts-ignore `file://${__filename}` is shimmed at dist/cjs by dist-cjs-fixup.js.
21
- const importMetaUrl = `file://${__filename}`;
20
+ // @ts-ignore `file://${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js.
21
+ const importMetaUrl = `file://${__filename.split('\\').join('/')}`;
22
22
  const require_ = (0, module_1.createRequire)(importMetaUrl);
23
23
  (0, utils_js_1.assertIsNotProductionRuntime)();
24
24
  installSourceMapSupport();
@@ -573,6 +573,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
573
573
  // Defined over pointer import
574
574
  (0, utils_js_1.assert)(confVal.valueIsLoaded);
575
575
  const pointerImport = (0, resolvePointerImport_js_1.resolvePointerImport)(confVal.value, plusFile.filePath, userRootDir, configName);
576
+ console.log('pointerImport', pointerImport);
576
577
  const configDefinedAt = (0, getConfigDefinedAt_js_1.getConfigDefinedAt)('Config', configName, definedAtFilePath_);
577
578
  (0, utils_js_1.assertUsage)(pointerImport, `${configDefinedAt} should be an import`);
578
579
  valueFilePath = pointerImport.fileExportPath.filePathAbsoluteVite;
@@ -2,10 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveClientEntriesDev = resolveClientEntriesDev;
4
4
  const utils_js_1 = require("../utils.js");
5
- const module_1 = require("module");
6
- // @ts-ignore `file://${__filename}` is shimmed at dist/cjs by dist-cjs-fixup.js.
7
- const importMetaUrl = `file://${__filename}`;
8
- const require_ = (0, module_1.createRequire)(importMetaUrl);
5
+ // @ts-ignore `file://${__filename.split('\\').join('/')}` is shimmed at dist/cjs by dist-cjs-fixup.js.
6
+ const importMetaUrl = `file://${__filename.split('\\').join('/')}`;
9
7
  (0, utils_js_1.assertIsNotProductionRuntime)();
10
8
  async function resolveClientEntriesDev(clientEntry, viteDevServer) {
11
9
  let root = viteDevServer.config.root;
@@ -32,17 +30,17 @@ async function resolveClientEntriesDev(clientEntry, viteDevServer) {
32
30
  try {
33
31
  // For Vitest (which doesn't resolve vike to its dist but to its source files)
34
32
  // [RELATIVE_PATH_FROM_DIST] Current file: node_modules/vike/node/plugin/shared/resolveClientEntriesDev.js
35
- filePath = (0, utils_js_1.toPosixPath)(require_.resolve(clientEntry.replace('@@vike/dist/esm/client/', '../../../client/').replace('.js', '.ts')));
33
+ filePath = (0, utils_js_1.requireResolveInternal)(clientEntry.replace('@@vike/dist/esm/client/', '../../../client/').replace('.js', '.ts'), importMetaUrl);
36
34
  }
37
35
  catch {
38
36
  // For users
39
37
  // [RELATIVE_PATH_FROM_DIST] Current file: node_modules/vike/dist/esm/node/plugin/shared/resolveClientEntriesDev.js
40
- filePath = (0, utils_js_1.toPosixPath)(require_.resolve(clientEntry.replace('@@vike/dist/esm/client/', '../../../../../dist/esm/client/')));
38
+ filePath = (0, utils_js_1.requireResolveInternal)(clientEntry.replace('@@vike/dist/esm/client/', '../../../../../dist/esm/client/'), importMetaUrl);
41
39
  }
42
40
  }
43
41
  else {
44
42
  (0, utils_js_1.assertIsNpmPackageImport)(clientEntry);
45
- filePath = require_.resolve(clientEntry);
43
+ filePath = (0, utils_js_1.requireResolveExpected)(clientEntry, root);
46
44
  }
47
45
  }
48
46
  if (!filePath.startsWith('/')) {
@@ -54,7 +54,6 @@ const resolveRouteString_js_1 = require("../../shared/route/resolveRouteString.j
54
54
  const getConfigValueRuntime_js_1 = require("../../shared/page-configs/getConfigValueRuntime.js");
55
55
  const loadConfigValues_js_1 = require("../../shared/page-configs/loadConfigValues.js");
56
56
  const error_page_js_1 = require("../../shared/error-page.js");
57
- const getPageContextUrlComputed_js_1 = require("../../shared/getPageContextUrlComputed.js");
58
57
  const abort_js_1 = require("../../shared/route/abort.js");
59
58
  const loadUserFilesServerSide_js_1 = require("../runtime/renderPage/loadUserFilesServerSide.js");
60
59
  const getHook_js_1 = require("../../shared/hooks/getHook.js");
@@ -124,8 +123,7 @@ async function runPrerender(options = {}, standaloneTrigger) {
124
123
  const { partial, noExtraDir, parallel, defaultLocalValue, isPrerenderingEnabled } = prerenderConfigGlobal;
125
124
  if (!isPrerenderingEnabled) {
126
125
  (0, utils_js_1.assert)(standaloneTrigger);
127
- // TODO/now: make it assertUsage() and remove dist/server/entry.mjs if pre-rendering is completely disabled
128
- (0, utils_js_1.assertWarning)(false, `You're executing ${picocolors_1.default.cyan(standaloneTrigger)} but you didn't enable pre-rendering. Use the ${picocolors_1.default.cyan('prerender')} setting (${picocolors_1.default.underline('https://vike.dev/prerender')}) to enable pre-rendering for at least one page.`, { onlyOnce: true });
126
+ (0, utils_js_1.assertUsage)(false, `You're executing ${picocolors_1.default.cyan(standaloneTrigger)} but you didn't enable pre-rendering. Use the ${picocolors_1.default.cyan('prerender')} setting (${picocolors_1.default.underline('https://vike.dev/prerender')}) to enable pre-rendering for at least one page.`);
129
127
  }
130
128
  const concurrencyLimit = (0, utils_js_1.pLimit)(parallel === false || parallel === 0 ? 1 : parallel === true || parallel === undefined ? (0, os_1.cpus)().length : parallel);
131
129
  await (0, globalContext_js_1.initGlobalContext_runPrerender)();
@@ -134,27 +132,37 @@ async function runPrerender(options = {}, standaloneTrigger) {
134
132
  const prerenderContext = {
135
133
  noExtraDir: noExtraDir ?? false,
136
134
  pageContexts: [],
135
+ pageContexts404: [],
137
136
  pageContextInit: options.pageContextInit ?? null,
138
137
  prerenderedPageContexts: {},
139
138
  output: []
140
139
  };
141
140
  const doNotPrerenderList = [];
142
141
  await collectDoNoPrerenderList(vikeConfig.pageConfigs, doNotPrerenderList, defaultLocalValue, concurrencyLimit, globalContext);
142
+ // Allow user to create `pageContext` for parameterized routes and/or bulk data fetching
143
+ // https://vike.dev/onBeforePrerenderStart
143
144
  await callOnBeforePrerenderStartHooks(prerenderContext, globalContext, concurrencyLimit, doNotPrerenderList);
144
- await handlePagesWithStaticRoutes(prerenderContext, globalContext, doNotPrerenderList, concurrencyLimit);
145
- await callOnPrerenderStartHook(prerenderContext, globalContext);
145
+ // Create `pageContext` for each page with a static route
146
+ const urlList = getUrlListFromPagesWithStaticRoute(globalContext, doNotPrerenderList);
147
+ await createPageContextsForOnPrerenderStartHook(urlList, prerenderContext, globalContext, concurrencyLimit, false);
148
+ // Create `pageContext` for 404 page
149
+ const urlList404 = getUrlList404(globalContext);
150
+ await createPageContextsForOnPrerenderStartHook(urlList404, prerenderContext, globalContext, concurrencyLimit, true);
151
+ // Allow user to duplicate the list of `pageContext` for i18n
152
+ // https://vike.dev/onPrerenderStart
153
+ await callOnPrerenderStartHook(prerenderContext, globalContext, concurrencyLimit);
146
154
  let prerenderedCount = 0;
147
155
  // Write files as soon as pages finish rendering (instead of writing all files at once only after all pages have rendered).
148
156
  const onComplete = async (htmlFile) => {
149
157
  prerenderedCount++;
150
- if (htmlFile.pageId) {
151
- prerenderContext.prerenderedPageContexts[htmlFile.pageId] = htmlFile.pageContext;
152
- }
158
+ const { pageId } = htmlFile.pageContext;
159
+ (0, utils_js_1.assert)(pageId);
160
+ prerenderContext.prerenderedPageContexts[pageId] = htmlFile.pageContext;
153
161
  await writeFiles(htmlFile, root, outDirClient, options.onPagePrerender, prerenderContext.output, logLevel);
154
162
  };
155
- await routeAndPrerender(prerenderContext, globalContext, concurrencyLimit, onComplete);
163
+ await prerenderPages(prerenderContext, concurrencyLimit, onComplete);
156
164
  warnContradictoryNoPrerenderList(prerenderContext.prerenderedPageContexts, doNotPrerenderList);
157
- await prerender404(prerenderContext, globalContext, onComplete);
165
+ await prerenderPages404(prerenderContext, onComplete, concurrencyLimit);
158
166
  if (logLevel === 'info') {
159
167
  console.log(`${picocolors_1.default.green(`✓`)} ${prerenderedCount} HTML documents pre-rendered.`);
160
168
  }
@@ -266,12 +274,13 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, globalContext,
266
274
  });
267
275
  })));
268
276
  await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId, hookTimeout }) => concurrencyLimit(async () => {
269
- if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
277
+ if (doNotPrerenderList.find((p) => p.pageId === pageId))
270
278
  return;
271
- }
272
279
  const prerenderResult = await (0, executeHook_js_1.executeHook)(() => hookFn(), { hookName, hookFilePath, hookTimeout }, null);
273
280
  const result = normalizeOnPrerenderHookResult(prerenderResult, hookFilePath, hookName);
281
+ // Handle result
274
282
  await Promise.all(result.map(async ({ url, pageContext }) => {
283
+ // Assert no duplication
275
284
  {
276
285
  const pageContextFound = prerenderContext.pageContexts.find((pageContext) => isSameUrl(pageContext.urlOriginal, url));
277
286
  if (pageContextFound) {
@@ -282,30 +291,23 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, globalContext,
282
291
  (0, utils_js_1.assertUsage)(false, `URL ${picocolors_1.default.cyan(url)} provided ${providedTwice}. Make sure to provide the URL only once instead.`);
283
292
  }
284
293
  }
285
- const pageContextNew = await createPageContext(url, prerenderContext, globalContext);
286
- (0, utils_js_1.objectAssign)(pageContextNew, {
287
- _providedByHook: {
288
- hookFilePath,
289
- hookName
290
- }
291
- });
294
+ // Add result
295
+ const providedByHook = { hookFilePath, hookName };
296
+ const pageContextNew = await createPageContext(url, prerenderContext, globalContext, false, undefined, providedByHook);
292
297
  prerenderContext.pageContexts.push(pageContextNew);
293
298
  if (pageContext) {
294
- (0, utils_js_1.objectAssign)(pageContextNew, {
295
- _pageContextAlreadyProvidedByOnPrerenderHook: true
296
- });
299
+ (0, utils_js_1.objectAssign)(pageContextNew, { _pageContextAlreadyProvidedByOnPrerenderHook: true });
297
300
  (0, utils_js_1.objectAssign)(pageContextNew, pageContext);
298
301
  }
299
302
  }));
300
303
  })));
301
304
  }
302
- async function handlePagesWithStaticRoutes(prerenderContext, globalContext, doNotPrerenderList, concurrencyLimit) {
303
- // Pre-render pages with a static route
304
- await Promise.all(globalContext.pageRoutes.map((pageRoute) => concurrencyLimit(async () => {
305
+ function getUrlListFromPagesWithStaticRoute(globalContext, doNotPrerenderList) {
306
+ const urlList = [];
307
+ globalContext.pageRoutes.map((pageRoute) => {
305
308
  const { pageId } = pageRoute;
306
- if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
309
+ if (doNotPrerenderList.find((p) => p.pageId === pageId))
307
310
  return;
308
- }
309
311
  let urlOriginal;
310
312
  if (!('routeString' in pageRoute)) {
311
313
  // Abort since the page's route is a Route Function
@@ -321,43 +323,116 @@ async function handlePagesWithStaticRoutes(prerenderContext, globalContext, doNo
321
323
  urlOriginal = url;
322
324
  }
323
325
  (0, utils_js_1.assert)(urlOriginal.startsWith('/'));
326
+ urlList.push({ urlOriginal, pageId });
327
+ });
328
+ return urlList;
329
+ }
330
+ function getUrlList404(globalContext) {
331
+ const urlList = [];
332
+ const errorPageId = (0, error_page_js_1.getErrorPageId)(globalContext.pageFilesAll, globalContext.pageConfigs);
333
+ if (errorPageId) {
334
+ urlList.push({
335
+ // A URL is required for `viteDevServer.transformIndexHtml(url,html)`
336
+ urlOriginal: '/404',
337
+ pageId: errorPageId
338
+ });
339
+ }
340
+ return urlList;
341
+ }
342
+ async function createPageContextsForOnPrerenderStartHook(urlList, prerenderContext, globalContext, concurrencyLimit, is404) {
343
+ await Promise.all(urlList.map(({ urlOriginal, pageId }) => concurrencyLimit(async () => {
324
344
  // Already included in a onBeforePrerenderStart() hook
325
- if (prerenderContext.pageContexts.find((pageContext) => isSameUrl(pageContext.urlOriginal, urlOriginal))) {
345
+ if ([...prerenderContext.pageContexts, ...prerenderContext.pageContexts404].find((pageContext) => isSameUrl(pageContext.urlOriginal, urlOriginal))) {
326
346
  return;
327
347
  }
328
- const routeParams = {};
329
- const pageContext = await createPageContext(urlOriginal, prerenderContext, globalContext);
330
- (0, utils_js_1.objectAssign)(pageContext, {
331
- _providedByHook: null,
332
- routeParams,
333
- pageId: pageId,
334
- _debugRouteMatches: [
335
- {
336
- pageId,
337
- routeType: pageRoute.routeType,
338
- routeString: urlOriginal,
339
- routeParams
340
- }
341
- ]
342
- });
343
- (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
344
- prerenderContext.pageContexts.push(pageContext);
348
+ const pageContext = await createPageContext(urlOriginal, prerenderContext, globalContext, is404, pageId, null);
349
+ if (is404) {
350
+ prerenderContext.pageContexts404.push(pageContext);
351
+ }
352
+ else {
353
+ prerenderContext.pageContexts.push(pageContext);
354
+ }
345
355
  })));
346
356
  }
347
- async function createPageContext(urlOriginal, prerenderContext, globalContext) {
348
- const pageContextInit = { urlOriginal };
349
- (0, utils_js_1.objectAssign)(pageContextInit, prerenderContext.pageContextInit);
350
- const pageContext = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext, true, {});
357
+ async function createPageContext(urlOriginal, prerenderContext, globalContext, is404, pageId, providedByHook) {
358
+ const pageContextInit = {
359
+ urlOriginal,
360
+ ...prerenderContext.pageContextInit
361
+ };
362
+ const pageContext = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext, true);
351
363
  (0, utils_js_1.assert)(pageContext.isPrerendering === true);
352
364
  (0, utils_js_1.objectAssign)(pageContext, {
353
365
  _urlHandler: null,
366
+ _httpRequestId: null,
354
367
  _urlRewrite: null,
355
368
  _noExtraDir: prerenderContext.noExtraDir,
356
- _prerenderContext: prerenderContext
369
+ _prerenderContext: prerenderContext,
370
+ _providedByHook: providedByHook,
371
+ _urlOriginalModifiedByHook: null,
372
+ is404
357
373
  });
374
+ if (!is404) {
375
+ const pageContextFromRoute = await (0, index_js_1.route)(pageContext);
376
+ (0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageContextFromRoute, 'pageId', 'null') || (0, utils_js_1.hasProp)(pageContextFromRoute, 'pageId', 'string')); // Help TS
377
+ assertRouteMatch(pageContextFromRoute, pageContext);
378
+ (0, utils_js_1.assert)(pageContextFromRoute.pageId);
379
+ (0, utils_js_1.objectAssign)(pageContext, pageContextFromRoute);
380
+ }
381
+ else {
382
+ (0, utils_js_1.assert)(pageId);
383
+ (0, utils_js_1.objectAssign)(pageContext, {
384
+ pageId,
385
+ _debugRouteMatches: [],
386
+ routeParams: {}
387
+ });
388
+ }
389
+ (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
390
+ let usesClientRouter;
391
+ {
392
+ const { pageId } = pageContext;
393
+ (0, utils_js_1.assert)(pageId);
394
+ (0, utils_js_1.assert)(globalContext.isPrerendering);
395
+ if (globalContext.pageConfigs.length > 0) {
396
+ const pageConfig = globalContext.pageConfigs.find((p) => p.pageId === pageId);
397
+ (0, utils_js_1.assert)(pageConfig);
398
+ usesClientRouter = (0, getConfigValueRuntime_js_1.getConfigValueRuntime)(pageConfig, 'clientRouting', 'boolean')?.value ?? false;
399
+ }
400
+ else {
401
+ usesClientRouter = globalContext.usesClientRouter;
402
+ }
403
+ }
404
+ (0, utils_js_1.objectAssign)(pageContext, { _usesClientRouter: usesClientRouter });
358
405
  return pageContext;
359
406
  }
360
- async function callOnPrerenderStartHook(prerenderContext, globalContext) {
407
+ function assertRouteMatch(pageContextFromRoute, pageContext) {
408
+ if (pageContextFromRoute.pageId !== null) {
409
+ (0, utils_js_1.assert)(pageContextFromRoute.pageId);
410
+ return;
411
+ }
412
+ let hookName;
413
+ let hookFilePath;
414
+ if (pageContext._urlOriginalModifiedByHook) {
415
+ hookName = pageContext._urlOriginalModifiedByHook.hookName;
416
+ hookFilePath = pageContext._urlOriginalModifiedByHook.hookFilePath;
417
+ }
418
+ else if (pageContext._providedByHook) {
419
+ hookName = pageContext._providedByHook.hookName;
420
+ hookFilePath = pageContext._providedByHook.hookFilePath;
421
+ }
422
+ if (hookName) {
423
+ (0, utils_js_1.assert)(hookFilePath);
424
+ const { urlOriginal } = pageContext;
425
+ (0, utils_js_1.assert)(urlOriginal);
426
+ (0, utils_js_1.assertUsage)(false, `The ${hookName}() hook defined by ${hookFilePath} returns a URL ${picocolors_1.default.cyan(urlOriginal)} that ${noRouteMatch_js_1.noRouteMatch}. Make sure that the URLs returned by ${hookName}() always match the route of a page.`);
427
+ }
428
+ else {
429
+ // `prerenderHookFile` is `null` when the URL was deduced by the Filesytem Routing of `.page.js` files. The `onBeforeRoute()` can override Filesystem Routing; it is therefore expected that the deduced URL may not match any page.
430
+ (0, utils_js_1.assert)(pageContextFromRoute._routingProvidedByOnBeforeRouteHook);
431
+ // Abort since the URL doesn't correspond to any page
432
+ return;
433
+ }
434
+ }
435
+ async function callOnPrerenderStartHook(prerenderContext, globalContext, concurrencyLimit) {
361
436
  let onPrerenderStartHook;
362
437
  // V1 design
363
438
  if (globalContext.pageConfigs.length > 0) {
@@ -427,8 +502,11 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext) {
427
502
  pageContext._urlOriginalBeforeHook = pageContext.urlOriginal;
428
503
  });
429
504
  const docLink = 'https://vike.dev/i18n#pre-rendering';
430
- // Set `enumerable` to `false` to avoid computed URL properties from being iterated & copied in onPrerenderStart() hook, e.g. /examples/i18n/
431
- const { restoreEnumerable, addPageContextComputedUrl } = makePageContextComputedUrlNonEnumerable(prerenderContext.pageContexts);
505
+ prerenderContext.pageContexts.forEach((pageContext) => {
506
+ // Preserve URL computed properties when the user is copying pageContext is his onPrerenderStart() hook, e.g. /examples/i18n/
507
+ // https://vike.dev/i18n#pre-rendering
508
+ (0, utils_js_1.preservePropertyGetters)(pageContext);
509
+ });
432
510
  let result = await (0, executeHook_js_1.executeHook)(() => {
433
511
  const prerenderContextPublic = makePublic(prerenderContext);
434
512
  // TODO/v1-release: remove warning
@@ -443,7 +521,11 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext) {
443
521
  });
444
522
  return hookFn(prerenderContextPublic);
445
523
  }, onPrerenderStartHook, null);
446
- restoreEnumerable();
524
+ // Before applying result
525
+ prerenderContext.pageContexts.forEach((pageContext) => {
526
+ ;
527
+ pageContext._restorePropertyGetters?.();
528
+ });
447
529
  if (result === null || result === undefined) {
448
530
  return;
449
531
  }
@@ -474,82 +556,41 @@ async function callOnPrerenderStartHook(prerenderContext, globalContext) {
474
556
  }
475
557
  delete pageContext.url;
476
558
  });
559
+ // After applying result
477
560
  prerenderContext.pageContexts.forEach((pageContext) => {
561
+ ;
562
+ pageContext._restorePropertyGetters?.();
563
+ });
564
+ // Assert URL modified by user
565
+ await Promise.all(prerenderContext.pageContexts.map((pageContext) => concurrencyLimit(async () => {
478
566
  if (pageContext.urlOriginal !== pageContext._urlOriginalBeforeHook) {
479
567
  pageContext._urlOriginalModifiedByHook = {
480
568
  hookFilePath,
481
569
  hookName
482
570
  };
571
+ const pageContextFromRoute = await (0, index_js_1.route)(pageContext,
572
+ // Avoid calling onBeforeRoute() twice, otherwise user's onBeforeRoute() will wrongfully believe URL doesn't have locale when onBeforeRoute() removes the local from the URL
573
+ true);
574
+ assertRouteMatch(pageContextFromRoute, pageContext);
483
575
  }
484
- });
485
- addPageContextComputedUrl(prerenderContext.pageContexts);
576
+ })));
486
577
  }
487
- async function routeAndPrerender(prerenderContext, globalContext, concurrencyLimit, onComplete) {
488
- (0, utils_js_1.assert)(globalContext.isPrerendering);
489
- // Route all URLs
490
- await Promise.all(prerenderContext.pageContexts.map((pageContext) => concurrencyLimit(async () => {
491
- const { urlOriginal } = pageContext;
492
- (0, utils_js_1.assert)(urlOriginal);
493
- const pageContextFromRoute = await (0, index_js_1.route)(pageContext);
494
- (0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageContextFromRoute, 'pageId', 'null') || (0, utils_js_1.hasProp)(pageContextFromRoute, 'pageId', 'string'));
495
- if (pageContextFromRoute.pageId === null) {
496
- let hookName;
497
- let hookFilePath;
498
- if (pageContext._providedByHook) {
499
- hookName = pageContext._providedByHook.hookName;
500
- hookFilePath = pageContext._providedByHook.hookFilePath;
501
- }
502
- else if (pageContext._urlOriginalModifiedByHook) {
503
- hookName = pageContext._urlOriginalModifiedByHook.hookName;
504
- hookFilePath = pageContext._urlOriginalModifiedByHook.hookFilePath;
505
- }
506
- if (hookName) {
507
- (0, utils_js_1.assert)(hookFilePath);
508
- (0, utils_js_1.assertUsage)(false, `The ${hookName}() hook defined by ${hookFilePath} returns a URL ${picocolors_1.default.cyan(urlOriginal)} that ${noRouteMatch_js_1.noRouteMatch}. Make sure that the URLs returned by ${hookName}() always match the route of a page.`);
509
- }
510
- else {
511
- // `prerenderHookFile` is `null` when the URL was deduced by the Filesytem Routing of `.page.js` files. The `onBeforeRoute()` can override Filesystem Routing; it is therefore expected that the deduced URL may not match any page.
512
- (0, utils_js_1.assert)(pageContextFromRoute._routingProvidedByOnBeforeRouteHook);
513
- // Abort since the URL doesn't correspond to any page
514
- return;
515
- }
516
- }
517
- (0, utils_js_1.assert)(pageContextFromRoute.pageId);
518
- (0, utils_js_1.objectAssign)(pageContext, pageContextFromRoute);
519
- const { pageId: pageId } = pageContext;
520
- (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
521
- let usesClientRouter;
522
- {
523
- if (pageContext._pageConfigs.length > 0) {
524
- const pageConfig = pageContext._pageConfigs.find((p) => p.pageId === pageId);
525
- (0, utils_js_1.assert)(pageConfig);
526
- usesClientRouter = (0, getConfigValueRuntime_js_1.getConfigValueRuntime)(pageConfig, 'clientRouting', 'boolean')?.value ?? false;
527
- }
528
- else {
529
- usesClientRouter = globalContext.usesClientRouter;
530
- }
531
- }
532
- (0, utils_js_1.objectAssign)(pageContext, {
533
- is404: null,
534
- _httpRequestId: null,
535
- _usesClientRouter: usesClientRouter
536
- });
578
+ async function prerenderPages(prerenderContext, concurrencyLimit, onComplete) {
579
+ await Promise.all(prerenderContext.pageContexts.map((pageContextBeforeRender) => concurrencyLimit(async () => {
537
580
  let res;
538
581
  try {
539
- res = await (0, renderPageAlreadyRouted_js_1.prerenderPage)(pageContext);
582
+ res = await (0, renderPageAlreadyRouted_js_1.prerenderPage)(pageContextBeforeRender);
540
583
  }
541
584
  catch (err) {
542
- assertIsNotAbort(err, picocolors_1.default.cyan(pageContext.urlOriginal));
585
+ assertIsNotAbort(err, picocolors_1.default.cyan(pageContextBeforeRender.urlOriginal));
543
586
  throw err;
544
587
  }
545
- const { documentHtml, pageContextSerialized } = res;
588
+ const { documentHtml, pageContextSerialized, pageContext } = res;
546
589
  await onComplete({
547
- urlOriginal,
548
590
  pageContext,
549
591
  htmlString: documentHtml,
550
592
  pageContextSerialized,
551
- doNotCreateExtraDirectory: prerenderContext.noExtraDir,
552
- pageId
593
+ doNotCreateExtraDirectory: prerenderContext.noExtraDir
553
594
  });
554
595
  })));
555
596
  }
@@ -581,31 +622,27 @@ async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPre
581
622
  (0, utils_js_1.assertWarning)(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while no ${hookName}() hook returned any URL matching the page's route. You need to use a ${hookName}() hook (https://vike.dev/${hookName}) providing a list of URLs for ${pageAt} that should be pre-rendered. If you don't want to pre-render ${pageAt} then use the option prerender.partial (https://vike.dev/prerender#partial) to suppress this warning.`, { onlyOnce: true });
582
623
  });
583
624
  }
584
- async function prerender404(prerenderContext, globalContext, onComplete) {
585
- if (!Object.values(prerenderContext.prerenderedPageContexts).find(({ urlOriginal }) => urlOriginal === '/404')) {
625
+ async function prerenderPages404(prerenderContext, onComplete, concurrencyLimit) {
626
+ await Promise.all(prerenderContext.pageContexts404.map((pageContextBeforeRender) => concurrencyLimit(async () => {
586
627
  let result;
587
628
  try {
588
- result = await (0, renderPageAlreadyRouted_js_1.prerender404Page)(prerenderContext.pageContextInit, globalContext);
629
+ result = await (0, renderPageAlreadyRouted_js_1.prerenderPage)(pageContextBeforeRender);
589
630
  }
590
631
  catch (err) {
591
632
  assertIsNotAbort(err, 'the 404 page');
592
633
  throw err;
593
634
  }
594
- if (result) {
595
- const urlOriginal = '/404';
596
- const { documentHtml, pageContext } = result;
597
- await onComplete({
598
- urlOriginal,
599
- pageContext,
600
- htmlString: documentHtml,
601
- pageContextSerialized: null,
602
- doNotCreateExtraDirectory: true,
603
- pageId: null
604
- });
605
- }
606
- }
635
+ const { documentHtml, pageContext } = result;
636
+ await onComplete({
637
+ pageContext,
638
+ htmlString: documentHtml,
639
+ pageContextSerialized: null,
640
+ doNotCreateExtraDirectory: true
641
+ });
642
+ })));
607
643
  }
608
- async function writeFiles({ urlOriginal, pageContext, htmlString, pageContextSerialized, doNotCreateExtraDirectory }, root, outDirClient, onPagePrerender, output, logLevel) {
644
+ async function writeFiles({ pageContext, htmlString, pageContextSerialized, doNotCreateExtraDirectory }, root, outDirClient, onPagePrerender, output, logLevel) {
645
+ const { urlOriginal } = pageContext;
609
646
  (0, utils_js_1.assert)(urlOriginal.startsWith('/'));
610
647
  const writeJobs = [
611
648
  write(urlOriginal, pageContext, 'HTML', htmlString, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, output, logLevel)
@@ -750,26 +787,6 @@ function assertIsNotAbort(err, urlOr404) {
750
787
  (0, utils_js_1.assert)(abortCall);
751
788
  (0, utils_js_1.assertUsage)(false, `${picocolors_1.default.cyan(abortCall)} thrown${thrownBy} while pre-rendering ${urlOr404} but ${picocolors_1.default.cyan(abortCaller)} isn't supported for pre-rendered pages`);
752
789
  }
753
- function makePageContextComputedUrlNonEnumerable(pageContexts) {
754
- change(false);
755
- return { restoreEnumerable, addPageContextComputedUrl };
756
- function restoreEnumerable() {
757
- change(true);
758
- }
759
- function addPageContextComputedUrl(pageContexts) {
760
- // Add URL computed props to the user-generated pageContext copies
761
- pageContexts.forEach((pageContext) => {
762
- const pageContextUrlComputed = (0, getPageContextUrlComputed_js_1.getPageContextUrlComputed)(pageContext);
763
- (0, utils_js_1.objectAssign)(pageContext, pageContextUrlComputed);
764
- });
765
- }
766
- function change(enumerable) {
767
- pageContexts.forEach((pageContext) => {
768
- (0, utils_js_1.changeEnumerable)(pageContext, 'urlPathname', enumerable);
769
- (0, utils_js_1.changeEnumerable)(pageContext, 'urlParsed', enumerable);
770
- });
771
- }
772
- }
773
790
  function validatePrerenderConfig(
774
791
  // Guaranteed by configDef.type to be either an object or boolean
775
792
  prerenderConfig) {
@@ -808,7 +825,8 @@ prerenderConfig) {
808
825
  function makePublic(prerenderContext) {
809
826
  const prerenderContextPublic = (0, utils_js_1.makePublicCopy)(prerenderContext, 'prerenderContext', [
810
827
  'output', // vite-plugin-vercel
811
- 'pageContexts' // https://vike.dev/i18n#pre-rendering
828
+ 'pageContexts', // https://vike.dev/i18n#pre-rendering
829
+ 'pageContexts404' // https://vike.dev/i18n#pre-rendering
812
830
  ]);
813
831
  return prerenderContextPublic;
814
832
  }
@@ -31,6 +31,6 @@ __exportStar(require("../../utils/pLimit.js"), exports);
31
31
  __exportStar(require("../../utils/isFilePathAbsoluteFilesystem.js"), exports);
32
32
  __exportStar(require("../../utils/isArray.js"), exports);
33
33
  __exportStar(require("../../utils/isObject.js"), exports);
34
- __exportStar(require("../../utils/changeEnumerable.js"), exports);
35
34
  __exportStar(require("../../utils/makePublicCopy.js"), exports);
36
35
  __exportStar(require("../../utils/isNullish.js"), exports);
36
+ __exportStar(require("../../utils/preservePropertyGetters.js"), exports);
@@ -15,6 +15,7 @@ async function analyzePage(pageFilesAll, pageConfig, pageId, globalContext) {
15
15
  clientEntries.push(clientFilePath);
16
16
  if (isClientRuntimeLoaded)
17
17
  clientEntries.push((0, determineClientEntry_js_1.getVikeClientEntry)(isClientRouting));
18
+ console.log('clientEntries', clientEntries);
18
19
  const clientDependencies = [];
19
20
  clientDependencies.push({
20
21
  id: (0, virtualFilePageConfigValuesAll_js_1.getVirtualFileIdPageConfigValuesAll)(pageConfig.pageId, true),
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.renderPageAlreadyRouted = renderPageAlreadyRouted;
7
7
  exports.prerenderPage = prerenderPage;
8
- exports.prerender404Page = prerender404Page;
9
8
  exports.getPageContextInitEnhanced = getPageContextInitEnhanced;
10
9
  exports.createPageContext = createPageContext;
11
10
  const error_page_js_1 = require("../../../shared/error-page.js");
@@ -85,28 +84,6 @@ async function prerenderPage(pageContext) {
85
84
  return { documentHtml, pageContextSerialized, pageContext };
86
85
  }
87
86
  }
88
- async function prerender404Page(pageContextInit_, globalContext) {
89
- const errorPageId = (0, error_page_js_1.getErrorPageId)(globalContext.pageFilesAll, globalContext.pageConfigs);
90
- if (!errorPageId) {
91
- return null;
92
- }
93
- // A URL is required for `viteDevServer.transformIndexHtml(url,html)`
94
- const pageContextInit = { urlOriginal: '/fake-404-url' };
95
- (0, utils_js_1.objectAssign)(pageContextInit, pageContextInit_);
96
- const pageContext = await getPageContextInitEnhanced(pageContextInit, globalContext, true);
97
- (0, utils_js_1.objectAssign)(pageContext, {
98
- pageId: errorPageId,
99
- _httpRequestId: null,
100
- _urlRewrite: null,
101
- is404: true,
102
- routeParams: {},
103
- // `prerender404Page()` is about generating `dist/client/404.html` for static hosts; there is no Client Routing.
104
- _usesClientRouter: false,
105
- _debugRouteMatches: []
106
- });
107
- (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
108
- return prerenderPage(pageContext);
109
- }
110
87
  async function getPageContextInitEnhanced(pageContextInit, globalContext, isPrerendering, { ssr: { urlRewrite, urlHandler, isClientSideNavigation } = {
111
88
  urlRewrite: null,
112
89
  urlHandler: null,