vike 0.4.218-commit-85af52a → 0.4.218-commit-ea8bb27

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 (57) hide show
  1. package/dist/cjs/__internal/index.js +2 -3
  2. package/dist/cjs/node/api/prepareViteApiCall.js +1 -2
  3. package/dist/cjs/node/plugin/plugins/baseUrls.js +1 -1
  4. package/dist/cjs/node/plugin/plugins/commonConfig.js +1 -1
  5. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +26 -22
  6. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +111 -181
  7. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +1 -1
  8. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +2 -2
  9. package/dist/cjs/node/prerender/runPrerender.js +73 -32
  10. package/dist/cjs/node/prerender/utils.js +1 -0
  11. package/dist/cjs/node/runtime/globalContext.js +31 -5
  12. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +11 -33
  13. package/dist/cjs/node/runtime/renderPage/resolveRedirects.js +9 -1
  14. package/dist/cjs/node/runtime/renderPage.js +21 -22
  15. package/dist/cjs/node/shared/assertRuntimeManifest.js +0 -2
  16. package/dist/cjs/shared/getPageFiles/getPageFiles.js +6 -3
  17. package/dist/cjs/shared/page-configs/getPageConfigUserFriendly.js +2 -2
  18. package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +4 -4
  19. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  20. package/dist/esm/__internal/index.js +2 -3
  21. package/dist/esm/client/client-routing-runtime/createPageContext.js +1 -4
  22. package/dist/esm/client/server-routing-runtime/getPageContext.js +1 -4
  23. package/dist/esm/node/api/prepareViteApiCall.js +1 -2
  24. package/dist/esm/node/plugin/plugins/baseUrls.js +1 -1
  25. package/dist/esm/node/plugin/plugins/commonConfig.d.ts +2 -4
  26. package/dist/esm/node/plugin/plugins/commonConfig.js +1 -1
  27. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.d.ts +6 -9
  28. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +25 -21
  29. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +1 -6
  30. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +108 -178
  31. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +1 -1
  32. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +2 -2
  33. package/dist/esm/node/prerender/runPrerender.js +75 -34
  34. package/dist/esm/node/prerender/utils.d.ts +1 -0
  35. package/dist/esm/node/prerender/utils.js +1 -0
  36. package/dist/esm/node/runtime/globalContext.d.ts +17 -3
  37. package/dist/esm/node/runtime/globalContext.js +32 -6
  38. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +27 -42
  39. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +11 -33
  40. package/dist/esm/node/runtime/renderPage/resolveRedirects.d.ts +1 -1
  41. package/dist/esm/node/runtime/renderPage/resolveRedirects.js +9 -1
  42. package/dist/esm/node/runtime/renderPage.js +22 -23
  43. package/dist/esm/node/shared/assertPluginManifest.d.ts +0 -1
  44. package/dist/esm/node/shared/assertRuntimeManifest.d.ts +0 -1
  45. package/dist/esm/node/shared/assertRuntimeManifest.js +1 -3
  46. package/dist/esm/shared/getPageFiles/getPageFiles.d.ts +2 -0
  47. package/dist/esm/shared/getPageFiles/getPageFiles.js +6 -3
  48. package/dist/esm/shared/page-configs/Config/PageContextConfig.d.ts +9 -5
  49. package/dist/esm/shared/page-configs/Config.d.ts +13 -1
  50. package/dist/esm/shared/page-configs/getPageConfigUserFriendly.d.ts +7 -4
  51. package/dist/esm/shared/page-configs/getPageConfigUserFriendly.js +2 -2
  52. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.d.ts +2 -6
  53. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +4 -4
  54. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  55. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  56. package/dist/esm/utils/projectInfo.d.ts +1 -1
  57. package/package.json +1 -1
@@ -7,7 +7,7 @@ export { isV1Design };
7
7
  export { getConfigValueInterfaceFile };
8
8
  import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, lowerFirst, assertKeys, objectKeys, objectFromEntries, makeFirst, isNpmPackageImport, reverse } from '../../../utils.js';
9
9
  import path from 'path';
10
- import { configDefinitionsBuiltIn, configDefinitionsBuiltInGlobal } from './getVikeConfig/configDefinitionsBuiltIn.js';
10
+ import { configDefinitionsBuiltInAll } from './getVikeConfig/configDefinitionsBuiltIn.js';
11
11
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
12
12
  import { isTemporaryBuildFile } from './getVikeConfig/transpileAndExecuteFile.js';
13
13
  import { isConfigInvalid, isConfigInvalid_set } from '../../../../runtime/renderPage/isConfigInvalid.js';
@@ -25,6 +25,8 @@ import { getConfigValueBuildTime } from '../../../../../shared/page-configs/getC
25
25
  import { assertExtensionsPeerDependencies, assertExtensionsConventions } from './assertExtensions.js';
26
26
  import { getPageConfigUserFriendlyNew } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
27
27
  import { getConfigValuesBase } from '../../../../../shared/page-configs/serialize/serializeConfigValues.js';
28
+ const configDefinitionsBuiltIn = getConfigDefinitionsBuiltIn();
29
+ const configDefinitionsBuiltInGlobal = getConfigDefinitionsBuiltInGlobal();
28
30
  assertIsNotProductionRuntime();
29
31
  let restartVite = false;
30
32
  let wasConfigInvalid = null;
@@ -241,9 +243,7 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
241
243
  configValueSources: {}
242
244
  },
243
245
  vikeConfigGlobal: resolveVikeConfigGlobal({}, {}),
