vike 0.4.223-commit-59f3966 → 0.4.223-commit-535bde1

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 (34) hide show
  1. package/dist/cjs/node/api/prepareViteApiCall.js +0 -1
  2. package/dist/cjs/node/plugin/plugins/commonConfig.js +2 -1
  3. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +2 -1
  4. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +113 -71
  5. package/dist/cjs/node/prerender/context.js +3 -8
  6. package/dist/cjs/node/prerender/resolvePrerenderConfig.js +23 -21
  7. package/dist/cjs/node/prerender/runPrerender.js +24 -28
  8. package/dist/cjs/node/prerender/utils.js +1 -0
  9. package/dist/cjs/shared/page-configs/getConfigValueBuildTime.js +2 -2
  10. package/dist/cjs/shared/page-configs/serialize/parsePageConfigs.js +3 -1
  11. package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +1 -1
  12. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  13. package/dist/esm/node/api/prepareViteApiCall.js +0 -1
  14. package/dist/esm/node/plugin/plugins/commonConfig.js +3 -2
  15. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +2 -1
  16. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +113 -71
  17. package/dist/esm/node/prerender/context.d.ts +0 -2
  18. package/dist/esm/node/prerender/context.js +4 -9
  19. package/dist/esm/node/prerender/resolvePrerenderConfig.d.ts +10 -6
  20. package/dist/esm/node/prerender/resolvePrerenderConfig.js +24 -22
  21. package/dist/esm/node/prerender/runPrerender.d.ts +7 -25
  22. package/dist/esm/node/prerender/runPrerender.js +25 -29
  23. package/dist/esm/node/prerender/utils.d.ts +1 -0
  24. package/dist/esm/node/prerender/utils.js +1 -0
  25. package/dist/esm/node/runtime/globalContext.d.ts +2 -1
  26. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +165 -5
  27. package/dist/esm/shared/page-configs/Config.d.ts +8 -0
  28. package/dist/esm/shared/page-configs/getConfigValueBuildTime.js +2 -2
  29. package/dist/esm/shared/page-configs/serialize/parsePageConfigs.js +3 -1
  30. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +1 -1
  31. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  32. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  33. package/dist/esm/utils/projectInfo.d.ts +1 -1
  34. package/package.json +2 -2
@@ -142,7 +142,7 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
142
142
  const configDefinitionsResolved = await resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache);
143
143
  assertKnownConfigs(configDefinitionsResolved, plusFilesAll);
144
144
  const { pageConfigGlobal, pageConfigs } = getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRootDir);
145
- // interop vike(options) in vite.config.js
145
+ // Backwards compatibility for vike(options) in vite.config.js
146
146
  temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir);
147
147
  // global
148
148
  const pageConfigGlobalValues = getConfigValues(pageConfigGlobal);
@@ -155,9 +155,7 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
155
155
  return { pageConfigs, pageConfigGlobal, global, pages };
156
156
  }
157
157
  async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache) {
158
- const configDefinitionsGlobal = getConfigDefinitions(
159
- // We use `plusFilesAll` in order to allow local Vike extensions to create global configs.
160
- sortForGlobal(plusFilesAll), (configDef) => !!configDef.global);
158
+ const configDefinitionsGlobal = getConfigDefinitions(sortAfterInheritanceOrderGlobal(plusFilesAll), (configDef) => !!configDef.global);
161
159
  await loadCustomConfigBuildTimeFiles(plusFilesAll, configDefinitionsGlobal, userRootDir, esbuildCache);
162
160
  const configDefinitionsLocal = {};
163
161
  await Promise.all(objectEntries(plusFilesAll).map(async ([locationId, plusFiles]) => {
@@ -193,13 +191,13 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
193
191
  configValueSources: {}
194
192
  };
195
193
  objectEntries(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
196
- const sources = resolveConfigValueSources(configName, configDef,
197
- // We use `plusFilesAll` in order to allow local Vike extensions to set the value of global configs (e.g. `vite`).
198
- sortForGlobal(plusFilesAll), userRootDir, true);
194
+ const sources = resolveConfigValueSources(configName, configDef, sortAfterInheritanceOrderGlobal(plusFilesAll), userRootDir, true);
199
195
  if (sources.length === 0)
200
196
  return;
201
197
  pageConfigGlobal.configValueSources[configName] = sources;
202
198
  });
199
+ applyEffectsMetaEnv(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
200
+ applyEffectsConfVal(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
203
201
  assertPageConfigGlobal(pageConfigGlobal, plusFilesAll);
204
202
  const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
205
203
  .filter(([_locationId, { plusFiles }]) => isDefiningPage(plusFiles))
@@ -216,7 +214,8 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
216
214
  configValueSources[configName] = sources;
217
215
  });
218
216
  const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
219
- applyEffectsAll(configValueSources, configDefinitionsLocal);
217
+ applyEffectsMetaEnv(configValueSources, configDefinitionsLocal);
218
+ applyEffectsConfVal(configValueSources, configDefinitionsLocal);
220
219
  const configValuesComputed = getComputed(configValueSources, configDefinitionsLocal);
221
220
  const pageConfig = {
222
221
  pageId: locationId,
@@ -359,18 +358,18 @@ function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, use
359
358
  });
360
359
  });
