vike 0.4.224 → 0.4.225-commit-37a36a5

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 (139) hide show
  1. package/dist/cjs/node/api/build.js +1 -1
  2. package/dist/cjs/node/api/context.js +4 -4
  3. package/dist/cjs/node/api/dev.js +1 -1
  4. package/dist/cjs/node/api/prepareViteApiCall.js +3 -2
  5. package/dist/cjs/node/api/prerender.js +1 -1
  6. package/dist/cjs/node/api/preview.js +1 -1
  7. package/dist/cjs/node/cli/context.js +5 -4
  8. package/dist/cjs/node/cli/entry.js +3 -3
  9. package/dist/cjs/node/cli/parseCli.js +43 -15
  10. package/dist/cjs/node/cli/utils.js +1 -1
  11. package/dist/cjs/node/plugin/plugins/build/pluginBuildEntry.js +1 -1
  12. package/dist/cjs/node/plugin/plugins/commonConfig.js +16 -5
  13. package/dist/cjs/node/plugin/plugins/devConfig/determineOptimizeDeps.js +6 -4
  14. package/dist/cjs/node/plugin/plugins/devConfig/index.js +1 -1
  15. package/dist/cjs/node/plugin/plugins/importUserCode/index.js +14 -10
  16. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +10 -2
  17. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +11 -12
  18. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +138 -83
  19. package/dist/cjs/node/plugin/plugins/previewConfig.js +12 -7
  20. package/dist/cjs/node/plugin/plugins/setGlobalContext.js +10 -1
  21. package/dist/cjs/node/plugin/shared/addSsrMiddleware.js +5 -1
  22. package/dist/cjs/node/plugin/shared/getEnvVarObject.js +9 -8
  23. package/dist/cjs/node/plugin/shared/loggerNotProd/log.js +1 -1
  24. package/dist/cjs/node/prerender/context.js +1 -1
  25. package/dist/cjs/node/prerender/resolvePrerenderConfig.js +33 -18
  26. package/dist/cjs/node/prerender/runPrerender.js +6 -8
  27. package/dist/cjs/node/prerender/utils.js +1 -1
  28. package/dist/cjs/node/runtime/globalContext.js +9 -5
  29. package/dist/cjs/node/runtime/html/injectAssets/getViteDevScript.js +6 -3
  30. package/dist/cjs/node/runtime/html/stream.js +7 -0
  31. package/dist/cjs/node/runtime/renderPage/createHttpResponse/assertNoInfiniteHttpRedirect.js +14 -5
  32. package/dist/cjs/node/runtime/renderPage/createHttpResponse.js +2 -4
  33. package/dist/cjs/node/runtime/renderPage/logErrorHint.js +6 -1
  34. package/dist/cjs/node/runtime/renderPage.js +6 -10
  35. package/dist/cjs/node/runtime/utils.js +0 -1
  36. package/dist/cjs/node/runtime-dev/createDevMiddleware.js +10 -8
  37. package/dist/cjs/node/shared/assertV1Design.js +2 -1
  38. package/dist/cjs/node/shared/utils.js +0 -1
  39. package/dist/cjs/shared/page-configs/getConfigDefinedAt.js +19 -2
  40. package/dist/cjs/shared/page-configs/getConfigValueBuildTime.js +8 -5
  41. package/dist/cjs/shared/page-configs/helpers.js +1 -1
  42. package/dist/cjs/shared/page-configs/serialize/parsePageConfigs.js +2 -5
  43. package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +9 -5
  44. package/dist/cjs/shared/route/loadPageRoutes.js +2 -2
  45. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  46. package/dist/cjs/utils/assert.js +11 -4
  47. package/dist/cjs/utils/assertSingleInstance.js +11 -17
  48. package/dist/cjs/utils/debug.js +2 -1
  49. package/dist/cjs/utils/getRandomId.js +1 -1
  50. package/dist/cjs/utils/normalizeHeaders.js +1 -1
  51. package/dist/cjs/utils/parseUrl-extras.js +1 -0
  52. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
  53. package/dist/esm/client/client-routing-runtime/createPageContext.js +2 -2
  54. package/dist/esm/node/api/build.js +1 -1
  55. package/dist/esm/node/api/context.d.ts +8 -2
  56. package/dist/esm/node/api/context.js +4 -4
  57. package/dist/esm/node/api/dev.js +1 -1
  58. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -2
  59. package/dist/esm/node/api/prepareViteApiCall.js +3 -2
  60. package/dist/esm/node/api/prerender.js +1 -1
  61. package/dist/esm/node/api/preview.js +1 -1
  62. package/dist/esm/node/api/types.d.ts +7 -0
  63. package/dist/esm/node/cli/context.d.ts +4 -2
  64. package/dist/esm/node/cli/context.js +5 -4
  65. package/dist/esm/node/cli/entry.js +4 -4
  66. package/dist/esm/node/cli/parseCli.d.ts +3 -0
  67. package/dist/esm/node/cli/parseCli.js +44 -16
  68. package/dist/esm/node/cli/utils.d.ts +1 -1
  69. package/dist/esm/node/cli/utils.js +1 -1
  70. package/dist/esm/node/plugin/plugins/build/pluginBuildEntry.js +2 -2
  71. package/dist/esm/node/plugin/plugins/commonConfig.d.ts +1 -0
  72. package/dist/esm/node/plugin/plugins/commonConfig.js +16 -5
  73. package/dist/esm/node/plugin/plugins/devConfig/determineOptimizeDeps.js +6 -4
  74. package/dist/esm/node/plugin/plugins/devConfig/index.js +1 -1
  75. package/dist/esm/node/plugin/plugins/importUserCode/index.js +15 -11
  76. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.d.ts +3 -1
  77. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +10 -2
  78. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.d.ts +5 -2
  79. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +11 -12
  80. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +3 -2
  81. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +140 -84
  82. package/dist/esm/node/plugin/plugins/previewConfig.js +12 -7
  83. package/dist/esm/node/plugin/plugins/setGlobalContext.js +11 -2
  84. package/dist/esm/node/plugin/shared/addSsrMiddleware.d.ts +1 -1
  85. package/dist/esm/node/plugin/shared/addSsrMiddleware.js +5 -1
  86. package/dist/esm/node/plugin/shared/getEnvVarObject.d.ts +3 -1
  87. package/dist/esm/node/plugin/shared/getEnvVarObject.js +9 -8
  88. package/dist/esm/node/plugin/shared/loggerNotProd/log.js +2 -2
  89. package/dist/esm/node/prerender/context.js +1 -1
  90. package/dist/esm/node/prerender/resolvePrerenderConfig.d.ts +2 -1
  91. package/dist/esm/node/prerender/resolvePrerenderConfig.js +34 -19
  92. package/dist/esm/node/prerender/runPrerender.js +7 -9
  93. package/dist/esm/node/prerender/utils.d.ts +1 -1
  94. package/dist/esm/node/prerender/utils.js +1 -1
  95. package/dist/esm/node/runtime/globalContext.d.ts +1 -1
  96. package/dist/esm/node/runtime/globalContext.js +10 -6
  97. package/dist/esm/node/runtime/html/injectAssets/getViteDevScript.js +6 -3
  98. package/dist/esm/node/runtime/html/stream.js +7 -0
  99. package/dist/esm/node/runtime/index-deprecated.d.ts +1 -3
  100. package/dist/esm/node/runtime/renderPage/createHttpResponse/assertNoInfiniteHttpRedirect.d.ts +3 -1
  101. package/dist/esm/node/runtime/renderPage/createHttpResponse/assertNoInfiniteHttpRedirect.js +15 -6
  102. package/dist/esm/node/runtime/renderPage/createHttpResponse.d.ts +3 -1
  103. package/dist/esm/node/runtime/renderPage/createHttpResponse.js +2 -4
  104. package/dist/esm/node/runtime/renderPage/logErrorHint.js +6 -1
  105. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +5 -5
  106. package/dist/esm/node/runtime/renderPage.js +7 -11
  107. package/dist/esm/node/runtime/utils.d.ts +0 -1
  108. package/dist/esm/node/runtime/utils.js +0 -1
  109. package/dist/esm/node/runtime-dev/createDevMiddleware.js +10 -8
  110. package/dist/esm/node/shared/assertV1Design.js +2 -1
  111. package/dist/esm/node/shared/utils.d.ts +0 -1
  112. package/dist/esm/node/shared/utils.js +0 -1
  113. package/dist/esm/shared/page-configs/Config.d.ts +19 -1
  114. package/dist/esm/shared/page-configs/PageConfig.d.ts +16 -5
  115. package/dist/esm/shared/page-configs/getConfigDefinedAt.d.ts +5 -3
  116. package/dist/esm/shared/page-configs/getConfigDefinedAt.js +20 -3
  117. package/dist/esm/shared/page-configs/getConfigValueBuildTime.js +8 -5
  118. package/dist/esm/shared/page-configs/helpers.js +1 -1
  119. package/dist/esm/shared/page-configs/serialize/parsePageConfigs.d.ts +1 -1
  120. package/dist/esm/shared/page-configs/serialize/parsePageConfigs.js +2 -5
  121. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.d.ts +3 -3
  122. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +9 -5
  123. package/dist/esm/shared/route/loadPageRoutes.js +2 -2
  124. package/dist/esm/shared/types.d.ts +5 -1
  125. package/dist/esm/types/index.d.ts +2 -0
  126. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  127. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  128. package/dist/esm/utils/assert.d.ts +2 -1
  129. package/dist/esm/utils/assert.js +11 -4
  130. package/dist/esm/utils/assertSingleInstance.js +11 -17
  131. package/dist/esm/utils/debug.js +2 -1
  132. package/dist/esm/utils/getRandomId.d.ts +1 -1
  133. package/dist/esm/utils/getRandomId.js +1 -1
  134. package/dist/esm/utils/normalizeHeaders.js +1 -1
  135. package/dist/esm/utils/parseUrl-extras.js +1 -0
  136. package/package.json +6 -3
  137. package/dist/cjs/utils/projectInfo.js +0 -8
  138. package/dist/esm/utils/projectInfo.d.ts +0 -4
  139. package/dist/esm/utils/projectInfo.js +0 -5