244
- vikeConfigNew: {
245
- global: getPageConfigUserFriendlyNew({ configValues: {} })
246
- }
246
+ global: getPageConfigUserFriendlyNew({ configValues: {} })
247
247
  };
248
248
  return dummyData;
249
249
  }
@@ -252,7 +252,97 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
252
252
  async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
253
253
  const interfaceFilesByLocationId = await loadInterfaceFiles(userRootDir);
254
254
  const importedFilesLoaded = {};
255
- const { pageConfigGlobal, vikeConfigGlobal } = await getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded, vikeVitePluginOptions);
255
+ const [globalConfigs, pageConfigs] = await Promise.all([
256
+ getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded, vikeVitePluginOptions),
257
+ getPageConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded)
258
+ ]);
259
+ return { pageConfigs, ...globalConfigs };
260
+ }
261
+ async function getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded, vikeVitePluginOptions) {
262
+ const locationIds = objectKeys(interfaceFilesByLocationId);
263
+ const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesByLocationId).filter(([locationId]) => {
264
+ return isGlobalLocation(locationId, locationIds);
265
+ }));
266
+ // Validate that global configs live in global interface files
267
+ {
268
+ const interfaceFilesGlobalPaths = [];
269
+ objectEntries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
270
+ assert(isGlobalLocation(locationId, locationIds));
271
+ interfaceFiles.forEach(({ filePath: { filePathAbsoluteUserRootDir } }) => {
272
+ if (filePathAbsoluteUserRootDir) {
273
+ interfaceFilesGlobalPaths.push(filePathAbsoluteUserRootDir);
274
+ }
275
+ });
276
+ });
277
+ const globalPaths = Array.from(new Set(interfaceFilesGlobalPaths.map((p) => path.posix.dirname(p))));
278
+ objectEntries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
279
+ interfaceFiles.forEach((interfaceFile) => {
280
+ Object.keys(interfaceFile.fileExportsByConfigName).forEach((configName) => {
281
+ if (!isGlobalLocation(locationId, locationIds) && isGlobalConfig(configName)) {
282
+ assertUsage(false, [
283
+ `${interfaceFile.filePath.filePathToShowToUser} defines the config ${pc.cyan(configName)} which is global:`,
284
+ globalPaths.length
285
+ ? `define ${pc.cyan(configName)} in ${joinEnglish(globalPaths, 'or')} instead`
286
+ : `create a global config (e.g. /pages/+config.js) and define ${pc.cyan(configName)} there instead`
287
+ ].join(' '));
288
+ }
289
+ });
290
+ });
291
+ });
292
+ }
293
+ const pageConfigGlobalValues = {};
294
+ const pageConfigGlobal = {
295
+ configDefinitions: configDefinitionsBuiltInGlobal,
296
+ configValueSources: {}
297
+ };
298
+ await Promise.all(objectEntries(configDefinitionsBuiltInGlobal).map(async ([configName, configDef]) => {
299
+ const sources = await resolveConfigValueSources(configName, configDef, interfaceFilesGlobal, userRootDir, importedFilesLoaded);
300
+ const configValueSource = sources[0];
301
+ if (!configValueSource)
302
+ return;
303
+ pageConfigGlobal.configValueSources[configName] = sources;
304
+ // TODO/now
305
+ if (configName === 'onBeforeRoute' || configName === 'onPrerenderStart') {
306
+ assert(!('value' in configValueSource));
307
+ }
308
+ else {
309
+ assert('value' in configValueSource);
310
+ // TODO/now
311
+ if (configName === 'prerender' && typeof configValueSource.value === 'boolean')
312
+ return;
313
+ pageConfigGlobalValues[configName] = configValueSource.value;
314
+ }
315
+ }));
316
+ const vikeConfigGlobal = resolveVikeConfigGlobal(vikeVitePluginOptions, pageConfigGlobalValues);
317
+ {
318
+ assert(isObject(vikeVitePluginOptions));
319
+ Object.entries(vikeVitePluginOptions).forEach(([configName, value]) => {
320
+ var _a;
321
+ assert(includes(objectKeys(configDefinitionsBuiltInGlobal), configName));
322
+ const configDef = configDefinitionsBuiltInGlobal[configName];
323
+ const sources = ((_a = pageConfigGlobal.configValueSources)[configName] ?? (_a[configName] = []));
324
+ sources.push({
325
+ value,
326
+ configEnv: configDef.env,
327
+ definedAtFilePath: {
328
+ ...getFilePathResolved({
329
+ userRootDir,
330
+ filePathAbsoluteUserRootDir: '/vite.config.js'
331
+ }),
332
+ fileExportPathToShowToUser: null
333
+ },
334
+ locationId: '/',
335
+ isOverriden: configDef.cumulative ? false : sources.length > 0,
336
+ valueIsImportedAtRuntime: false,
337
+ valueIsDefinedByPlusFile: false
338
+ });
339
+ });
340
+ }
341
+ const configValues = getConfigValues(pageConfigGlobal);
342
+ const global = getPageConfigUserFriendlyNew({ configValues });
343
+ return { pageConfigGlobal, vikeConfigGlobal, global };
344
+ }
345
+ async function getPageConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded) {
256
346
  const pageConfigs = await Promise.all(objectEntries(interfaceFilesByLocationId)
257
347
  .filter(([_pageId, interfaceFiles]) => isDefiningPage(interfaceFiles))
258
348
  .map(async ([locationId]) => {
@@ -302,13 +392,11 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
302
392
  return pageConfig;
303
393
  }));
304
394
  assertPageConfigs(pageConfigs);
305
- const configValues = getConfigValues(pageConfigGlobal);
306
- const global = getPageConfigUserFriendlyNew({ configValues });
307
- return { pageConfigs, pageConfigGlobal, vikeConfigGlobal, vikeConfigNew: { global } };
395
+ return pageConfigs;
308
396
  }