361
360
  }
361
+ // Together with getPlusFilesOrdered() this implements the whole config inheritance ordering for non-global configs. See sortAfterInheritanceOrderGlobal() for global configs.
362
362
  function getPlusFilesRelevant(plusFilesAll, locationIdPage) {
363
363
  const plusFilesRelevant = Object.fromEntries(objectEntries(plusFilesAll)
364
364
  .filter(([locationId]) => {
365
365
  return isInherited(locationId, locationIdPage);
366
366
  })
367
- // Sort after config inheritance.
368
- // - Together with getPlusFilesOrdered() this implements the whole order of config inheritance.
369
- // - See sortForGlobal() for global configs order.
370
367
  .sort(([locationId1], [locationId2]) => sortAfterInheritanceOrder(locationId1, locationId2, locationIdPage)));
371
368
  return plusFilesRelevant;
372
369
  }
373
- function sortForGlobal(plusFilesAll) {
370
+ // This implements the whole config inheritance ordering for global configs.
371
+ // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
372
+ function sortAfterInheritanceOrderGlobal(plusFilesAll) {
374
373
  const plusFilesAllSorted = Object.fromEntries(objectEntries(plusFilesAll)
375
374
  .sort(lowerFirst(([locationId]) => locationId.split('/').length))
376
375
  .sort(makeFirst(([locationId]) => isGlobalLocation(locationId, plusFilesAll))));
@@ -384,22 +383,20 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
384
383
  return configValueSource;
385
384
  });
386
385
  if (isCallable(configDef.global)) {
387
- const isGlobalValue = configDef.global;
388
386
  assert(configDef.env.config);
389
387
  sources = sources.filter((source) => {
390
388
  assert(source.configEnv.config);
391
389
  assert(source.valueIsLoaded);
392
- const valueIsGlobal = isGlobalValue(source.value);
390
+ const valueIsGlobal = resolveIsGlobalValue(configDef.global, source.value);
393
391
  return isGlobal ? valueIsGlobal : !valueIsGlobal;
394
392
  });
395
393
  }
396
394
  return sources;
397
395
  }