@@ -1,12 +1,12 @@
1
1
  export { getVikeConfig };
2
+ export { getVikeConfigOptional };
2
3
  export { getVikeConfig2 };
3
4
  export { reloadVikeConfig };
4
- export { vikeConfigDependencies };
5
5
  export { isV1Design };
6
6
  export { getConfVal };
7
7
  export { getConfigDefinitionOptional };
8
8
  export { isOverriden };
9
- import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, assertKeys, objectKeys, objectFromEntries, unique, isCallable, makeFirst, lowerFirst, makeLast } from '../../../utils.js';
9
+ import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, assertKeys, objectKeys, objectFromEntries, unique, isCallable, makeFirst, lowerFirst, makeLast, assertIsSingleModuleInstance } from '../../../utils.js';
10
10
  import { configDefinitionsBuiltIn } from './getVikeConfig/configDefinitionsBuiltIn.js';
11
11
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
12
12
  import { isVikeConfigInvalid, isVikeConfigInvalid_set } from '../../../../runtime/renderPage/isVikeConfigInvalid.js';
@@ -14,7 +14,7 @@ import { getViteDevServer } from '../../../../runtime/globalContext.js';
14
14
  import { logConfigError, logConfigErrorRecover } from '../../../shared/loggerNotProd.js';
15
15
  import { removeSuperfluousViteLog_enable, removeSuperfluousViteLog_disable } from '../../../shared/loggerVite/removeSuperfluousViteLog.js';
16
16
  import pc from '@brillout/picocolors';
17
- import { getConfigDefinedAt } from '../../../../../shared/page-configs/getConfigDefinedAt.js';
17
+ import { getConfigDefinedAt, getDefinedByString } from '../../../../../shared/page-configs/getConfigDefinedAt.js';
18
18
  import { loadPointerImport, loadValueFile } from './getVikeConfig/loadFileAtConfigTime.js';