309
397
  function getConfigValues(pageConfig) {
310
398
  const configValues = {};
311
- getConfigValuesBase(pageConfig, (configEnv) => !!configEnv.config).forEach((entry) => {
399
+ getConfigValuesBase(pageConfig, (configEnv) => !!configEnv.config, null).forEach((entry) => {
312
400
  if (entry.configValueBase.type === 'computed') {
313
401
  assert('value' in entry); // Help TS
314
402
  const { configValueBase, value, configName } = entry;
@@ -334,7 +422,7 @@ function getConfigValues(pageConfig) {
334
422
  });
335
423
  return configValues;
336
424
  }
337
- // TODO/soon: refactor
425
+ // TODO/now: refactor
338
426
  // - Dedupe: most of the assertUsageGlobalConfigs() code below is a copy-paste of the assertUsage() logic inside getGlobalConfigs()
339
427
  // - This assertUsage() message is slightly better: use this one for getGlobalConfigs()
340
428
  // Global configs should be defined at global locations
@@ -351,7 +439,7 @@ function assertUsageGlobalConfigs(interfaceFilesRelevantList, configDefinitions,
351
439
  if (isGlobalConfig(configName))
352
440
  return;
353
441
  const configDef = getConfigDefinition(configDefinitions, configName, interfaceFile.filePath.filePathToShowToUser);
354
- if (configDef.global) {
442
+ if (configDef.global === true) {
355
443
  const locationIds = objectKeys(interfaceFilesByLocationId);
356
444
  if (!isGlobalLocation(interfaceFile.locationId, locationIds)) {
357
445
  const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesByLocationId).filter(([locationId]) => {
@@ -410,85 +498,6 @@ function getInterfaceFilesRelevant(interfaceFilesByLocationId, locationIdPage) {
410
498
  .sort(([locationId1], [locationId2]) => sortAfterInheritanceOrder(locationId1, locationId2, locationIdPage)));
411
499
  return interfaceFilesRelevant;
412
500
  }
413
- async function getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded, vikeVitePluginOptions) {
414
- const locationIds = objectKeys(interfaceFilesByLocationId);
415
- const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesByLocationId).filter(([locationId]) => {
416
- return isGlobalLocation(locationId, locationIds);
417
- }));
418
- // Validate that global configs live in global interface files
419
- {
420
- const interfaceFilesGlobalPaths = [];
421
- objectEntries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
422
- assert(isGlobalLocation(locationId, locationIds));
423
- interfaceFiles.forEach(({ filePath: { filePathAbsoluteUserRootDir } }) => {
424
- if (filePathAbsoluteUserRootDir) {
425
- interfaceFilesGlobalPaths.push(filePathAbsoluteUserRootDir);
426
- }
427
- });
428
- });
429
- const globalPaths = Array.from(new Set(interfaceFilesGlobalPaths.map((p) => path.posix.dirname(p))));
430
- objectEntries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
431
- interfaceFiles.forEach((interfaceFile) => {
432
- Object.keys(interfaceFile.fileExportsByConfigName).forEach((configName) => {
433
- if (!isGlobalLocation(locationId, locationIds) && isGlobalConfig(configName)) {
434
- assertUsage(false, [
435
- `${interfaceFile.filePath.filePathToShowToUser} defines the config ${pc.cyan(configName)} which is global:`,
436
- globalPaths.length
437
- ? `define ${pc.cyan(configName)} in ${joinEnglish(globalPaths, 'or')} instead`
438
- : `create a global config (e.g. /pages/+config.js) and define ${pc.cyan(configName)} there instead`
439
- ].join(' '));
440
- }
441
- });
442
- });
443
- });
444
- }
445
- const pageConfigGlobalValues = {};
446
- const pageConfigGlobal = {
447
- configDefinitions: configDefinitionsBuiltInGlobal,
448
- configValueSources: {}
449
- };
450
- await Promise.all(objectEntries(configDefinitionsBuiltInGlobal).map(async ([configName, configDef]) => {
451
- const sources = await resolveConfigValueSources(configName, configDef, interfaceFilesGlobal, userRootDir, importedFilesLoaded);
452
- const configValueSource = sources[0];
453
- if (!configValueSource)
454
- return;
455
- pageConfigGlobal.configValueSources[configName] = sources;
456
- if (configName === 'onBeforeRoute' || configName === 'onPrerenderStart') {
457
- assert(!('value' in configValueSource));
458
- }
459
- else {
460
- assert('value' in configValueSource);
461
- if (configName === 'prerender' && typeof configValueSource.value === 'boolean')
462
- return;
463
- pageConfigGlobalValues[configName] = configValueSource.value;
464
- }
465
- }));
466
- const vikeConfigGlobal = resolveVikeConfigGlobal(vikeVitePluginOptions, pageConfigGlobalValues);
467
- {
468
- assert(isObject(vikeVitePluginOptions));
469
- Object.entries(vikeVitePluginOptions).forEach(([configName, value]) => {
470
- if (pageConfigGlobal.configValueSources[configName])
471
- return;
472
- pageConfigGlobal.configValueSources[configName] = [];
473
- pageConfigGlobal.configValueSources[configName].push({
474
- value,
475
- configEnv: { config: true },
476
- definedAtFilePath: {
477
- ...getFilePathResolved({
478
- userRootDir,
479
- filePathAbsoluteUserRootDir: '/vite.config.js'
480
- }),
481
- fileExportPathToShowToUser: null
482
- },
483
- locationId: '/',
484
- isOverriden: false,
485
- valueIsImportedAtRuntime: false,
486
- valueIsDefinedByPlusFile: false
487
- });
488
- });
489
- }
490
- return { pageConfigGlobal, pageConfigGlobalValues, vikeConfigGlobal };
491
- }
492
501
  async function resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, importedFilesLoaded) {
493
502
  const sourcesInfo = [];
494
503
  // interfaceFilesRelevant is sorted by sortAfterInheritanceOrder()
@@ -1031,6 +1040,7 @@ function isLoadableAtBuildTime(configDef) {
1031
1040
  return !!configDef.env.config && !configDef._valueIsFilePath;
1032
1041
  }
1033
1042
  function isGlobalConfig(configName) {
1043
+ // TODO/now
1034
1044
  if (configName === 'prerender')
1035
1045
  return false;
1036
1046
  const configNamesGlobal = getConfigNamesGlobal();
@@ -1039,6 +1049,12 @@ function isGlobalConfig(configName) {
1039
1049
  function getConfigNamesGlobal() {
1040
1050
  return Object.keys(configDefinitionsBuiltInGlobal);
1041
1051
  }
1052
+ function getConfigDefinitionsBuiltInGlobal() {
1053
+ return objectFromEntries(objectEntries(configDefinitionsBuiltInAll).filter(([_configName, configDef]) => configDef.global !== undefined));
1054
+ }
1055
+ function getConfigDefinitionsBuiltIn() {
1056
+ return objectFromEntries(objectEntries(configDefinitionsBuiltInAll).filter(([_configName, configDef]) => configDef.global !== true));
1057
+ }
1042
1058
  function assertConfigExists(configName, configNamesRelevant, filePathToShowToUser) {
1043
1059
  const configNames = [...configNamesRelevant, ...getConfigNamesGlobal()];
1044
1060
  if (configNames.includes(configName))
@@ -1065,23 +1081,15 @@ function sortConfigValueSources(configValueSources, locationIdPage) {
1065
1081
  function getConfigValueInterfaceFile(interfaceFile, configName) {
1066
1082
  return interfaceFile.fileExportsByConfigName[configName]?.configValue;
1067
1083
  }
1068
- // TODO: refactor code below
1084
+ // TODO/now: refactor code below
1069
1085
  function resolveVikeConfigGlobal(vikeVitePluginOptions, pageConfigGlobalValues) {
1070
- // TODO/v1-release: remove
1071
- assertVikeConfigGlobal(vikeVitePluginOptions, ({ prop, errMsg }) => `vite.config.js > vike option ${prop} ${errMsg}`);
1072
- const configs = [vikeVitePluginOptions];
1073
- assertVikeConfigGlobal(pageConfigGlobalValues, ({ prop, errMsg }) => {
1074
- // Can we add the config file path ?
1075
- return `config ${pc.cyan(prop)} ${errMsg}`;
1076
- });
1077
- configs.push(pageConfigGlobalValues);
1086
+ const configs = [vikeVitePluginOptions, pageConfigGlobalValues];
1078
1087
  const vikeConfigGlobal = {
1079
1088
  disableAutoFullBuild: pickFirst(configs.map((c) => c.disableAutoFullBuild)) ?? null,
1080
1089
  prerender: resolvePrerenderOptions(configs),
1081
1090
  includeAssetsImportedByServer: pickFirst(configs.map((c) => c.includeAssetsImportedByServer)) ?? true,
1082
1091
  baseServer: pickFirst(configs.map((c) => c.baseServer)) ?? null,
1083
1092
  baseAssets: pickFirst(configs.map((c) => c.baseAssets)) ?? null,
1084
- redirects: merge(configs.map((c) => c.redirects)) ?? {},
1085
1093
  disableUrlNormalization: pickFirst(configs.map((c) => c.disableUrlNormalization)) ?? false,
1086
1094
  trailingSlash: pickFirst(configs.map((c) => c.trailingSlash)) ?? false
1087
1095
  };
@@ -1102,84 +1110,6 @@ function resolvePrerenderOptions(configs) {
1102
1110
  function isObject2(p) {
1103
1111
  return typeof p === 'object';
1104
1112
  }
1105
- function merge(objs) {
1106
- const obj = {};
1107
- objs.forEach((e) => {
1108
- Object.assign(obj, e);
1109
- });
1110
- return obj;
1111
- }
1112
1113
  function pickFirst(arr) {
1113
1114
  return arr.filter((v) => v !== undefined)[0];
1114
1115
  }
1115
- function assertVikeConfigGlobal(vikeConfigGlobal, wrongUsageMsg) {
1116
- const wrongUsageError = check(vikeConfigGlobal);
1117
- if (wrongUsageError) {
1118
- assertUsage(false, wrongUsageMsg(wrongUsageError));
1119
- }
1120
- }
1121
- function check(vikeConfigGlobal) {
1122
- assert(isObject(vikeConfigGlobal));
1123
- {
1124
- const prop = 'disableUrlNormalization';
1125
- if (!hasProp(vikeConfigGlobal, prop, 'boolean') && !hasProp(vikeConfigGlobal, prop, 'undefined'))
1126
- return { prop, errMsg: 'should be a boolean' };
1127
- }
1128
- {
1129
- const prop = 'trailingSlash';
1130
- if (!hasProp(vikeConfigGlobal, prop, 'boolean') && !hasProp(vikeConfigGlobal, prop, 'undefined'))
1131
- return { prop, errMsg: 'should be a boolean' };
1132
- }
1133
- {
1134
- const prop = 'redirects';
1135
- const { redirects } = vikeConfigGlobal;
1136
- if (!(redirects === undefined ||
1137
- (isObject(redirects) && Object.values(redirects).every((v) => typeof v === 'string'))))
1138
- return { prop, errMsg: 'should be an object of strings' };
1139
- }
1140
- {
1141
- const prop = 'disableAutoFullBuild';
1142
- if (!hasProp(vikeConfigGlobal, prop, 'boolean') &&
1143
- !hasProp(vikeConfigGlobal, prop, 'undefined') &&
1144
- !(vikeConfigGlobal[prop] === 'prerender'))
1145
- return { prop, errMsg: "should be a boolean or 'prerender'" };
1146
- }
1147
- {
1148
- const prop = 'includeAssetsImportedByServer';
1149
- if (!hasProp(vikeConfigGlobal, prop, 'boolean') && !hasProp(vikeConfigGlobal, prop, 'undefined'))
1150
- return { prop, errMsg: 'should be a boolean' };
1151
- }
1152
- {
1153
- const prop = 'prerender';
1154
- if (!hasProp(vikeConfigGlobal, prop, 'object') &&
1155
- !hasProp(vikeConfigGlobal, prop, 'boolean') &&
1156
- !hasProp(vikeConfigGlobal, prop, 'undefined'))
1157
- return { prop, errMsg: 'should be an object or a boolean' };
1158
- }
1159
- const configVikePrerender = vikeConfigGlobal.prerender;
1160
- if (typeof configVikePrerender === 'object') {
1161
- {
1162
- const p = 'partial';
1163
- if (!hasProp(configVikePrerender, p, 'boolean') && !hasProp(configVikePrerender, p, 'undefined'))
1164
- return { prop: `prerender.${p}`, errMsg: 'should be a boolean' };
1165
- }
1166
- {
1167
- const p = 'noExtraDir';
1168
- if (!hasProp(configVikePrerender, p, 'boolean') && !hasProp(configVikePrerender, p, 'undefined'))
1169
- return { prop: `prerender.${p}`, errMsg: 'should be a boolean' };
1170
- }
1171
- {
1172
- const p = 'disableAutoRun';
1173
- if (!hasProp(configVikePrerender, p, 'boolean') && !hasProp(configVikePrerender, p, 'undefined'))
1174
- return { prop: `prerender.${p}`, errMsg: 'should be a boolean' };
1175
- }
1176
- {
1177
- const p = 'parallel';
1178
- if (!hasProp(configVikePrerender, p, 'boolean') &&
1179
- !hasProp(configVikePrerender, p, 'number') &&
1180
- !hasProp(configVikePrerender, p, 'undefined'))
1181
- return { prop: `prerender.${p}`, errMsg: 'should be a boolean or a number' };
1182
- }
1183
- }
1184
- return null;
1185
- }
@@ -31,7 +31,7 @@ function getLoadConfigValuesAll(pageConfig, isForClientSide, pageId, includeAsse
31
31
  const importStatements = [];
32
32
  const isClientRouting = getConfigValueBuildTime(pageConfig, 'clientRouting', 'boolean')?.value ?? false;
33
33
  lines.push('export const configValuesSerialized = {');
34
- lines.push(...serializeConfigValues(pageConfig, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), { isEager: false }, ''));
34
+ lines.push(...serializeConfigValues(pageConfig, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), '', false));
35
35
  lines.push('};');
36
36
  if (!fixServerAssets_isEnabled() && includeAssetsImportedByServer && isForClientSide && !isDev) {
37
37
  importStatements.push(`import '${extractAssetsAddQuery(getVirtualFileIdPageConfigValuesAll(pageId, false))}'`);
@@ -33,7 +33,7 @@ function getCodePageConfigsSerialized(pageConfigs, isForClientSide, isClientRout
33
33
  lines.push(` routeFilesystem: ${JSON.stringify(routeFilesystem)},`);
34
34
  lines.push(` loadConfigValuesAll: () => import(${JSON.stringify(virtualFileIdPageConfigValuesAll)}),`);
35
35
  lines.push(` configValuesSerialized: {`);
36
- lines.push(...serializeConfigValues(pageConfig, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), { isEager: true }, ' '));
36
+ lines.push(...serializeConfigValues(pageConfig, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), ' ', true));
37
37
  lines.push(` },`);
38
38
  lines.push(` },`);
39
39
  });
@@ -43,7 +43,7 @@ function getCodePageConfigsSerialized(pageConfigs, isForClientSide, isClientRout
43
43
  function getCodePageConfigGlobalSerialized(pageConfigGlobal, isForClientSide, isClientRouting, isDev, importStatements) {
44
44
  const lines = [];
45
45
  lines.push(` configValuesSerialized: {`);
46
- lines.push(...serializeConfigValues(pageConfigGlobal, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), { isEager: true }, ' '));
46
+ lines.push(...serializeConfigValues(pageConfigGlobal, importStatements, (configEnv) => isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isDev }), ' ', null));
47
47
  lines.push(` },`);
48
48
  const code = lines.join('\n');
49
49
  return code;
@@ -4,8 +4,8 @@ export { runPrerenderFromAutoRun };
4
4
  export { runPrerender_forceExit };
5
5
  import path from 'path';
6
6
  import { route } from '../../shared/route/index.js';
7
- import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs, isPropertyGetter, assertPosixPath, urlToFile, isPlainObject, pLimit, isArray, changeEnumerable, onSetupPrerender } from './utils.js';
8
- import { prerenderPage, prerender404Page, getRenderContext, getPageContextInitEnhanced } from '../runtime/renderPage/renderPageAlreadyRouted.js';
7
+ import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs, isPropertyGetter, assertPosixPath, urlToFile, isPlainObject, pLimit, isArray, changeEnumerable, onSetupPrerender, isObject } from './utils.js';
8
+ import { prerenderPage, prerender404Page, getPageContextInitEnhanced } from '../runtime/renderPage/renderPageAlreadyRouted.js';
9
9
  import pc from '@brillout/picocolors';
10
10
  import { cpus } from 'os';
11
11
  import { getGlobalContext, initGlobalContext_runPrerender, setGlobalContext_isPrerendering } from '../runtime/globalContext.js';
@@ -70,6 +70,7 @@ async function runPrerender(options = {}, standaloneTrigger) {
70
70
  const { outDirClient } = getOutDirs(viteConfig);
71
71
  const { root } = viteConfig;
72
72
  const prerenderConfig = vikeConfig.vikeConfigGlobal.prerender;
73
+ validatePrerenderConfig(prerenderConfig);
73
74
  if (!prerenderConfig) {
74
75
  assert(standaloneTrigger);
75
76
  assertWarning(prerenderConfig, `You're executing ${pc.cyan(standaloneTrigger)} but the config ${pc.cyan('prerender')} isn't set to true`, {
@@ -79,8 +80,8 @@ async function runPrerender(options = {}, standaloneTrigger) {
79
80
  const { partial = false, noExtraDir = false, parallel = true } = prerenderConfig || {};
80
81
  const concurrencyLimit = pLimit(parallel === false || parallel === 0 ? 1 : parallel === true || parallel === undefined ? cpus().length : parallel);
81
82
  await initGlobalContext_runPrerender();
82
- const renderContext = await getRenderContext();
83
- renderContext.pageFilesAll.forEach(assertExportNames);
83
+ const globalContext = getGlobalContext();
84
+ globalContext.pageFilesAll.forEach(assertExportNames);
84
85
  const prerenderContext = {};
85
86
  objectAssign(prerenderContext, {
86
87
  _urlHandler: null,
@@ -89,10 +90,10 @@ async function runPrerender(options = {}, standaloneTrigger) {
89
90
  pageContextInit: options.pageContextInit ?? null
90
91
  });
91
92
  const doNotPrerenderList = [];
92
- await collectDoNoPrerenderList(renderContext, vikeConfig.pageConfigs, doNotPrerenderList, concurrencyLimit);
93
- await callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit, doNotPrerenderList);
94
- await handlePagesWithStaticRoutes(prerenderContext, renderContext, doNotPrerenderList, concurrencyLimit);
95
- await callOnPrerenderStartHook(prerenderContext, renderContext);
93
+ await collectDoNoPrerenderList(vikeConfig.pageConfigs, doNotPrerenderList, concurrencyLimit);
94
+ await callOnBeforePrerenderStartHooks(prerenderContext, concurrencyLimit, doNotPrerenderList);
95
+ await handlePagesWithStaticRoutes(prerenderContext, doNotPrerenderList, concurrencyLimit);
96
+ await callOnPrerenderStartHook(prerenderContext);
96
97
  const prerenderedPageContexts = {};
97
98
  let prerenderedCount = 0;
98
99
  const onComplete = async (htmlFile) => {
@@ -104,14 +105,14 @@ async function runPrerender(options = {}, standaloneTrigger) {
104
105
  };
105
106
  await routeAndPrerender(prerenderContext, concurrencyLimit, onComplete);
106
107
  warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerenderList);
107
- await prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete);
108
+ await prerender404(prerenderedPageContexts, prerenderContext, onComplete);
108
109
  if (logLevel === 'info') {
109
110
  console.log(`${pc.green(`✓`)} ${prerenderedCount} HTML documents pre-rendered.`);
110
111
  }
111
- warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial);
112
+ warnMissingPages(prerenderedPageContexts, doNotPrerenderList, partial);
112
113
  return { viteConfig };
113
114
  }
114
- async function collectDoNoPrerenderList(renderContext, pageConfigs, doNotPrerenderList, concurrencyLimit) {
115
+ async function collectDoNoPrerenderList(pageConfigs, doNotPrerenderList, concurrencyLimit) {
115
116
  // V1 design
116
117
  pageConfigs.forEach((pageConfig) => {
117
118
  const configName = 'prerender';
@@ -129,7 +130,8 @@ async function collectDoNoPrerenderList(renderContext, pageConfigs, doNotPrerend
129
130
  });
130
131
  // Old design
131
132
  // TODO/v1-release: remove
132
- await Promise.all(renderContext.pageFilesAll
133
+ const globalContext = getGlobalContext();
134
+ await Promise.all(globalContext.pageFilesAll
133
135
  .filter((p) => {
134
136
  assertExportNames(p);
135
137
  if (!p.exportNames?.includes('doNotPrerender'))
@@ -141,8 +143,8 @@ async function collectDoNoPrerenderList(renderContext, pageConfigs, doNotPrerend
141
143
  assert(p.loadFile);
142
144
  await p.loadFile();
143
145
  })));
144
- renderContext.allPageIds.forEach((pageId) => {
145
- const pageFilesServerSide = getPageFilesServerSide(renderContext.pageFilesAll, pageId);
146
+ globalContext.allPageIds.forEach((pageId) => {
147
+ const pageFilesServerSide = getPageFilesServerSide(globalContext.pageFilesAll, pageId);
146
148
  for (const p of pageFilesServerSide) {
147
149
  if (!p.exportNames?.includes('doNotPrerender'))
148
150
  continue;
@@ -171,10 +173,11 @@ function assertExportNames(pageFile) {
171
173
  const { exportNames, fileType } = pageFile;
172
174
  assert(exportNames || fileType === '.page.route' || fileType === '.css', pageFile.filePath);
173
175
  }
174
- async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit, doNotPrerenderList) {
176
+ async function callOnBeforePrerenderStartHooks(prerenderContext, concurrencyLimit, doNotPrerenderList) {
175
177
  const onBeforePrerenderStartHooks = [];
178
+ const globalContext = getGlobalContext();
176
179
  // V1 design
177
- await Promise.all(renderContext.pageConfigs.map((pageConfig) => concurrencyLimit(async () => {
180
+ await Promise.all(globalContext.pageConfigs.map((pageConfig) => concurrencyLimit(async () => {
178
181
  const hookName = 'onBeforePrerenderStart';
179
182
  const pageConfigLoaded = await loadConfigValues(pageConfig, false);
180
183
  const hook = getHookFromPageConfig(pageConfigLoaded, hookName);
@@ -190,7 +193,7 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
190
193
  });
191
194
  })));
192
195
  // 0.4 design
193
- await Promise.all(renderContext.pageFilesAll
196
+ await Promise.all(globalContext.pageFilesAll
194
197
  .filter((p) => {
195
198
  assertExportNames(p);
196
199
  if (!p.exportNames?.includes('prerender'))
@@ -231,7 +234,7 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
231
234
  assertUsage(false, `URL ${pc.cyan(url)} provided ${providedTwice}. Make sure to provide the URL only once instead.`);
232
235
  }
233
236
  }
234
- const pageContextNew = createPageContext(url, renderContext, prerenderContext);
237
+ const pageContextNew = createPageContext(url, prerenderContext);
235
238
  objectAssign(pageContextNew, {
236
239
  _providedByHook: {
237
240
  hookFilePath,
@@ -248,9 +251,10 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
248
251
  });
249
252
  })));
250
253
  }
251
- async function handlePagesWithStaticRoutes(prerenderContext, renderContext, doNotPrerenderList, concurrencyLimit) {
254
+ async function handlePagesWithStaticRoutes(prerenderContext, doNotPrerenderList, concurrencyLimit) {
252
255
  // Pre-render pages with a static route
253
- await Promise.all(renderContext.pageRoutes.map((pageRoute) => concurrencyLimit(async () => {
256
+ const globalContext = getGlobalContext();
257
+ await Promise.all(globalContext.pageRoutes.map((pageRoute) => concurrencyLimit(async () => {
254
258
  const { pageId } = pageRoute;
255
259
  if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
256
260
  return;
@@ -275,7 +279,7 @@ async function handlePagesWithStaticRoutes(prerenderContext, renderContext, doNo
275
279
  return;
276
280
  }
277
281
  const routeParams = {};
278
- const pageContext = createPageContext(urlOriginal, renderContext, prerenderContext);
282
+ const pageContext = createPageContext(urlOriginal, prerenderContext);
279
283
  objectAssign(pageContext, {
280
284
  _providedByHook: null,
281
285
  routeParams,
@@ -293,7 +297,7 @@ async function handlePagesWithStaticRoutes(prerenderContext, renderContext, doNo
293
297
  prerenderContext.pageContexts.push(pageContext);
294
298
  })));
295
299
  }
296
- function createPageContext(urlOriginal, renderContext, prerenderContext) {
300
+ function createPageContext(urlOriginal, prerenderContext) {
297
301
  const pageContext = {
298
302
  _urlHandler: null,
299
303
  _urlRewrite: null,
@@ -305,17 +309,18 @@ function createPageContext(urlOriginal, renderContext, prerenderContext) {
305
309
  };
306
310
  objectAssign(pageContextInit, prerenderContext.pageContextInit);
307
311
  {
308
- const pageContextInitEnhanced = getPageContextInitEnhanced(pageContextInit, renderContext);
312
+ const pageContextInitEnhanced = getPageContextInitEnhanced(pageContextInit);
309
313
  objectAssign(pageContext, pageContextInitEnhanced);
310
314
  }
311
315
  return pageContext;
312
316
  }
313
- async function callOnPrerenderStartHook(prerenderContext, renderContext) {
317
+ async function callOnPrerenderStartHook(prerenderContext) {
318
+ const globalContext = getGlobalContext();
314
319
  let onPrerenderStartHook;
315
320
  // V1 design
316
- if (renderContext.pageConfigs.length > 0) {
321
+ if (globalContext.pageConfigs.length > 0) {
317
322
  const hookName = 'onPrerenderStart';
318
- const hook = getHookFromPageConfigGlobal(renderContext.pageConfigGlobal, hookName);
323
+ const hook = getHookFromPageConfigGlobal(globalContext.pageConfigGlobal, hookName);
319
324
  if (hook) {
320
325
  assert(hook.hookName === 'onPrerenderStart');
321
326
  onPrerenderStartHook = {
@@ -327,9 +332,9 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
327
332
  }
328
333
  // Old design
329
334
  // TODO/v1-release: remove
330
- if (renderContext.pageConfigs.length === 0) {
335
+ if (globalContext.pageConfigs.length === 0) {
331
336
  const hookTimeout = getHookTimeoutDefault('onBeforePrerender');
332
- const pageFilesWithOnBeforePrerenderHook = renderContext.pageFilesAll.filter((p) => {
337
+ const pageFilesWithOnBeforePrerenderHook = globalContext.pageFilesAll.filter((p) => {
333
338
  assertExportNames(p);
334
339
  if (!p.exportNames?.includes('onBeforePrerender'))
335
340
  return false;
@@ -517,27 +522,28 @@ function warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerende
517
522
  assertWarning(false, `The ${providedByHook.hookName}() hook defined by ${providedByHook.hookFilePath} returns the URL ${pc.cyan(urlOriginal)}, while ${setByConfigFile} sets the config ${pc.cyan(setByConfigName)} to ${pc.cyan(String(setByConfigValue))}. This is contradictory: either don't set the config ${pc.cyan(setByConfigName)} to ${pc.cyan(String(setByConfigValue))} or remove the URL ${pc.cyan(urlOriginal)} from the list of URLs to be pre-rendered.`, { onlyOnce: true });
518
523
  });
519
524
  }
520
- function warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial) {
521
- const isV1 = renderContext.pageConfigs.length > 0;
525
+ function warnMissingPages(prerenderedPageContexts, doNotPrerenderList, partial) {
526
+ const globalContext = getGlobalContext();
527
+ const isV1 = globalContext.pageConfigs.length > 0;
522
528
  const hookName = isV1 ? 'onBeforePrerenderStart' : 'prerender';
523
529
  /* TODO/after-v1-design-release: document setting `prerender: false` as an alternative to using prerender.partial (both in the warnings and the docs)
524
530
  const optOutName = isV1 ? 'prerender' : 'doNotPrerender'
525
531
  const msgAddendum = `Explicitly opt-out by setting the config ${optOutName} to ${isV1 ? 'false' : 'true'} or use the option prerender.partial`
526
532
  */
527
- renderContext.allPageIds
533
+ globalContext.allPageIds
528
534
  .filter((pageId) => !prerenderedPageContexts[pageId])
529
535
  .filter((pageId) => !doNotPrerenderList.find((p) => p.pageId === pageId))
530
- .filter((pageId) => !isErrorPage(pageId, renderContext.pageConfigs))
536
+ .filter((pageId) => !isErrorPage(pageId, globalContext.pageConfigs))
531
537
  .forEach((pageId) => {
532
538
  const pageAt = isV1 ? pageId : `\`${pageId}.page.*\``;
533
539
  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 });
534
540
  });
535
541
  }
536
- async function prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete) {
542
+ async function prerender404(prerenderedPageContexts, prerenderContext, onComplete) {
537
543
  if (!Object.values(prerenderedPageContexts).find(({ urlOriginal }) => urlOriginal === '/404')) {
538
544
  let result;
539
545
  try {
540
- result = await prerender404Page(renderContext, prerenderContext.pageContextInit);
546
+ result = await prerender404Page(prerenderContext.pageContextInit);
541
547
  }
542
548
  catch (err) {
543
549
  assertIsNotAbort(err, 'the 404 page');
@@ -717,3 +723,38 @@ function makePageContextComputedUrlNonEnumerable(pageContexts) {
717
723
  });
718
724
  }
719
725
  }
726
+ function validatePrerenderConfig(
727
+ // Guaranteed by configDef.type to be either an object or boolean
728
+ prerenderConfig) {
729
+ if (!prerenderConfig || typeof prerenderConfig === 'boolean')
730
+ return;
731
+ assert(isObject(prerenderConfig));
732
+ const wrongValue = (() => {
733
+ {
734
+ const p = 'partial';
735
+ if (!hasProp(prerenderConfig, p, 'boolean') && !hasProp(prerenderConfig, p, 'undefined'))
736
+ return { prop: p, errMsg: 'should be a boolean' };
737
+ }
738
+ {
739
+ const p = 'noExtraDir';
740
+ if (!hasProp(prerenderConfig, p, 'boolean') && !hasProp(prerenderConfig, p, 'undefined'))
741
+ return { prop: p, errMsg: 'should be a boolean' };
742
+ }
743
+ {
744
+ const p = 'disableAutoRun';
745
+ if (!hasProp(prerenderConfig, p, 'boolean') && !hasProp(prerenderConfig, p, 'undefined'))
746
+ return { prop: p, errMsg: 'should be a boolean' };
747
+ }
748
+ {
749
+ const p = 'parallel';
750
+ if (!hasProp(prerenderConfig, p, 'boolean') &&
751
+ !hasProp(prerenderConfig, p, 'number') &&
752
+ !hasProp(prerenderConfig, p, 'undefined'))
753
+ return { prop: p, errMsg: 'should be a boolean or a number' };
754
+ }
755
+ })();
756
+ if (wrongValue) {
757
+ const { prop, errMsg } = wrongValue;
758
+ assertUsage(false, `Setting ${pc.cyan(`prerender.${prop}`)} ${errMsg}`);
759
+ }
760
+ }