398
- // Together with sortAfterInheritanceOrder() this implements the whole order of config inheritance.
396
+ // Together with getPlusFilesRelevant() this implements the whole config inheritance ordering.
399
397
  function getPlusFilesOrdered(configName, plusFilesRelevant) {
400
398
  const plusFilesOrdered = [];
401
- // `plusFilesRelevant` is already sorted by sortAfterInheritanceOrder() at getPlusFilesRelevant()
402
- // `plusFilesAtLocationId` is already sorted by sortMakeDeterministic() at getPlusFilesAll()
399
+ // `plusFilesRelevant` is already deterministic, see sortMakeDeterministic() at getPlusFilesAll()
403
400
  for (const plusFilesAtLocationId of Object.values(plusFilesRelevant)) {
404
401
  const plusFilesForConfigName = plusFilesAtLocationId.filter((plusFile) => getDefiningConfigNames(plusFile).includes(configName));
405
402
  // We populate `plusFilesOrdered` with inheritance order.
@@ -576,6 +573,15 @@ function isDefiningPage(plusFiles) {
576
573
  function isDefiningPageConfig(configName) {
577
574
  return ['Page', 'route'].includes(configName);
578
575
  }
576
+ function resolveIsGlobalValue(configDefGlobal, configValue) {
577
+ let isGlobal;
578
+ if (isCallable(configDefGlobal))
579
+ isGlobal = configDefGlobal(configValue);
580
+ else
581
+ isGlobal = configDefGlobal ?? false;
582
+ assert(typeof isGlobal === 'boolean');
583
+ return isGlobal;
584
+ }
579
585
  function getDefiningConfigNames(plusFile) {
580
586
  let configNames = [];
581
587
  if (!plusFile.isConfigFile) {
@@ -660,67 +666,103 @@ function assertMetaUsage(metaVal, metaConfigDefinedAt) {
660
666
  }
661
667
  });
662
668
  }
663
- function applyEffectsAll(configValueSources, configDefinitions) {
664
- objectEntries(configDefinitions).forEach(([configName, configDef]) => {
665
- if (!configDef.effect)
669
+ // Test: https://github.com/vikejs/vike/blob/441a37c4c1a3b07bb8f6efb1d1f7be297a53974a/test/playground/vite.config.ts#L39
670
+ function applyEffectsConfVal(configValueSources, configDefinitions) {
671
+ objectEntries(configDefinitions).forEach(([configNameEffect, configDefEffect]) => {
672
+ const sourceEffect = configValueSources[configNameEffect]?.[0];
673
+ if (!sourceEffect)
666
674
  return;
667
- // The value needs to be loaded at config time, that's why we only support effect for configs that are config-only for now.
668
- // (We could support effect for non config-only by always loading its value at config time, regardless of the config's `env` value.)
669
- assertUsage(configDef.env.config, [
670
- `Cannot add effect to ${pc.cyan(configName)} because its ${pc.cyan('env')} is ${pc.cyan(JSON.stringify(configDef.env))}: effects can only be added to configs with an ${pc.cyan('env')} with ${pc.cyan('{ config: true }')}.`
671
- ].join(' '));
672
- const source = configValueSources[configName]?.[0];
673
- if (!source)
675
+ const effect = runEffect(configNameEffect, configDefEffect, sourceEffect);
676
+ if (!effect)
674
677
  return;
675
- // The config value is eagerly loaded since `configDef.env === 'config-only``
676
- assert('value' in source);
677
- // Call effect
678
- const configModFromEffect = configDef.effect({
679
- configValue: source.value,
680
- configDefinedAt: getConfigDefinedAt('Config', configName, source.definedAtFilePath)
681
- });
682
- if (!configModFromEffect)
678
+ const { configModFromEffect, configValueEffectSource } = effect;
679
+ applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, configValueEffectSource);
680
+ });
681
+ }
682
+ // Test: https://github.com/vikejs/vike/blob/441a37c4c1a3b07bb8f6efb1d1f7be297a53974a/test/playground/pages/config-meta/effect/e2e-test.ts#L16
683
+ function applyEffectsMetaEnv(configValueSources, configDefinitions) {
684
+ objectEntries(configDefinitions).forEach(([configNameEffect, configDefEffect]) => {
685
+ const sourceEffect = configValueSources[configNameEffect]?.[0];
686
+ if (!sourceEffect)
687
+ return;
688
+ const effect = runEffect(configNameEffect, configDefEffect, sourceEffect);
689
+ if (!effect)
683
690
  return;
684
- assert(hasProp(source, 'value')); // We need to assume that the config value is loaded at build-time
685
- applyEffect(configModFromEffect, configValueSources, configDef);
691
+ const { configModFromEffect } = effect;
692
+ applyEffectMetaEnv(configModFromEffect, configValueSources, configDefEffect);
686
693
  });
687
694
  }
688
- function applyEffect(configModFromEffect, configValueSources, configDefEffect) {
689
- const notSupported = `Effects currently only supports modifying the the ${pc.cyan('env')} of a config.`;
690
- objectEntries(configModFromEffect).forEach(([configName, configValue]) => {
691
- if (configName === 'meta') {
692
- let configDefinedAt;
693
- if (configDefEffect._userEffectDefinedAtFilePath) {
694
- configDefinedAt = getConfigDefinedAt('Config', configName, configDefEffect._userEffectDefinedAtFilePath);
695
- }
696
- else {
697
- configDefinedAt = null;
698
- }
699
- assertMetaUsage(configValue, configDefinedAt);
700
- objectEntries(configValue).forEach(([configTargetName, configTargetDef]) => {
701
- {
702
- const keys = Object.keys(configTargetDef);
703
- assertUsage(keys.includes('env'), notSupported);
704
- assertUsage(keys.length === 1, notSupported);
705
- }
706
- const envOverriden = configTargetDef.env;
707
- const sources = configValueSources[configTargetName];
708
- sources?.forEach((configValueSource) => {
709
- // Apply effect
710
- configValueSource.configEnv = envOverriden;
711
- });
712
- });
695
+ function runEffect(configName, configDef, source) {
696
+ if (!configDef.effect)
697
+ return null;
698
+ // The value needs to be loaded at config time, that's why we only support effect for configs that are config-only for now.
699
+ assertUsage(configDef.env.config, [
700
+ `Cannot add meta.effect to ${pc.cyan(configName)} because its meta.env is ${pc.cyan(JSON.stringify(configDef.env))} but an effect can only be added to a config that has a meta.env with ${pc.cyan('{ config: true }')}.`
701
+ ].join(' '));
702
+ assert(source.valueIsLoaded);
703
+ const configValueEffectSource = source.value;
704
+ // Call effect
705
+ const configModFromEffect = configDef.effect({
706
+ configValue: configValueEffectSource,
707
+ configDefinedAt: getConfigDefinedAt('Config', configName, source.definedAtFilePath)
708
+ });
709
+ if (!configModFromEffect)
710
+ return null;
711
+ return { configModFromEffect, configValueEffectSource };
712
+ }
713
+ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, configValueEffectSource) {
714
+ objectEntries(configModFromEffect).forEach(([configNameTarget, configValue]) => {
715
+ if (configNameTarget === 'meta')
716
+ return;
717
+ const configDef = configDefinitions[configNameTarget];
718
+ assert(configDef);
719
+ assert(configDefEffect._userEffectDefinedAtFilePath);
720
+ const configValueSource = {
721
+ definedAtFilePath: configDefEffect._userEffectDefinedAtFilePath,
722
+ plusFile: sourceEffect.plusFile,
723
+ locationId: sourceEffect.locationId,
724
+ configEnv: configDef.env,
725
+ isOverriden: false, // TODO/now check
726
+ valueIsLoadedWithImport: false,
727
+ valueIsDefinedByPlusValueFile: false,
728
+ valueIsLoaded: true,
729
+ value: configValue
730
+ };
731
+ const isValueGlobalSource = resolveIsGlobalValue(configDefEffect.global, configValueEffectSource);
732
+ const isValueGlobalTarget = resolveIsGlobalValue(configDef.global, configValue);
733
+ const isGlobalHumanReadable = (isGlobal) => `${isGlobal ? 'non-' : ''}global`;
734
+ // The error message make it sound like it's an inherent limitation, it actually isn't (both ways can make senses).
735
+ assertUsage(isValueGlobalSource === isValueGlobalTarget, `The configuration ${pc.cyan(configNameEffect)} is set to ${pc.cyan(JSON.stringify(configValueEffectSource))} which is considered ${isGlobalHumanReadable(isValueGlobalSource)}. However, it has a meta.effect that sets the configuration ${pc.cyan(configNameTarget)} to ${pc.cyan(JSON.stringify(configValue))} which is considered ${isGlobalHumanReadable(isValueGlobalTarget)}. This is contradictory: make sure the values are either both non-global or both global.`);
736
+ configValueSources[configNameTarget] ?? (configValueSources[configNameTarget] = []);
737
+ configValueSources[configNameTarget].push(configValueSource);
738
+ });
739
+ }
740
+ function applyEffectMetaEnv(configModFromEffect, configValueSources, configDefEffect) {
741
+ const notSupported = `${pc.cyan('meta.effect')} currently only supports setting the value of a config, or modifying the ${pc.cyan('meta.env')} of a config.`;
742
+ objectEntries(configModFromEffect).forEach(([configNameTarget, configValue]) => {
743
+ if (configNameTarget !== 'meta')
744
+ return;
745
+ let configDefinedAt;
746
+ if (configDefEffect._userEffectDefinedAtFilePath) {
747
+ configDefinedAt = getConfigDefinedAt('Config', configNameTarget, configDefEffect._userEffectDefinedAtFilePath);
713
748
  }
714
749
  else {
715
- assertUsage(false, notSupported);
716
- /* To implement being able to set a config value in an effect:
717
- * - Copy and append definedAtFile.fileExportPathToShowToUser with ['meta', configName, 'effect']
718
- * - Copying the definedAtFile of the config that defines the effect
719
- * - Same precedence as the config that sets the value triggering the effect (not the config defining the effect)
720
- * - Apply sortConfigValueSources() again?
721
- configValueSources.push()
722
- */
750
+ configDefinedAt = null;
723
751
  }
752
+ assertMetaUsage(configValue, configDefinedAt);
753
+ objectEntries(configValue).forEach(([configTargetName, configTargetDef]) => {
754
+ {
755
+ const keys = Object.keys(configTargetDef);
756
+ assertUsage(keys.includes('env'), notSupported);
757
+ assertUsage(keys.length === 1, notSupported);
758
+ }
759
+ const envOverriden = configTargetDef.env;
760
+ const sources = configValueSources[configTargetName];
761
+ sources?.forEach((configValueSource) => {
762
+ // Apply effect
763
+ configValueSource.configEnv = envOverriden;
764
+ });
765
+ });
724
766
  });
725
767
  }
726
768
  function getComputed(configValueSources, configDefinitions) {
@@ -834,7 +876,7 @@ function determineRouteFilesystem(locationId, configValueSources) {
834
876
  function getFilesystemRoutingRootEffect(configFilesystemRoutingRoot, configName) {
835
877
  assert(configFilesystemRoutingRoot.configEnv.config);
836
878
  // Eagerly loaded since it's config-only
837
- assert('value' in configFilesystemRoutingRoot);
879
+ assert(configFilesystemRoutingRoot.valueIsLoaded);
838
880
  const { value } = configFilesystemRoutingRoot;
839
881
  const configDefinedAt = getConfigDefinedAt('Config', configName, configFilesystemRoutingRoot.definedAtFilePath);
840
882
  assertUsage(typeof value === 'string', `${configDefinedAt} should be a string`);
@@ -1,10 +1,8 @@
1
- export { isPrerenderEnabled };
2
1
  export { isPrerenderAutoRunEnabled };
3
2
  export { temp_disablePrerenderAutoRun };
4
3
  export { isPrerendering };
5
4
  export { setContextIsPrerendering };
6
5
  import type { VikeConfigObject } from '../plugin/plugins/importUserCode/v1-design/getVikeConfig.js';
7
- declare function isPrerenderEnabled(vikeConfig: VikeConfigObject): boolean;
8
6
  declare function isPrerenderAutoRunEnabled(vikeConfig: VikeConfigObject): boolean;
9
7
  declare function temp_disablePrerenderAutoRun(): void;
10
8
  declare function isPrerendering(): boolean;
@@ -1,19 +1,14 @@
1
- export { isPrerenderEnabled };
2
1
  export { isPrerenderAutoRunEnabled };
3
2
  export { temp_disablePrerenderAutoRun };
4
3
  export { isPrerendering };
5
4
  export { setContextIsPrerendering };
6
5
  import { getGlobalObject } from '../../utils/getGlobalObject.js';
7
- import { resolvePrerenderConfig } from './resolvePrerenderConfig.js';
6
+ import { resolvePrerenderConfigGlobal } from './resolvePrerenderConfig.js';
8
7
  const globalObject = getGlobalObject('prerender/context.ts', {});
9
- function isPrerenderEnabled(vikeConfig) {
10
- const prerenderConfig = resolvePrerenderConfig(vikeConfig);
11
- return !!prerenderConfig;
12
- }
13
8
  function isPrerenderAutoRunEnabled(vikeConfig) {
14
- const prerenderConfig = resolvePrerenderConfig(vikeConfig);
15
- return (isPrerenderEnabled(vikeConfig) &&
16
- !(prerenderConfig || {}).disableAutoRun &&
9
+ const prerenderConfigGlobal = resolvePrerenderConfigGlobal(vikeConfig);
10
+ return (prerenderConfigGlobal.isEnabled &&
11
+ !(prerenderConfigGlobal || {}).disableAutoRun &&
17
12
  !globalObject.isDisabled &&
18
13
  vikeConfig.global.config.disableAutoFullBuild !== 'prerender');
19
14
  }
@@ -1,12 +1,16 @@
1
- export { resolvePrerenderConfig };
1
+ export { resolvePrerenderConfigGlobal };
2
2
  export { resolvePrerenderConfigLocal };
3
- import type { ConfigResolved } from '../../shared/page-configs/Config/PageContextConfig.js';
4
3
  import { VikeConfigObject } from '../plugin/plugins/importUserCode/v1-design/getVikeConfig.js';
5
4
  import type { PageConfigBuildTime } from '../../shared/page-configs/PageConfig.js';
6
- type PrerenderConfigSemiResolved = ConfigResolved['prerender'];
7
- type PrerenderConfig = false | Exclude<Required<NonNullable<PrerenderConfigSemiResolved>[number]>, boolean>;
8
- declare function resolvePrerenderConfig(vikeConfig: VikeConfigObject): PrerenderConfig;
5
+ declare function resolvePrerenderConfigGlobal(vikeConfig: VikeConfigObject): {
6
+ partial: boolean;
7
+ noExtraDir: boolean;
8
+ parallel: number | boolean;
9
+ disableAutoRun: boolean;
10
+ } & {
11
+ defaultLocalValue: boolean;
12
+ isEnabled: boolean;
13
+ };
9
14
  declare function resolvePrerenderConfigLocal(pageConfig: PageConfigBuildTime): {
10
15
  value: boolean;
11
- configValueFilePathToShowToUser: string;
12
16
  } | null;
@@ -1,27 +1,30 @@
1
- export { resolvePrerenderConfig };
1
+ export { resolvePrerenderConfigGlobal };
2
2
  export { resolvePrerenderConfigLocal };
3
- import { assert, isArray } from './utils.js';
3
+ import { assert, isArray, objectAssign } from './utils.js';
4
4
  import { getConfigValueBuildTime } from '../../shared/page-configs/getConfigValueBuildTime.js';
5
- import { getConfigValueFilePathToShowToUser } from '../../shared/page-configs/helpers.js';
6
- // TODO/now:
7
- // - prerender.value
8
- function resolvePrerenderConfig(vikeConfig) {
5
+ function resolvePrerenderConfigGlobal(vikeConfig) {
9
6
  const prerenderConfigs = vikeConfig.global.config.prerender;
10
- if (!prerenderConfigs &&
11
- !vikeConfig.pageConfigs.some((pageConfig) => resolvePrerenderConfigLocal(pageConfig)?.value)) {
12
- return false;
13
- }
14
- let prerenderSettings = prerenderConfigs || [];
7
+ let prerenderConfigList = prerenderConfigs || [];
15
8
  // Needed because of backwards compatibility of `vike({prerender:true})` in `vite.config.js`; after we remove it we can remove this line.
16
- prerenderSettings = prerenderSettings.filter(isObject2);
17
- assert(prerenderSettings.every(isObject2));
18
- const prerenderConfig = {
19
- partial: pickFirst(prerenderSettings.map((c) => c.partial)) ?? false,
20
- noExtraDir: pickFirst(prerenderSettings.map((c) => c.noExtraDir)) ?? false,
21
- parallel: pickFirst(prerenderSettings.map((c) => c.parallel)) ?? true,
22
- disableAutoRun: pickFirst(prerenderSettings.map((c) => c.disableAutoRun)) ?? false
9
+ prerenderConfigList = prerenderConfigList.filter(isObject2);
10
+ assert(prerenderConfigList.every(isObject2)); // Help TS
11
+ const prerenderConfigGlobal = {
12
+ partial: pickFirst(prerenderConfigList.map((c) => c.partial)) ?? false,
13
+ noExtraDir: pickFirst(prerenderConfigList.map((c) => c.noExtraDir)) ?? false,
14
+ parallel: pickFirst(prerenderConfigList.map((c) => c.parallel)) ?? true,
15
+ disableAutoRun: pickFirst(prerenderConfigList.map((c) => c.disableAutoRun)) ?? false
23
16
  };
24
- return prerenderConfig;
17
+ const prerenderConfigGlobalLocalValue = prerenderConfigList.map((c) => c.value).filter((v) => v !== null);
18
+ const defaultLocalValue = pickFirst(prerenderConfigGlobalLocalValue) ??
19
+ (prerenderConfigGlobalLocalValue.length > 0 ||
20
+ // Backwards compatibility for with vike({ prerender: true }) in vite.config.js
21
+ prerenderConfigs?.some((p) => p === true) ||
22
+ false);
23
+ objectAssign(prerenderConfigGlobal, {
24
+ defaultLocalValue,
25
+ isEnabled: defaultLocalValue || vikeConfig.pageConfigs.some((pageConfig) => resolvePrerenderConfigLocal(pageConfig)?.value)
26
+ });
27
+ return prerenderConfigGlobal;
25
28
  }
26
29
  function resolvePrerenderConfigLocal(pageConfig) {
27
30
  const configValue = getConfigValueBuildTime(pageConfig, 'prerender');
@@ -32,9 +35,8 @@ function resolvePrerenderConfigLocal(pageConfig) {
32
35
  const value = values[0];
33
36
  assert(typeof value === 'boolean');
34
37
  assert(isArray(configValue.definedAtData));
35
- const configValueFilePathToShowToUser = getConfigValueFilePathToShowToUser(configValue.definedAtData[0]);
36
- assert(configValueFilePathToShowToUser);
37
- return { value, configValueFilePathToShowToUser };
38
+ const prerenderConfigLocal = { value };
39
+ return prerenderConfigLocal;
38
40
  }
39
41
  function isObject2(p) {
40
42
  return typeof p === 'object' && p !== null;
@@ -4,46 +4,24 @@ export { runPrerenderFromAutoRun };
4
4
  export { runPrerender_forceExit };
5
5
  export type { PrerenderOptions };
6
6
  export type { PrerenderContextPublic };
7
- import { PageContextInitEnhanced } from '../runtime/renderPage/renderPageAlreadyRouted.js';
8
7
  import type { InlineConfig, ResolvedConfig } from 'vite';
9
- import { PageContextUrlInternal } from '../../shared/getPageContextUrlComputed.js';
10
8
  import type { APIOptions } from '../api/types.js';
9
+ import type { PageContextServer } from '../../shared/types.js';
11
10
  type ProvidedByHook = null | {
12
11
  hookFilePath: string;
13
12
  hookName: 'onBeforePrerenderStart' | 'prerender';
14
13
  };
15
- type TransformerHook = {
16
- hookFilePath: string;
17
- hookName: 'onPrerenderStart' | 'onBeforePrerender';
18
- };
19
14
  type PageContextPrerendered = {
20
15
  urlOriginal: string;
21
16
  _providedByHook?: ProvidedByHook;
22
17
  };
23
- type PrerenderedPageContexts = Record<string, PageContextPrerendered>;
24
- type PrerenderContext = {
25
- pageContexts: PageContext[];
26
- pageContextInit: Record<string, unknown> | null;
27
- noExtraDir: boolean;
28
- prerenderedPageContexts: PrerenderedPageContexts;
29
- output: Output;
30
- };
31
- type Output = {
18
+ type Output<PageContext = PageContextPrerendered> = {
32
19
  filePath: string;
33
20
  fileType: FileType;
34
21
  fileContent: string;
35
- pageContext: PageContextPrerendered;
22
+ pageContext: PageContext;
36
23
  }[];
37
24
  type FileType = 'HTML' | 'JSON';
38
- type PrerenderContextPublic = Pick<PrerenderContext, 'pageContexts'>;
39
- type PageContext = PageContextInitEnhanced & {
40
- _urlRewrite: null;
41
- _urlHandler: null;
42
- _urlOriginalBeforeHook?: string;
43
- _urlOriginalModifiedByHook?: TransformerHook;
44
- _providedByHook: ProvidedByHook;
45
- _pageContextAlreadyProvidedByOnPrerenderHook?: true;
46
- } & PageContextUrlInternal;
47
25
  type PrerenderOptions = APIOptions & {
48
26
  /** Initial `pageContext` values */
49
27
  pageContextInit?: Record<string, unknown>;
@@ -72,3 +50,7 @@ declare function runPrerenderFromAutoRun(viteConfig: InlineConfig | undefined, c
72
50
  forceExit: boolean;
73
51
  }>;
74
52
  declare function runPrerender_forceExit(): void;
53
+ type PrerenderContextPublic = {
54
+ output: Output<PageContextServer>;
55
+ pageContexts: PageContextServer[];
56
+ };
@@ -26,7 +26,7 @@ import { logErrorHint } from '../runtime/renderPage/logErrorHint.js';
26
26
  import { executeHook, isUserHookError } from '../../shared/hooks/executeHook.js';
27
27
  import { prepareViteApiCall } from '../api/prepareViteApiCall.js';
28
28
  import { setContextIsPrerendering } from './context.js';
29
- import { resolvePrerenderConfig, resolvePrerenderConfigLocal } from './resolvePrerenderConfig.js';
29
+ import { resolvePrerenderConfigGlobal, resolvePrerenderConfigLocal } from './resolvePrerenderConfig.js';
30
30
  import { getOutDirs } from '../plugin/shared/getOutDirs.js';
31
31
  import { isVikeCli } from '../cli/context.js';
32
32
  import { isViteCliCall } from '../plugin/shared/isViteCliCall.js';
@@ -82,15 +82,16 @@ async function runPrerender(options = {}, standaloneTrigger) {
82
82
  const vikeConfig = await getVikeConfig(viteConfig);
83
83
  const { outDirClient } = getOutDirs(viteConfig);
84
84
  const { root } = viteConfig;
85
- const prerenderConfig = resolvePrerenderConfig(vikeConfig);
86
- validatePrerenderConfig(prerenderConfig);
87
- if (!prerenderConfig) {
85
+ const prerenderConfigGlobal = resolvePrerenderConfigGlobal(vikeConfig);
86
+ validatePrerenderConfig(prerenderConfigGlobal);
87
+ const { partial, noExtraDir, parallel, defaultLocalValue, isEnabled } = prerenderConfigGlobal;
88
+ if (!isEnabled) {
88
89
  assert(standaloneTrigger);
89
- assertWarning(prerenderConfig, `You're executing ${pc.cyan(standaloneTrigger)} but the config ${pc.cyan('prerender')} isn't set to true`, {
90
+ // TODO/now: make it assertUsage() and remove dist/server/entry.mjs whenever possible
91
+ assertWarning(prerenderConfigGlobal, `You're executing ${pc.cyan(standaloneTrigger)} but you didn't enable pre-rendering. Use the config ${pc.cyan('prerender')} (${pc.underline('https://vike.dev/prerender')}) to enable it.`, {
90
92
  onlyOnce: true
91
93
  });
92
94
  }
93
- const { partial = false, noExtraDir = false, parallel = true } = prerenderConfig || {};
94
95
  const concurrencyLimit = pLimit(parallel === false || parallel === 0 ? 1 : parallel === true || parallel === undefined ? cpus().length : parallel);
95
96
  await initGlobalContext_runPrerender();
96
97
  const globalContext = await getGlobalContextInternal();
@@ -103,7 +104,7 @@ async function runPrerender(options = {}, standaloneTrigger) {
103
104
  output: []
104
105
  };
105
106
  const doNotPrerenderList = [];
106
- await collectDoNoPrerenderList(vikeConfig.pageConfigs, doNotPrerenderList, concurrencyLimit, globalContext);
107
+ await collectDoNoPrerenderList(vikeConfig.pageConfigs, doNotPrerenderList, defaultLocalValue, concurrencyLimit, globalContext);
107
108
  await callOnBeforePrerenderStartHooks(prerenderContext, globalContext, concurrencyLimit, doNotPrerenderList);
108
109
  await handlePagesWithStaticRoutes(prerenderContext, globalContext, doNotPrerenderList, concurrencyLimit);
109
110
  await callOnPrerenderStartHook(prerenderContext, globalContext);
@@ -126,20 +127,21 @@ async function runPrerender(options = {}, standaloneTrigger) {
126
127
  const prerenderContextPublic = makePublic(prerenderContext);
127
128
  return { viteConfig, prerenderContextPublic };
128
129
  }
129
- async function collectDoNoPrerenderList(pageConfigs, doNotPrerenderList, concurrencyLimit, globalContext) {
130
+ async function collectDoNoPrerenderList(pageConfigs, doNotPrerenderList, defaultLocalValue, concurrencyLimit, globalContext) {
130
131
  // V1 design
131
132
  pageConfigs.forEach((pageConfig) => {
132
- const configValue = resolvePrerenderConfigLocal(pageConfig);
133
- if (!configValue)
134
- return;
135
- const { value, configValueFilePathToShowToUser } = configValue;
136
- if (value === false) {
137
- doNotPrerenderList.push({
138
- pageId: pageConfig.pageId,
139
- setByConfigName: 'prerender',
140
- setByConfigValue: false,
141
- setByConfigFile: configValueFilePathToShowToUser
142
- });
133
+ const prerenderConfigLocal = resolvePrerenderConfigLocal(pageConfig);
134
+ const { pageId } = pageConfig;
135
+ if (!prerenderConfigLocal) {
136
+ if (!defaultLocalValue) {
137
+ doNotPrerenderList.push({ pageId });
138
+ }
139
+ }
140
+ else {
141
+ const { value } = prerenderConfigLocal;
142
+ if (value === false) {
143
+ doNotPrerenderList.push({ pageId });
144
+ }
143
145
  }
144
146
  });
145
147
  // Old design
@@ -172,12 +174,7 @@ async function collectDoNoPrerenderList(pageConfigs, doNotPrerenderList, concurr
172
174
  }
173
175
  else {
174
176
  // Don't pre-render `pageId`
175
- doNotPrerenderList.push({
176
- pageId,
177
- setByConfigFile: p.filePath,
178
- setByConfigName: 'doNotPrerender',
179
- setByConfigValue: doNotPrerender
180
- });
177
+ doNotPrerenderList.push({ pageId });
181
178
  }
182
179
  }
183
180
  });
@@ -530,8 +527,7 @@ function warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerende
530
527
  if (!isContradictory)
531
528
  return;
532
529
  }
533
- const { setByConfigName, setByConfigValue, setByConfigFile } = doNotPrerenderListEntry;
534
- 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 });
530
+ assertWarning(false, `The ${providedByHook.hookName}() hook defined by ${providedByHook.hookFilePath} returns the URL ${pc.cyan(urlOriginal)} matching the route of the page ${pc.cyan(pageId)} which isn't configured to be pre-rendered. This is contradictory: either enable pre-rendering for ${pc.cyan(pageId)} or remove the URL ${pc.cyan(urlOriginal)} from the list of URLs to be pre-rendered.`, { onlyOnce: true });
535
531
  });
536
532
  }
537
533
  async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPrerenderList, partial) {
@@ -778,8 +774,8 @@ prerenderConfig) {
778
774
  }
779
775
  function makePublic(prerenderContext) {
780
776
  const prerenderContextPublic = makePublicCopy(prerenderContext, 'prerenderContext', [
781
- 'pageContexts',
782
- 'output'
777
+ 'output', // vite-plugin-vercel
778
+ 'pageContexts' // https://vike.dev/i18n#pre-rendering
783
779
  ]);
784
780
  return prerenderContextPublic;
785
781
  }
@@ -15,3 +15,4 @@ export * from '../../utils/isArray.js';
15
15
  export * from '../../utils/isObject.js';
16
16
  export * from '../../utils/changeEnumerable.js';
17
17
  export * from '../../utils/makePublicCopy.js';
18
+ export * from '../../utils/isNotNullish.js';
@@ -17,3 +17,4 @@ export * from '../../utils/isArray.js';
17
17
  export * from '../../utils/isObject.js';
18
18
  export * from '../../utils/changeEnumerable.js';
19
19
  export * from '../../utils/makePublicCopy.js';
20
+ export * from '../../utils/isNotNullish.js';
@@ -23,7 +23,6 @@ import type { ResolvedConfig, ViteDevServer } from 'vite';
23
23
  import type { PageConfigUserFriendly, PageConfigsUserFriendly } from '../../shared/page-configs/getPageConfigUserFriendly.js';
24
24
  import type { ConfigVitePluginServerEntry } from '@brillout/vite-plugin-server-entry/plugin';
25
25
  import { type BaseUrlsResolved } from '../shared/resolveBase.js';
26
- type GlobalContextPublic = Pick<GlobalContext, 'assetsManifest' | 'config' | 'viteConfig' | 'pages' | 'baseAssets' | 'baseServer'>;
27
26
  type PageRuntimeInfo = Awaited<ReturnType<typeof getUserFiles>>;
28
27
  type GlobalContextInternal = GlobalContext & {
29
28
  globalContext_public: GlobalContextPublic;
@@ -57,6 +56,8 @@ declare function getGlobalContextInternal(): Promise<GlobalContextInternal>;
57
56
  declare function getGlobalContextSync(): GlobalContextPublic;
58
57
  /** @experimental https://vike.dev/getGlobalContext */
59
58
  declare function getGlobalContextAsync(isProduction: boolean): Promise<GlobalContextPublic>;
59
+ type GlobalContextPublic = ReturnType<typeof makePublic>;
60
+ declare function makePublic(globalContext: GlobalContext): Pick<GlobalContext, "pages" | "baseServer" | "baseAssets" | "config" | "assetsManifest" | "viteConfig">;
60
61
  declare function setGlobalContext_viteDevServer(viteDevServer: ViteDevServer): Promise<void>;
61
62
  declare function setGlobalContext_viteConfig(viteConfig: ResolvedConfig, outDirRoot: string): void;
62
63
  declare function setGlobalContext_isPrerendering(): void;