19
19
  import { resolvePointerImport } from './getVikeConfig/resolvePointerImport.js';
20
20
  import { getFilePathResolved } from '../../../shared/getFilePath.js';
@@ -23,17 +23,18 @@ import { assertExtensionsRequire } from './getVikeConfig/assertExtensions.js';
23
23
  import { getPageConfigGlobalUserFriendly, getPageConfigUserFriendly } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
24
24
  import { getConfigValuesBase, isJsonValue } from '../../../../../shared/page-configs/serialize/serializeConfigValues.js';
25
25
  import { getPlusFilesAll } from './getVikeConfig/getPlusFilesAll.js';
26
+ import { getEnvVarObject } from '../../../shared/getEnvVarObject.js';
27
+ import { getApiOperation } from '../../../../api/context.js';
28
+ import { getCliOptions } from '../../../../cli/context.js';
26
29
  assertIsNotProductionRuntime();
30
+ assertIsSingleModuleInstance('v1-design/getVikeConfig.ts');
27
31
  let restartVite = false;
28
32
  let wasConfigInvalid = null;
29
33
  let vikeConfigPromise = null;
30
- const vikeConfigDependencies = new Set();
31
34
  function reloadVikeConfig(config) {
32
35
  const userRootDir = config.root;
33
36
  const vikeVitePluginOptions = config._vikeVitePluginOptions;
34
37
  assert(vikeVitePluginOptions);
35
- // TODO/now: unify with esbuildCache
36
- vikeConfigDependencies.clear();
37
38
  vikeConfigPromise = loadVikeConfig_withErrorHandling(userRootDir, true, vikeVitePluginOptions);
38
39
  handleReloadSideEffects();
39
40
  }
@@ -87,6 +88,11 @@ async function getVikeConfigEntry(userRootDir, isDev, vikeVitePluginOptions, doN
87
88
  }
88
89
  return await vikeConfigPromise;
89
90
  }
91
+ async function getVikeConfigOptional() {
92
+ if (!vikeConfigPromise)
93
+ return null;
94
+ return await vikeConfigPromise;
95
+ }
90
96
  function isV1Design(config) {
91
97
  const vikeConfig = config._vikeConfigObject;
92
98
  assert(vikeConfig);
@@ -131,20 +137,24 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
131
137
  configValueSources: {}
132
138
  },
133
139
  global: getPageConfigGlobalUserFriendly({ pageConfigGlobalValues: {} }),
134
- pages: {}
140
+ pages: {},
141
+ vikeConfigDependencies: new Set()
135
142
  };
136
143
  return dummyData;
137
144
  }
138
145
  }
139
146
  }
140
147
  async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
141
- const esbuildCache = {};
148
+ const esbuildCache = {
149
+ transpileCache: {},
150
+ vikeConfigDependencies: new Set()
151
+ };
142
152
  const plusFilesAll = await getPlusFilesAll(userRootDir, esbuildCache);
143
153
  const configDefinitionsResolved = await resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache);
144
- assertKnownConfigs(configDefinitionsResolved, plusFilesAll);
145
154
  const { pageConfigGlobal, pageConfigs } = getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRootDir);
146
155
  // Backwards compatibility for vike(options) in vite.config.js
147
156
  temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir);
157
+ setCliAndApiOptions(pageConfigGlobal, configDefinitionsResolved);
148
158
  // global
149
159
  const pageConfigGlobalValues = getConfigValues(pageConfigGlobal);
150
160
  const global = getPageConfigGlobalUserFriendly({ pageConfigGlobalValues });
@@ -153,7 +163,7 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
153
163
  const pageConfigValues = getConfigValues(pageConfig, true);
154
164
  return getPageConfigUserFriendly(pageConfigGlobalValues, pageConfig, pageConfigValues);
155
165
  }));
156
- return { pageConfigs, pageConfigGlobal, global, pages };
166
+ return { pageConfigs, pageConfigGlobal, global, pages, vikeConfigDependencies: esbuildCache.vikeConfigDependencies };
157
167
  }
158
168
  async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache) {
159
169
  const plusFilesAllOrdered = Object.values(plusFilesAll)
@@ -163,6 +173,10 @@ async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache)
163
173
  // 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).
164
174
  plusFilesAllOrdered, (configDef) => !!configDef.global);
165
175
  await loadCustomConfigBuildTimeFiles(plusFilesAll, configDefinitionsGlobal, userRootDir, esbuildCache);
176
+ const configDefinitionsAll = getConfigDefinitions(Object.values(plusFilesAll).flat());
177
+ const configNamesKnownAll = Object.keys(configDefinitionsAll);
178
+ const configNamesKnownGlobal = Object.keys(configDefinitionsGlobal);
179
+ assert(configNamesKnownGlobal.every((configName) => configNamesKnownAll.includes(configName)));
166
180
  const configDefinitionsLocal = {};
167
181
  await Promise.all(objectEntries(plusFilesAll).map(async ([locationIdPage, plusFiles]) => {
168
182
  const plusFilesRelevant = objectEntries(plusFilesAll)
@@ -172,12 +186,23 @@ async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache)
172
186
  .sort((plusFile1, plusFile2) => sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, null));
173
187
  const configDefinitions = getConfigDefinitions(plusFilesRelevant, (configDef) => configDef.global !== true);
174
188
  await loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, userRootDir, esbuildCache);
175
- configDefinitionsLocal[locationIdPage] = { configDefinitions, plusFiles, plusFilesRelevant };
189
+ const configNamesKnownLocal = unique([...Object.keys(configDefinitions), ...configNamesKnownGlobal]);
190
+ assert(configNamesKnownLocal.every((configName) => configNamesKnownAll.includes(configName)));
191
+ configDefinitionsLocal[locationIdPage] = {
192
+ configDefinitions,
193
+ plusFiles,
194
+ plusFilesRelevant,
195
+ configNamesKnownLocal
196
+ };
176
197
  }));
177
198
  const configDefinitionsResolved = {
178
199
  configDefinitionsGlobal,
179
- configDefinitionsLocal
200
+ configDefinitionsLocal,
201
+ configDefinitionsAll,
202
+ configNamesKnownAll,
203
+ configNamesKnownGlobal
180
204
  };
205
+ assertKnownConfigs(configDefinitionsResolved);
181
206
  return configDefinitionsResolved;
182
207
  }
183
208
  // Load value files (with `env.config===true`) of *custom* configs.
@@ -203,13 +228,13 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
203
228
  objectEntries(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
204
229
  const sources = resolveConfigValueSources(configName, configDef,
205
230
  // 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).
206
- Object.values(plusFilesAll).flat(), userRootDir, true);
231
+ Object.values(plusFilesAll).flat(), userRootDir, true, plusFilesAll);
207
232
  if (sources.length === 0)
208
233
  return;
209
234
  pageConfigGlobal.configValueSources[configName] = sources;
210
235
  });
211
236
  applyEffectsMetaEnv(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
212
- applyEffectsConfVal(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
237
+ applyEffectsConfVal(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal, plusFilesAll);
213
238
  sortConfigValueSources(pageConfigGlobal.configValueSources, null);
214
239
  assertPageConfigGlobal(pageConfigGlobal, plusFilesAll);
215
240
  const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
@@ -220,14 +245,14 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
220
245
  objectEntries(configDefinitionsLocal)
221
246
  .filter(([_configName, configDef]) => configDef.global !== true)
222
247
  .forEach(([configName, configDef]) => {
223
- const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false);
248
+ const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false, plusFilesAll);
224
249
  if (sources.length === 0)
225
250
  return;
226
251
  configValueSources[configName] = sources;
227
252
  });
228
253
  const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
229
254
  applyEffectsMetaEnv(configValueSources, configDefinitionsLocal);
230
- applyEffectsConfVal(configValueSources, configDefinitionsLocal);
255
+ applyEffectsConfVal(configValueSources, configDefinitionsLocal, plusFilesAll);
231
256
  sortConfigValueSources(configValueSources, locationId);
232
257
  const configValuesComputed = getComputed(configValueSources, configDefinitionsLocal);
233
258
  const pageConfig = {
@@ -349,27 +374,58 @@ function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, use
349
374
  assertWarning(Object.keys(vikeVitePluginOptions).length === 0, `Define Vike settings in +config.js instead of vite.config.js ${pc.underline('https://vike.dev/migration/settings')}`, { onlyOnce: true });
350
375
  Object.entries(vikeVitePluginOptions).forEach(([configName, value]) => {
351
376
  var _a;
352
- assert(includes(objectKeys(configDefinitionsBuiltIn), configName));
353
- const configDef = configDefinitionsBuiltIn[configName];
354
377
  const sources = ((_a = pageConfigGlobal.configValueSources)[configName] ?? (_a[configName] = []));
355
- sources.push({
356
- valueIsLoaded: true,
357
- value,
358
- configEnv: configDef.env,
359
- definedAtFilePath: {
360
- ...getFilePathResolved({
361
- userRootDir,
362
- filePathAbsoluteUserRootDir: '/vite.config.js'
363
- }),
364
- fileExportPathToShowToUser: null
365
- },
366
- locationId: '/',
367
- plusFile: null,
368
- valueIsLoadedWithImport: false,
369
- valueIsDefinedByPlusValueFile: false
370
- });
378
+ sources.push(getSourceNonConfigFile(configName, value, {
379
+ ...getFilePathResolved({
380
+ userRootDir,
381
+ filePathAbsoluteUserRootDir: '/vite.config.js'
382
+ }),
383
+ fileExportPathToShowToUser: null
384
+ }));
371
385
  });
372
386
  }
387
+ function setCliAndApiOptions(pageConfigGlobal, configDefinitionsResolved) {
388
+ // Vike API — passed options [lowest precedence]
389
+ const apiOperation = getApiOperation();
390
+ if (apiOperation?.options.vikeConfig) {
391
+ addSources(apiOperation.options.vikeConfig, { definedBy: 'api', operation: apiOperation.operation }, false);
392
+ }
393
+ // Vike CLI options
394
+ const cliOptions = getCliOptions();
395
+ if (cliOptions) {
396
+ addSources(cliOptions, { definedBy: 'cli' }, true);
397
+ }
398
+ // VIKE_CONFIG [highest precedence]
399
+ const configFromEnv = getEnvVarObject('VIKE_CONFIG');
400
+ if (configFromEnv) {
401
+ addSources(configFromEnv, { definedBy: 'env' }, false);
402
+ }
403
+ return;
404
+ function addSources(configValues, definedBy, exitOnError) {
405
+ Object.entries(configValues).forEach(([configName, value]) => {
406
+ var _a;
407
+ const sourceName = `The ${getDefinedByString(definedBy, configName)}`;
408
+ assertKnownConfig(configName, configDefinitionsResolved.configNamesKnownGlobal, configDefinitionsResolved, '/', sourceName, exitOnError);
409
+ const sources = ((_a = pageConfigGlobal.configValueSources)[configName] ?? (_a[configName] = []));
410
+ sources.unshift(getSourceNonConfigFile(configName, value, definedBy));
411
+ });
412
+ }
413
+ }
414
+ function getSourceNonConfigFile(configName, value, definedAt) {
415
+ assert(includes(objectKeys(configDefinitionsBuiltIn), configName));
416
+ const configDef = configDefinitionsBuiltIn[configName];
417
+ const source = {
418
+ valueIsLoaded: true,
419
+ value,
420
+ configEnv: configDef.env,
421
+ definedAt,
422
+ locationId: '/',
423
+ plusFile: null,
424
+ valueIsLoadedWithImport: false,
425
+ valueIsDefinedByPlusValueFile: false
426
+ };
427
+ return source;
428
+ }
373
429
  function sortConfigValueSources(configValueSources, locationIdPage) {
374
430
  Object.entries(configValueSources).forEach(([configName, sources]) => {
375
431
  sources
@@ -456,7 +512,7 @@ function sortPlusFilesSameLocationId(plusFile1, plusFile2, configName) {
456
512
  // No need to make it deterministic: the overall order is arleady deterministic, see sortMakeDeterministic() at getPlusFilesAll()
457
513
  return 0;
458
514
  }
459
- function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal) {
515
+ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal, plusFilesAll) {
460
516
  let sources = plusFilesRelevant
461
517
  .filter((plusFile) => isDefiningConfig(plusFile, configName))
462
518
  .map((plusFile) => getConfigValueSource(configName, plusFile, configDef, userRootDir));
@@ -471,14 +527,14 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
471
527
  sources = sources.filter((source) => {
472
528
  assert(source.configEnv.config);
473
529
  assert(source.valueIsLoaded);
474
- const valueIsGlobal = resolveIsGlobalValue(configDef.global, source.value);
530
+ const valueIsGlobal = resolveIsGlobalValue(configDef.global, source, plusFilesAll);
475
531
  return isGlobal ? valueIsGlobal : !valueIsGlobal;
476
532
  });
477
533
  }
478
534
  return sources;
479
535
  }
480
536
  function isDefiningConfig(plusFile, configName) {
481
- return getDefiningConfigNames(plusFile).includes(configName);
537
+ return getConfigNamesSetByPlusFile(plusFile).includes(configName);
482
538
  }
483
539
  function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
484
540
  const confVal = getConfVal(plusFile, configName);
@@ -521,7 +577,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
521
577
  configEnv: configDef.env,
522
578
  valueIsLoadedWithImport: false,
523
579
  valueIsDefinedByPlusValueFile: false,
524
- definedAtFilePath
580
+ definedAt: definedAtFilePath
525
581
  };
526
582
  return configValueSource;
527
583
  }
@@ -545,7 +601,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
545
601
  configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
546
602
  valueIsLoadedWithImport: true,
547
603
  valueIsDefinedByPlusValueFile: false,
548
- definedAtFilePath: pointerImport.fileExportPath
604
+ definedAt: pointerImport.fileExportPath
549
605
  };
550
606
  return configValueSource;
551
607
  }
@@ -557,7 +613,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
557
613
  configEnv: configDef.env,
558
614
  valueIsLoadedWithImport: false,
559
615
  valueIsDefinedByPlusValueFile: false,
560
- definedAtFilePath: definedAtFilePath_
616
+ definedAt: definedAtFilePath_
561
617
  };
562
618
  return configValueSource;
563
619
  }
@@ -571,7 +627,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
571
627
  configEnv: configEnvResolved,
572
628
  valueIsLoadedWithImport: !confVal.valueIsLoaded || !isJsonValue(confVal.value),
573
629
  valueIsDefinedByPlusValueFile: true,
574
- definedAtFilePath: {
630
+ definedAt: {
575
631
  ...plusFile.filePath,
576
632
  fileExportPathToShowToUser: configName === plusFile.configName
577
633
  ? []
@@ -585,7 +641,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
585
641
  }
586
642
  function isDefiningPage(plusFiles) {
587
643
  for (const plusFile of plusFiles) {
588
- const configNames = getDefiningConfigNames(plusFile);
644
+ const configNames = getConfigNamesSetByPlusFile(plusFile);
589
645
  if (configNames.some((configName) => isDefiningPageConfig(configName))) {
590
646
  return true;
591
647
  }
@@ -595,16 +651,19 @@ function isDefiningPage(plusFiles) {
595
651
  function isDefiningPageConfig(configName) {
596
652
  return ['Page', 'route'].includes(configName);
597
653
  }
598
- function resolveIsGlobalValue(configDefGlobal, configValue) {
654
+ function resolveIsGlobalValue(configDefGlobal, source, plusFilesAll) {
655
+ assert(source.valueIsLoaded);
599
656
  let isGlobal;
600
657
  if (isCallable(configDefGlobal))
601
- isGlobal = configDefGlobal(configValue);
658
+ isGlobal = configDefGlobal(source.value, {
659
+ isGlobalLocation: isGlobalLocation(source.locationId, plusFilesAll)
660
+ });
602
661
  else
603
662
  isGlobal = configDefGlobal ?? false;
604
663
  assert(typeof isGlobal === 'boolean');
605
664
  return isGlobal;
606
665
  }
607
- function getDefiningConfigNames(plusFile) {
666
+ function getConfigNamesSetByPlusFile(plusFile) {
608
667
  let configNames = [];
609
668
  if (!plusFile.isConfigFile) {
610
669
  configNames.push(plusFile.configName);
@@ -688,7 +747,7 @@ function assertMetaUsage(metaVal, metaConfigDefinedAt) {
688
747
  });
689
748
  }
690
749
  // Test: https://github.com/vikejs/vike/blob/441a37c4c1a3b07bb8f6efb1d1f7be297a53974a/test/playground/vite.config.ts#L39
691
- function applyEffectsConfVal(configValueSources, configDefinitions) {
750
+ function applyEffectsConfVal(configValueSources, configDefinitions, plusFilesAll) {
692
751
  objectEntries(configDefinitions).forEach(([configNameEffect, configDefEffect]) => {
693
752
  const sourceEffect = configValueSources[configNameEffect]?.[0];
694
753
  if (!sourceEffect)
@@ -696,8 +755,8 @@ function applyEffectsConfVal(configValueSources, configDefinitions) {
696
755
  const effect = runEffect(configNameEffect, configDefEffect, sourceEffect);
697
756
  if (!effect)
698
757
  return;
699
- const { configModFromEffect, configValueEffectSource } = effect;
700
- applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, configValueEffectSource);
758
+ const configModFromEffect = effect;
759
+ applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, plusFilesAll);
701
760
  });
702
761
  }
703
762
  // Test: https://github.com/vikejs/vike/blob/441a37c4c1a3b07bb8f6efb1d1f7be297a53974a/test/playground/pages/config-meta/effect/e2e-test.ts#L16
@@ -709,7 +768,7 @@ function applyEffectsMetaEnv(configValueSources, configDefinitions) {
709
768
  const effect = runEffect(configNameEffect, configDefEffect, sourceEffect);
710
769
  if (!effect)
711
770
  return;
712
- const { configModFromEffect } = effect;
771
+ const configModFromEffect = effect;
713
772
  applyEffectMetaEnv(configModFromEffect, configValueSources, configDefEffect);
714
773
  });
715
774
  }
@@ -721,17 +780,16 @@ function runEffect(configName, configDef, source) {
721
780
  `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 }')}.`
722
781
  ].join(' '));
723
782
  assert(source.valueIsLoaded);
724
- const configValueEffectSource = source.value;
725
783
  // Call effect
726
784
  const configModFromEffect = configDef.effect({
727
- configValue: configValueEffectSource,
728
- configDefinedAt: getConfigDefinedAt('Config', configName, source.definedAtFilePath)
785
+ configValue: source.value,
786
+ configDefinedAt: getConfigDefinedAt('Config', configName, source.definedAt)
729
787
  });
730
788
  if (!configModFromEffect)
731
789
  return null;
732
- return { configModFromEffect, configValueEffectSource };
790
+ return configModFromEffect;
733
791
  }
734
- function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, configValueEffectSource) {
792
+ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, plusFilesAll) {
735
793
  objectEntries(configModFromEffect).forEach(([configNameTarget, configValue]) => {
736
794
  if (configNameTarget === 'meta')
737
795
  return;
@@ -739,7 +797,7 @@ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSource
739
797
  assert(configDef);
740
798
  assert(configDefEffect._userEffectDefinedAtFilePath);
741
799
  const configValueSource = {
742
- definedAtFilePath: configDefEffect._userEffectDefinedAtFilePath,
800
+ definedAt: configDefEffect._userEffectDefinedAtFilePath,
743
801
  plusFile: sourceEffect.plusFile,
744
802
  locationId: sourceEffect.locationId,
745
803
  configEnv: configDef.env,
@@ -748,11 +806,12 @@ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSource
748
806
  valueIsLoaded: true,
749
807
  value: configValue
750
808
  };
751
- const isValueGlobalSource = resolveIsGlobalValue(configDefEffect.global, configValueEffectSource);
752
- const isValueGlobalTarget = resolveIsGlobalValue(configDef.global, configValue);
809
+ assert(sourceEffect.valueIsLoaded);
810
+ const isValueGlobalSource = resolveIsGlobalValue(configDefEffect.global, sourceEffect, plusFilesAll);
811
+ const isValueGlobalTarget = resolveIsGlobalValue(configDef.global, configValueSource, plusFilesAll);
753
812
  const isGlobalHumanReadable = (isGlobal) => `${isGlobal ? 'non-' : ''}global`;
754
813
  // The error message make it sound like it's an inherent limitation, it actually isn't (both ways can make senses).
755
- 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.`);
814
+ assertUsage(isValueGlobalSource === isValueGlobalTarget, `The configuration ${pc.cyan(configNameEffect)} is set to ${pc.cyan(JSON.stringify(sourceEffect.value))} 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.`);
756
815
  configValueSources[configNameTarget] ?? (configValueSources[configNameTarget] = []);
757
816
  configValueSources[configNameTarget].push(configValueSource);
758
817
  });
@@ -801,33 +860,30 @@ function getComputed(configValueSources, configDefinitions) {
801
860
  return configValuesComputed;
802
861
  }
803
862
  // Show error message upon unknown config
804
- function assertKnownConfigs(configDefinitionsResolved, plusFilesAll) {
805
- const configDefinitionsAll = getConfigDefinitions(Object.values(plusFilesAll).flat());
806
- const configNamesKnownAll = Object.keys(configDefinitionsAll);
807
- const configNamesGlobal = Object.keys(configDefinitionsResolved.configDefinitionsGlobal);
808
- objectEntries(configDefinitionsResolved.configDefinitionsLocal).forEach(([_locationId, { configDefinitions, plusFiles }]) => {
809
- const configDefinitionsLocal = configDefinitions;
810
- const configNamesKnownLocal = [...Object.keys(configDefinitionsLocal), ...configNamesGlobal];
863
+ function assertKnownConfigs(configDefinitionsResolved) {
864
+ objectEntries(configDefinitionsResolved.configDefinitionsLocal).forEach(([_locationId, { configNamesKnownLocal, plusFiles }]) => {
811
865
  plusFiles.forEach((plusFile) => {
812
- const configNames = getDefiningConfigNames(plusFile);
866
+ const configNames = getConfigNamesSetByPlusFile(plusFile);
813
867
  configNames.forEach((configName) => {
814
- assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLocal, plusFile);
815
- assert(configNamesKnownLocal.includes(configName));
816
- assert(configNamesKnownAll.includes(configName));
868
+ const { locationId } = plusFile;
869
+ const sourceName = plusFile.filePath.filePathToShowToUser;
870
+ assertKnownConfig(configName, configNamesKnownLocal, configDefinitionsResolved, locationId, sourceName, false);
817
871
  });
818
872
  });
819
873
  });
820
874
  }
821
- function assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLocal, plusFile) {
822
- if (configNamesKnownLocal.includes(configName))
875
+ function assertKnownConfig(configName, configNamesKnownRelevant, configDefinitionsResolved, locationId, sourceName, exitOnError) {
876
+ const { configNamesKnownAll } = configDefinitionsResolved;
877
+ if (configNamesKnownRelevant.includes(configName)) {
878
+ assert(configNamesKnownAll.includes(configName));
823
879
  return;
880
+ }
824
881
  const configNameColored = pc.cyan(configName);
825
- const { locationId, filePath: { filePathToShowToUser } } = plusFile;
826
- const errMsg = `${filePathToShowToUser} sets an unknown config ${configNameColored}`;
827
882
  // Inheritance issue: config is known but isn't defined at `locationId`
828
883
  if (configNamesKnownAll.includes(configName)) {
829
- assertUsage(false, `${filePathToShowToUser} sets the value of the config ${configNameColored} which is a custom config that is defined with ${pc.underline('https://vike.dev/meta')} at a path that doesn't apply to ${locationId} — see ${pc.underline('https://vike.dev/config#inheritance')}`);
884
+ assertUsage(false, `${sourceName} sets the value of the config ${configNameColored} which is a custom config that is defined with ${pc.underline('https://vike.dev/meta')} at a path that doesn't apply to ${locationId} — see ${pc.underline('https://vike.dev/config#inheritance')}`, { exitOnError });
830
885
  }
886
+ const errMsg = `${sourceName} sets an unknown config ${configNameColored}`;
831
887
  // Missing vike-{react,vue,solid} installation
832
888
  {
833
889
  const ui = ['vike-react', 'vike-vue', 'vike-solid'];
@@ -843,11 +899,9 @@ function assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLoca
843
899
  Wrapper: ui
844
900
  };
845
901
  if (configName in knownVikeExntensionConfigs) {
846
- const requiredVikeExtension = knownVikeExntensionConfigs[configName]
847
- .map((e) => pc.bold(e))
848
- .join('/');
902
+ const requiredVikeExtension = joinEnglish(knownVikeExntensionConfigs[configName].map((e) => pc.bold(e)), 'or');
849
903
  const errMsgEnhanced = `${errMsg}. If you want to use the configuration ${configNameColored} documented at ${pc.underline(`https://vike.dev/${configName}`)} then make sure to install ${requiredVikeExtension}. (Alternatively, you can define ${configNameColored} yourself by using ${pc.cyan('meta')}, see ${pc.underline('https://vike.dev/meta')} for more information.)`;
850
- assertUsage(false, errMsgEnhanced);
904
+ assertUsage(false, errMsgEnhanced, { exitOnError });
851
905
  }
852
906
  }
853
907
  // Similarity hint
@@ -864,9 +918,9 @@ function assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLoca
864
918
  if (configName === 'page') {
865
919
  errMsgEnhanced += ` (The name of the config ${pc.cyan('Page')} starts with a capital letter ${pc.cyan('P')} because it defines a UI component: a ubiquitous JavaScript convention is that the name of UI components start with a capital letter.)`;
866
920
  }
867
- assertUsage(false, errMsgEnhanced);
921
+ assertUsage(false, errMsgEnhanced, { exitOnError });
868
922
  }
869
- assertUsage(false, errMsg);
923
+ assertUsage(false, errMsg, { exitOnError });
870
924
  }
871
925
  function determineRouteFilesystem(locationId, configValueSources) {
872
926
  const configName = 'filesystemRoutingRoot';
@@ -889,7 +943,7 @@ function determineRouteFilesystem(locationId, configValueSources) {
889
943
  assert(filesystemRouteString.startsWith('/'));
890
944
  const routeFilesystem = {
891
945
  routeString: filesystemRouteString,
892
- definedBy: filesystemRouteDefinedBy
946
+ definedAtLocation: filesystemRouteDefinedBy
893
947
  };
894
948
  return { routeFilesystem, isErrorPage: undefined };
895
949
  }
@@ -898,10 +952,12 @@ function getFilesystemRoutingRootEffect(configFilesystemRoutingRoot, configName)
898
952
  // Eagerly loaded since it's config-only
899
953
  assert(configFilesystemRoutingRoot.valueIsLoaded);
900
954
  const { value } = configFilesystemRoutingRoot;
901
- const configDefinedAt = getConfigDefinedAt('Config', configName, configFilesystemRoutingRoot.definedAtFilePath);
955
+ const configDefinedAt = getConfigDefinedAt('Config', configName, configFilesystemRoutingRoot.definedAt);
902
956
  assertUsage(typeof value === 'string', `${configDefinedAt} should be a string`);
903
957
  assertUsage(value.startsWith('/'), `${configDefinedAt} is ${pc.cyan(value)} but it should start with a leading slash ${pc.cyan('/')}`);
904
- const { filePathAbsoluteUserRootDir } = configFilesystemRoutingRoot.definedAtFilePath;
958
+ const { definedAt } = configFilesystemRoutingRoot;
959
+ assert(!definedAt.definedBy);
960
+ const { filePathAbsoluteUserRootDir } = definedAt;
905
961
  assert(filePathAbsoluteUserRootDir);
906
962
  const before = getFilesystemRouteString(getLocationId(filePathAbsoluteUserRootDir));
907
963
  const after = value;
@@ -952,7 +1008,7 @@ function getConfigDefinitionOptional(configDefinitions, configName) {
952
1008
  return configDefinitions[configName] ?? null;
953
1009
  }
954
1010
  function getConfVal(plusFile, configName) {
955
- const configNames = getDefiningConfigNames(plusFile);
1011
+ const configNames = getConfigNamesSetByPlusFile(plusFile);
956
1012
  if (!configNames.includes(configName))
957
1013
  return null;
958
1014
  if (plusFile.isNotLoaded)
@@ -6,6 +6,8 @@ import { addSsrMiddleware } from '../shared/addSsrMiddleware.js';
6
6
  import pc from '@brillout/picocolors';
7
7
  import { logDockerHint } from './devConfig/index.js';
8
8
  import { getOutDirs, resolveOutDir } from '../shared/getOutDirs.js';
9
+ import sirv from 'sirv';
10
+ import { resolvePrerenderConfigGlobal } from '../../prerender/resolvePrerenderConfig.js';
9
11
  function previewConfig() {
10
12
  let config;
11
13
  // let vikeConfig: VikeConfigObject
@@ -32,23 +34,26 @@ function previewConfig() {
32
34
  */
33
35
  return () => {
34
36
  assertDist();
35
- /* We don't use this condition (we wrongfully always use the SSR middleware) because of the regression introduced by https://github.com/vitejs/vite/pull/14756 which stops servering .html files when `appType: 'custom'`.
36
- if (!vikeConfig.global.config.prerender || vikeConfig.global.config.prerender.partial) {
37
- addSsrMiddleware(server.middlewares, config, true)
37
+ // We cannot re-use Vite's static middleware: https://github.com/vitejs/vite/pull/14836#issuecomment-1788540300
38
+ addStaticAssetsMiddleware(server.middlewares);
39
+ const prerenderConfigGlobal = resolvePrerenderConfigGlobal(config._vikeConfigObject);
40
+ if (!prerenderConfigGlobal.isPrerenderingEnabledForAllPages) {
41
+ addSsrMiddleware(server.middlewares, config, true, prerenderConfigGlobal.isPrerenderingEnabled);
38
42
  }
39
- /*/
40
- addSsrMiddleware(server.middlewares, config, true);
41
- //*/
42
43
  addStatic404Middleware(server.middlewares);
43
44
  };
44
45
  }
45
46
  };
46
47
  function assertDist() {
47
- let { outDirRoot, outDirClient, outDirServer } = getOutDirs(config);
48
+ const { outDirRoot, outDirClient, outDirServer } = getOutDirs(config);
48
49
  [outDirRoot, outDirClient, outDirServer].forEach((outDirAny) => {
49
50
  assertUsage(fs.existsSync(outDirAny), `Cannot run ${pc.cyan('$ vike preview')}: your app isn't built (the build directory ${pc.cyan(outDirAny)} is missing). Make sure to run ${pc.cyan('$ vike build')} before running ${pc.cyan('$ vike preview')}.`);
50
51
  });
51
52
  }
53
+ function addStaticAssetsMiddleware(middlewares) {
54
+ const { outDirClient } = getOutDirs(config);
55
+ middlewares.use(sirv(outDirClient));
56
+ }
52
57
  function addStatic404Middleware(middlewares) {
53
58
  const { outDirClient } = getOutDirs(config);
54
59
  middlewares.use(config.base, (_, res, next) => {
@@ -1,15 +1,23 @@
1
1
  export { setGlobalContext };
2
2
  import { setGlobalContext_viteDevServer, setGlobalContext_viteConfig, setGlobalContext_isProduction } from '../../runtime/globalContext.js';
3
- import { assertFilePathAbsoluteFilesystem, isDevCheck, markSetup_isViteDev, markSetup_viteDevServer, markSetup_vitePreviewServer } from '../utils.js';
3
+ import { assert, assertFilePathAbsoluteFilesystem, isDevCheck, markSetup_isViteDev, markSetup_viteDevServer, markSetup_vitePreviewServer } from '../utils.js';
4
4
  import { getOutDirs } from '../shared/getOutDirs.js';
5
+ import { reloadVikeConfig } from './importUserCode/v1-design/getVikeConfig.js';
5
6
  function setGlobalContext() {
7
+ let isServerReload = false;
8
+ let config;
6
9
  return [
7
10
  {
8
11
  name: 'vike:setGlobalContext:pre',
9
12
  enforce: 'pre',
13
+ // This hook is called not only at server start but also at server restart (a new `viteDevServer` instance is created)
10
14
  configureServer: {
11
15
  order: 'pre',
12
16
  handler(viteDevServer) {
17
+ assert(config);
18
+ if (isServerReload)
19
+ reloadVikeConfig(config);
20
+ isServerReload = true;
13
21
  setGlobalContext_viteDevServer(viteDevServer);
14
22
  markSetup_viteDevServer();
15
23
  }
@@ -31,7 +39,8 @@ function setGlobalContext() {
31
39
  enforce: 'post',
32
40
  configResolved: {
33
41
  order: 'post',
34
- async handler(config) {
42
+ async handler(config_) {
43
+ config = config_;
35
44
  const { outDirRoot } = getOutDirs(config);
36
45
  assertFilePathAbsoluteFilesystem(outDirRoot); // Needed for `importServerProductionEntry({ outDir })` of @brillout/vite-plugin-server-entry
37
46
  setGlobalContext_viteConfig(config, outDirRoot);
@@ -1,4 +1,4 @@
1
1
  export { addSsrMiddleware };
2
2
  import type { ResolvedConfig, ViteDevServer } from 'vite';
3
3
  type ConnectServer = ViteDevServer['middlewares'];
4
- declare function addSsrMiddleware(middlewares: ConnectServer, config: ResolvedConfig, isPreview: boolean): void;
4
+ declare function addSsrMiddleware(middlewares: ConnectServer, config: ResolvedConfig, isPreview: boolean, isPrerenderingEnabled: boolean | null): void;
@@ -2,7 +2,7 @@ export { addSsrMiddleware };
2
2
  import { renderPage } from '../../runtime/renderPage.js';
3
3
  import { assertWarning } from '../utils.js';
4
4
  import pc from '@brillout/picocolors';
5
- function addSsrMiddleware(middlewares, config, isPreview) {
5
+ function addSsrMiddleware(middlewares, config, isPreview, isPrerenderingEnabled) {
6
6
  middlewares.use(async (req, res, next) => {
7
7
  if (res.headersSent)
8
8
  return next();
@@ -37,6 +37,10 @@ function addSsrMiddleware(middlewares, config, isPreview) {
37
37
  // - We purposely don't use next(err) to align behavior: we use our own/copied implementation of buildErrorMessage() regardless of whether the user uses Vite's dev middleware or Vite's standalone dev server
38
38
  return next();
39
39
  }
40
+ if (pageContext.httpResponse.statusCode === 404 && isPreview && isPrerenderingEnabled) {
41
+ // Serve /dist/client/404.html instead
42
+ return next();
43
+ }
40
44
  const configHeaders = (isPreview && config?.preview?.headers) || config?.server?.headers;
41
45
  if (configHeaders) {
42
46
  for (const [name, value] of Object.entries(configHeaders))
@@ -1,2 +1,4 @@
1
1
  export { getEnvVarObject };
2
- declare function getEnvVarObject(envVarName: 'VITE_CONFIG' | 'VIKE_CRAWL'): null | Record<string, unknown>;
2
+ export { parseJson5 };
3
+ declare function getEnvVarObject(envVarName: 'VITE_CONFIG' | 'VIKE_CRAWL' | 'VIKE_CONFIG'): null | Record<string, unknown>;
4
+ declare function parseJson5(valueStr: string, what: string): unknown;