vike 0.4.160-commit-a1101c1 → 0.4.160-commit-30d535e

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 (83) hide show
  1. package/dist/cjs/node/plugin/plugins/autoFullBuild.js +2 -2
  2. package/dist/cjs/node/plugin/plugins/buildConfig.js +9 -0
  3. package/dist/cjs/node/plugin/plugins/commonConfig.js +1 -1
  4. package/dist/cjs/node/plugin/plugins/config/stemUtils.js +1 -1
  5. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +1 -5
  6. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +28 -46
  7. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{loadFileConfigEnv.js → loadFileAtConfigTime.js} +5 -5
  8. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.js +33 -0
  9. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +2 -2
  10. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformImports.js → transformFileImports.js} +7 -7
  11. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +21 -27
  12. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +150 -110
  13. package/dist/cjs/node/plugin/utils.js +1 -2
  14. package/dist/cjs/node/prerender/runPrerender.js +12 -5
  15. package/dist/cjs/node/runtime/globalContext.js +7 -4
  16. package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
  17. package/dist/cjs/node/runtime/renderPage/{logHintForCjsEsmError.js → logErrorHint.js} +81 -43
  18. package/dist/cjs/node/runtime/renderPage/loggerProd.js +3 -3
  19. package/dist/cjs/node/runtime/utils.js +1 -1
  20. package/dist/cjs/shared/page-configs/serialize/parseConfigValuesImported.js +53 -26
  21. package/dist/cjs/shared/route/executeGuardHook.js +3 -2
  22. package/dist/cjs/shared/utils.js +0 -1
  23. package/dist/cjs/utils/{findUserPackageJsonPath.js → findFile.js} +11 -8
  24. package/dist/cjs/utils/nodeEnv.js +23 -1
  25. package/dist/cjs/utils/objectKeys.js +19 -3
  26. package/dist/cjs/utils/projectInfo.js +1 -1
  27. package/dist/cjs/utils/sorter.js +62 -1
  28. package/dist/esm/node/plugin/plugins/autoFullBuild.js +2 -2
  29. package/dist/esm/node/plugin/plugins/buildConfig.js +10 -1
  30. package/dist/esm/node/plugin/plugins/commonConfig.js +2 -2
  31. package/dist/esm/node/plugin/plugins/config/stemUtils.js +2 -2
  32. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.d.ts +2 -0
  33. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +0 -1
  34. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +1 -5
  35. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.d.ts +39 -12
  36. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +29 -47
  37. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{loadFileConfigEnv.js → loadFileAtConfigTime.js} +4 -4
  38. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.d.ts +5 -0
  39. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.js +27 -0
  40. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.d.ts +1 -1
  41. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +1 -1
  42. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformImports.d.ts → transformFileImports.d.ts} +2 -2
  43. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{transformImports.js → transformFileImports.js} +6 -6
  44. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.d.ts +1 -1
  45. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +20 -26
  46. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +2 -0
  47. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +149 -109
  48. package/dist/esm/node/plugin/utils.d.ts +1 -2
  49. package/dist/esm/node/plugin/utils.js +1 -2
  50. package/dist/esm/node/prerender/runPrerender.js +13 -6
  51. package/dist/esm/node/runtime/globalContext.js +8 -5
  52. package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
  53. package/dist/esm/node/runtime/renderPage/logErrorHint.d.ts +8 -0
  54. package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError.js → logErrorHint.js} +80 -42
  55. package/dist/esm/node/runtime/renderPage/loggerProd.js +3 -3
  56. package/dist/esm/node/runtime/utils.d.ts +1 -1
  57. package/dist/esm/node/runtime/utils.js +1 -1
  58. package/dist/esm/shared/page-configs/PageConfig.d.ts +2 -0
  59. package/dist/esm/shared/page-configs/serialize/parseConfigValuesImported.js +53 -26
  60. package/dist/esm/shared/route/executeGuardHook.js +3 -2
  61. package/dist/esm/shared/utils.d.ts +0 -1
  62. package/dist/esm/shared/utils.js +0 -1
  63. package/dist/esm/utils/findFile.d.ts +3 -0
  64. package/dist/esm/utils/findFile.js +21 -0
  65. package/dist/esm/utils/nodeEnv.d.ts +4 -0
  66. package/dist/esm/utils/nodeEnv.js +19 -0
  67. package/dist/esm/utils/objectKeys.d.ts +10 -1
  68. package/dist/esm/utils/objectKeys.js +20 -3
  69. package/dist/esm/utils/projectInfo.d.ts +2 -2
  70. package/dist/esm/utils/projectInfo.js +1 -1
  71. package/dist/esm/utils/sorter.d.ts +59 -0
  72. package/dist/esm/utils/sorter.js +61 -0
  73. package/package.json +1 -1
  74. package/dist/cjs/utils/objectEntries.js +0 -8
  75. package/dist/esm/node/runtime/renderPage/logHintForCjsEsmError.d.ts +0 -13
  76. package/dist/esm/utils/findUserPackageJsonPath.d.ts +0 -2
  77. package/dist/esm/utils/findUserPackageJsonPath.js +0 -18
  78. package/dist/esm/utils/objectEntries.d.ts +0 -4
  79. package/dist/esm/utils/objectEntries.js +0 -5
  80. /package/dist/cjs/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.js +0 -0
  81. /package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/{loadFileConfigEnv.d.ts → loadFileAtConfigTime.d.ts} +0 -0
  82. /package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.d.ts +0 -0
  83. /package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.js +0 -0
@@ -2,7 +2,7 @@ export { getVikeConfig };
2
2
  export { reloadVikeConfig };
3
3
  export { vikeConfigDependencies };
4
4
  export { isVikeConfigFile };
5
- import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, arrayIncludes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, lowerFirst, mergeCumulativeValues, getOutDirs, assertKeys } from '../../../utils.js';
5
+ import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, arrayIncludes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, lowerFirst, mergeCumulativeValues, getOutDirs, assertKeys, objectKeys, objectFromEntries, makeFirst, isNpmPackageImport, reverse } from '../../../utils.js';
6
6
  import path from 'path';
7
7
  import { configDefinitionsBuiltIn, configDefinitionsBuiltInGlobal } from './getVikeConfig/configDefinitionsBuiltIn.js';
8
8
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
@@ -17,8 +17,9 @@ import { getConfigVike } from '../../../../shared/getConfigVike.js';
17
17
  import { assertConfigValueIsSerializable } from './getConfigValuesSerialized.js';
18
18
  import { crawlPlusFiles } from './getVikeConfig/crawlPlusFiles.js';
19
19
  import { getConfigFileExport } from './getConfigFileExport.js';
20
- import { loadConfigFile, loadImportedFile, loadValueFile } from './getVikeConfig/loadFileConfigEnv.js';
20
+ import { loadConfigFile, loadImportedFile, loadValueFile } from './getVikeConfig/loadFileAtConfigTime.js';
21
21
  import { clearFilesEnvMap, resolveImport } from './getVikeConfig/resolveImportPath.js';
22
+ import { resolveFilePathRelativeToUserRootDir } from './getVikeConfig/resolveFilePath.js';
22
23
  assertIsNotProductionRuntime();
23
24
  let devServerIsCorrupt = false;
24
25
  let wasConfigInvalid = null;
@@ -82,69 +83,77 @@ async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
82
83
  }
83
84
  });
84
85
  let interfaceFilesByLocationId = {};
85
- // Config files
86
- await Promise.all(configFiles.map(async (filePath) => {
87
- const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false);
88
- const interfaceFile = getInterfaceFileFromConfigFile(configFile, false);
89
- const locationId = getLocationId(filePath.filePathAbsoluteVite);
90
- interfaceFilesByLocationId[locationId] = interfaceFilesByLocationId[locationId] ?? [];
91
- interfaceFilesByLocationId[locationId].push(interfaceFile);
92
- extendsConfigs.forEach((extendsConfig) => {
93
- const interfaceFile = getInterfaceFileFromConfigFile(extendsConfig, true);
94
- interfaceFilesByLocationId[locationId].push(interfaceFile);
95
- });
96
- }));
97
- // Value files
98
- await Promise.all(valueFiles.map(async (filePath) => {
99
- const configName = getConfigName(filePath.filePathAbsoluteVite);
100
- assert(configName);
101
- const interfaceFile = {
102
- filePath,
103
- fileExportsByConfigName: {
104
- [configName]: {}
105
- },
106
- isConfigFile: false,
107
- isValueFile: true,
108
- configName
109
- };
110
- {
111
- // We don't have access to the custom config definitions defined by the user yet.
112
- // - If `configDef` is `undefined` => we load the file +{configName}.js later.
113
- // - We already need to load +meta.js here (to get the custom config definitions defined by the user)
114
- const configDef = getConfigDefinitionOptional(configDefinitionsBuiltIn, configName);
115
- if (configDef && isConfigEnv(configDef, configName)) {
116
- await loadValueFile(interfaceFile, configName, userRootDir);
117
- }
118
- }
119
- {
120
- const locationId = getLocationId(filePath.filePathAbsoluteVite);
86
+ await Promise.all([
87
+ // Config files
88
+ ...configFiles.map(async (filePath) => {
89
+ const { filePathRelativeToUserRootDir } = filePath;
90
+ assert(filePathRelativeToUserRootDir);
91
+ const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false);
92
+ assert(filePath.filePathRelativeToUserRootDir);
93
+ const locationId = getLocationId(filePathRelativeToUserRootDir);
94
+ const interfaceFile = getInterfaceFileFromConfigFile(configFile, false, locationId);
121
95
  interfaceFilesByLocationId[locationId] = interfaceFilesByLocationId[locationId] ?? [];
122
96
  interfaceFilesByLocationId[locationId].push(interfaceFile);
123
- }
124
- }));
97
+ extendsConfigs.forEach((extendsConfig) => {
98
+ /* We purposely use the same locationId because the Vike extension's config should only apply to where it's being extended from, for example:
99
+ ```js
100
+ // /pages/admin/+config.h.js
101
+
102
+ import vikeVue from 'vike-vue/config'
103
+ // Should only apply to /pages/admin/**
104
+ export default { extends: [vikeVue] }
105
+ ```
106
+ ```js
107
+ // /pages/marketing/+config.h.js
108
+
109
+ import vikeReact from 'vike-react/config'
110
+ // Should only apply to /pages/marketing/**
111
+ export default { extends: [vikeReact] }
112
+ ```
113
+ */
114
+ const interfaceFile = getInterfaceFileFromConfigFile(extendsConfig, true, locationId);
115
+ interfaceFilesByLocationId[locationId].push(interfaceFile);
116
+ });
117
+ }),
118
+ // Value files
119
+ ...valueFiles.map(async (filePath) => {
120
+ const { filePathRelativeToUserRootDir } = filePath;
121
+ assert(filePathRelativeToUserRootDir);
122
+ const configName = getConfigName(filePathRelativeToUserRootDir);
123
+ assert(configName);
124
+ const locationId = getLocationId(filePathRelativeToUserRootDir);
125
+ const interfaceFile = {
126
+ locationId,
127
+ filePath,
128
+ fileExportsByConfigName: {
129
+ [configName]: {}
130
+ },
131
+ isConfigFile: false,
132
+ isValueFile: true,
133
+ configName
134
+ };
135
+ {
136
+ // We don't have access to the custom config definitions defined by the user yet.
137
+ // - If `configDef` is `undefined` => we load the file +{configName}.js later.
138
+ // - We already need to load +meta.js here (to get the custom config definitions defined by the user)
139
+ const configDef = getConfigDefinitionOptional(configDefinitionsBuiltIn, configName);
140
+ if (configDef && isConfigEnv(configDef, configName)) {
141
+ await loadValueFile(interfaceFile, configName, userRootDir);
142
+ }
143
+ }
144
+ {
145
+ interfaceFilesByLocationId[locationId] = interfaceFilesByLocationId[locationId] ?? [];
146
+ interfaceFilesByLocationId[locationId].push(interfaceFile);
147
+ }
148
+ })
149
+ ]);
125
150
  assertAllConfigsAreKnown(interfaceFilesByLocationId);
126
151
  return interfaceFilesByLocationId;
127
152
  }
128
- function getConfigDefinition(configDefinitionsRelevant, configName, filePathToShowToUser) {
129
- const configDef = configDefinitionsRelevant[configName];
130
- assertConfigExists(configName, Object.keys(configDefinitionsRelevant), filePathToShowToUser);
131
- assert(configDef);
132
- return configDef;
133
- }
134
- function getConfigDefinitionOptional(configDefinitions, configName) {
135
- return configDefinitions[configName] ?? null;
136
- }
137
- function isConfigEnv(configDef, configName) {
138
- const configEnv = configDef.env;
139
- if (configDef.cumulative) {
140
- // In principle we could lift that requirement (but it requires non-trivial modifications)
141
- assertUsage(configEnv.config, `Config ${pc.cyan(configName)} needs its ${pc.cyan('env')} to have ${pc.cyan('{ config: true }')} (because ${pc.cyan(configName)} is a ${pc.cyan('cumulative')} config)`);
142
- }
143
- return !!configEnv.config;
144
- }
145
- function getInterfaceFileFromConfigFile(configFile, isConfigExtend) {
153
+ function getInterfaceFileFromConfigFile(configFile, isConfigExtend, locationId) {
146
154
  const { fileExports, filePath, extendsFilePaths } = configFile;
147
155
  const interfaceFile = {
156
+ locationId,
148
157
  filePath,
149
158
  fileExportsByConfigName: {},
150
159
  isConfigFile: true,
@@ -160,12 +169,12 @@ function getInterfaceFileFromConfigFile(configFile, isConfigExtend) {
160
169
  }
161
170
  /** Show error message upon unknown config */
162
171
  function assertAllConfigsAreKnown(interfaceFilesByLocationId) {
163
- Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
172
+ objectEntries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
164
173
  const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
165
- const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
174
+ const configDefinitions = getConfigDefinitions(interfaceFilesRelevant);
166
175
  interfaceFiles.forEach((interfaceFile) => {
167
176
  Object.keys(interfaceFile.fileExportsByConfigName).forEach((configName) => {
168
- assertConfigExists(configName, Object.keys(configDefinitionsRelevant), interfaceFile.filePath.filePathToShowToUser);
177
+ assertConfigExists(configName, Object.keys(configDefinitions), interfaceFile.filePath.filePathToShowToUser);
169
178
  });
170
179
  });
171
180
  });
@@ -215,11 +224,11 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
215
224
  const interfaceFilesByLocationId = await loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions);
216
225
  const importedFilesLoaded = {};
217
226
  const { globalVikeConfig, pageConfigGlobal } = await getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded);
218
- const pageConfigs = await Promise.all(Object.entries(interfaceFilesByLocationId)
227
+ const pageConfigs = await Promise.all(objectEntries(interfaceFilesByLocationId)
219
228
  .filter(([_pageId, interfaceFiles]) => isDefiningPage(interfaceFiles))
220
229
  .map(async ([locationId]) => {
221
230
  const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
222
- const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
231
+ const configDefinitions = getConfigDefinitions(interfaceFilesRelevant);
223
232
  // Load value files of custom config-only configs
224
233
  await Promise.all(getInterfaceFileList(interfaceFilesRelevant).map(async (interfaceFile) => {
225
234
  if (!interfaceFile.isValueFile)
@@ -227,7 +236,7 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
227
236
  const { configName } = interfaceFile;
228
237
  if (isGlobalConfig(configName))
229
238
  return;
230
- const configDef = getConfigDefinition(configDefinitionsRelevant, configName, interfaceFile.filePath.filePathToShowToUser);
239
+ const configDef = getConfigDefinition(configDefinitions, configName, interfaceFile.filePath.filePathToShowToUser);
231
240
  if (!isConfigEnv(configDef, configName))
232
241
  return;
233
242
  const isAlreadyLoaded = interfacefileIsAlreaydLoaded(interfaceFile);
@@ -237,8 +246,8 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
237
246
  assert(!(configName in configDefinitionsBuiltIn));
238
247
  await loadValueFile(interfaceFile, configName, userRootDir);
239
248
  }));
240
- const configValueSources = {};
241
- await Promise.all(objectEntries(configDefinitionsRelevant)
249
+ let configValueSources = {};
250
+ await Promise.all(objectEntries(configDefinitions)
242
251
  .filter(([configName]) => !isGlobalConfig(configName))
243
252
  .map(async ([configName, configDef]) => {
244
253
  const sources = await resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, importedFilesLoaded);
@@ -246,10 +255,12 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
246
255
  return;
247
256
  configValueSources[configName] = sources;
248
257
  }));
258
+ configValueSources = sortConfigValueSources(configValueSources, locationId);
259
+ console.log(JSON.stringify(configValueSources, null, 2));
249
260
  const { routeFilesystem, isErrorPage } = determineRouteFilesystem(locationId, configValueSources);
250
- applyEffectsAll(configValueSources, configDefinitionsRelevant);
251
- const configValuesComputed = getComputed(configValueSources, configDefinitionsRelevant);
252
- const configValues = getConfigValues(configValueSources, configValuesComputed, configDefinitionsRelevant);
261
+ applyEffectsAll(configValueSources, configDefinitions);
262
+ const configValuesComputed = getComputed(configValueSources, configDefinitions);
263
+ const configValues = getConfigValues(configValueSources, configValuesComputed, configDefinitions);
253
264
  const pageConfig = {
254
265
  pageId: locationId,
255
266
  isErrorPage,
@@ -286,7 +297,7 @@ function interfacefileIsAlreaydLoaded(interfaceFile) {
286
297
  return isAlreadyLoaded;
287
298
  }
288
299
  function getInterfaceFilesRelevant(interfaceFilesByLocationId, locationIdPage) {
289
- const interfaceFilesRelevant = Object.fromEntries(Object.entries(interfaceFilesByLocationId)
300
+ const interfaceFilesRelevant = Object.fromEntries(objectEntries(interfaceFilesByLocationId)
290
301
  .filter(([locationId]) => {
291
302
  return isInherited(locationId, locationIdPage);
292
303
  })
@@ -301,14 +312,14 @@ function getInterfaceFileList(interfaceFilesByLocationId) {
301
312
  return interfaceFiles;
302
313
  }
303
314
  async function getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importedFilesLoaded) {
304
- const locationIds = Object.keys(interfaceFilesByLocationId);
305
- const interfaceFilesGlobal = Object.fromEntries(Object.entries(interfaceFilesByLocationId).filter(([locationId]) => {
315
+ const locationIds = objectKeys(interfaceFilesByLocationId);
316
+ const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesByLocationId).filter(([locationId]) => {
306
317
  return isGlobalLocation(locationId, locationIds);
307
318
  }));
308
319
  // Validate that global configs live in global interface files
309
320
  {
310
321
  const interfaceFilesGlobalPaths = [];
311
- Object.entries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
322
+ objectEntries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
312
323
  assert(isGlobalLocation(locationId, locationIds));
313
324
  interfaceFiles.forEach(({ filePath: { filePathRelativeToUserRootDir } }) => {
314
325
  if (filePathRelativeToUserRootDir) {
@@ -317,7 +328,7 @@ async function getGlobalConfigs(interfaceFilesByLocationId, userRootDir, importe
317
328
  });
318
329
  });
319
330
  const globalPaths = Array.from(new Set(interfaceFilesGlobalPaths.map((p) => path.posix.dirname(p))));
320
- Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
331
+ objectEntries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
321
332
  interfaceFiles.forEach((interfaceFile) => {
322
333
  Object.keys(interfaceFile.fileExportsByConfigName).forEach((configName) => {
323
334
  if (!isGlobalLocation(locationId, locationIds) && isGlobalConfig(configName)) {
@@ -441,6 +452,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
441
452
  const conf = interfaceFile.fileExportsByConfigName[configName];
442
453
  assert(conf);
443
454
  const configEnv = configDef.env;
455
+ const { locationId } = interfaceFile;
444
456
  const definedAtConfigFile = {
445
457
  ...interfaceFile.filePath,
446
458
  fileExportPathToShowToUser: ['default', configName]
@@ -466,6 +478,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
466
478
  };
467
479
  }
468
480
  const configValueSource = {
481
+ locationId,
469
482
  value: valueFilePath,
470
483
  valueIsFilePath: true,
471
484
  configEnv,
@@ -482,6 +495,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
482
495
  const import_ = resolveImport(configValue, interfaceFile.filePath, userRootDir, configEnv, configName);
483
496
  if (import_) {
484
497
  const configValueSource = {
498
+ locationId,
485
499
  configEnv,
486
500
  valueIsImportedAtRuntime: true,
487
501
  definedAt: import_
@@ -504,6 +518,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
504
518
  }
505
519
  // Defined by config file, i.e. +config.js file
506
520
  const configValueSource = {
521
+ locationId,
507
522
  value: configValue,
508
523
  configEnv,
509
524
  valueIsImportedAtRuntime: false,
@@ -516,6 +531,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
516
531
  const valueAlreadyLoaded = 'configValue' in conf;
517
532
  assert(valueAlreadyLoaded === !!configEnv.config);
518
533
  const configValueSource = {
534
+ locationId,
519
535
  configEnv,
520
536
  valueIsImportedAtRuntime: !valueAlreadyLoaded,
521
537
  definedAt: {
@@ -546,8 +562,10 @@ function isDefiningPageConfig(configName) {
546
562
  return ['Page', 'route'].includes(configName);
547
563
  }
548
564
  function getConfigDefinitions(interfaceFilesRelevant) {
549
- const configDefinitions = { ...configDefinitionsBuiltIn };
550
- Object.entries(interfaceFilesRelevant).reverse().forEach(([_locationId, interfaceFiles]) => {
565
+ const configDefinitionsMerged = { ...configDefinitionsBuiltIn };
566
+ Object.entries(interfaceFilesRelevant)
567
+ .reverse()
568
+ .forEach(([_locationId, interfaceFiles]) => {
551
569
  interfaceFiles.forEach((interfaceFile) => {
552
570
  const configMeta = interfaceFile.fileExportsByConfigName['meta'];
553
571
  if (!configMeta)
@@ -566,13 +584,14 @@ function getConfigDefinitions(interfaceFilesRelevant) {
566
584
  });
567
585
  objectEntries(meta).forEach(([configName, configDefinition]) => {
568
586
  // User can override an existing config definition
569
- configDefinitions[configName] = {
570
- ...configDefinitions[configName],
587
+ configDefinitionsMerged[configName] = {
588
+ ...configDefinitionsMerged[configName],
571
589
  ...configDefinition
572
590
  };
573
591
  });
574
592
  });
575
593
  });
594
+ const configDefinitions = configDefinitionsMerged;
576
595
  return configDefinitions;
577
596
  }
578
597
  function assertMetaValue(metaVal, configMetaDefinedAt) {
@@ -611,8 +630,8 @@ function assertMetaValue(metaVal, configMetaDefinedAt) {
611
630
  }
612
631
  });
613
632
  }
614
- function applyEffectsAll(configValueSources, configDefinitionsRelevant) {
615
- objectEntries(configDefinitionsRelevant).forEach(([configName, configDef]) => {
633
+ function applyEffectsAll(configValueSources, configDefinitions) {
634
+ objectEntries(configDefinitions).forEach(([configName, configDef]) => {
616
635
  if (!configDef.effect)
617
636
  return;
618
637
  // The value needs to be loaded at config time, that's why we only support effect for configs that are config-only for now.
@@ -671,9 +690,9 @@ function applyEffect(configModFromEffect, configValueSources, configDefEffect) {
671
690
  }
672
691
  });
673
692
  }
674
- function getComputed(configValueSources, configDefinitionsRelevant) {
693
+ function getComputed(configValueSources, configDefinitions) {
675
694
  const configValuesComputed = {};
676
- objectEntries(configDefinitionsRelevant).forEach(([configName, configDef]) => {
695
+ objectEntries(configDefinitions).forEach(([configName, configDef]) => {
677
696
  if (!configDef._computed)
678
697
  return;
679
698
  const value = configDef._computed(configValueSources);
@@ -688,15 +707,7 @@ function getComputed(configValueSources, configDefinitionsRelevant) {
688
707
  }
689
708
  async function findPlusFiles(userRootDir, outDirRoot, isDev, extensions) {
690
709
  const files = await crawlPlusFiles(userRootDir, outDirRoot, isDev);
691
- const plusFiles = files.map(({ filePathRelativeToUserRootDir, filePathAbsoluteFilesystem }) => {
692
- return {
693
- filePathRelativeToUserRootDir,
694
- filePathAbsoluteVite: filePathRelativeToUserRootDir,
695
- filePathAbsoluteFilesystem,
696
- filePathToShowToUser: filePathRelativeToUserRootDir,
697
- importPathAbsolute: null
698
- };
699
- });
710
+ const plusFiles = files.map(({ filePathRelativeToUserRootDir }) => resolveFilePathRelativeToUserRootDir(filePathRelativeToUserRootDir, userRootDir));
700
711
  // TODO/v1-release: remove
701
712
  extensions.forEach((extension) => {
702
713
  extension.pageConfigsDistFiles?.forEach((pageConfigDistFile) => {
@@ -748,22 +759,6 @@ function assertNoUnexpectedPlusSign(filePath: string, fileName: string) {
748
759
  )
749
760
  }
750
761
  */
751
- function isGlobalConfig(configName) {
752
- if (configName === 'prerender')
753
- return false;
754
- const configNamesGlobal = getConfigNamesGlobal();
755
- return arrayIncludes(configNamesGlobal, configName);
756
- }
757
- function getConfigNamesGlobal() {
758
- return Object.keys(configDefinitionsBuiltInGlobal);
759
- }
760
- function assertConfigExists(configName, configNamesRelevant, filePathToShowToUser) {
761
- const configNames = [...configNamesRelevant, ...getConfigNamesGlobal()];
762
- if (configNames.includes(configName))
763
- return;
764
- handleUnknownConfig(configName, configNames, filePathToShowToUser);
765
- assert(false);
766
- }
767
762
  function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
768
763
  let errMsg = `${filePathToShowToUser} defines an unknown config ${pc.cyan(configName)}`;
769
764
  let configNameSimilar = null;
@@ -833,7 +828,7 @@ function determineIsErrorPage(routeFilesystem) {
833
828
  function isVikeConfigFile(filePath) {
834
829
  return !!getConfigName(filePath);
835
830
  }
836
- function getConfigValues(configValueSources, configValuesComputed, configDefinitionsRelevant) {
831
+ function getConfigValues(configValueSources, configValuesComputed, configDefinitions) {
837
832
  const configValues = {};
838
833
  Object.entries(configValuesComputed).forEach(([configName, configValueComputed]) => {
839
834
  configValues[configName] = {
@@ -842,7 +837,7 @@ function getConfigValues(configValueSources, configValuesComputed, configDefinit
842
837
  };
843
838
  });
844
839
  Object.entries(configValueSources).forEach(([configName, sources]) => {
845
- const configDef = configDefinitionsRelevant[configName];
840
+ const configDef = configDefinitions[configName];
846
841
  assert(configDef);
847
842
  if (!configDef.cumulative) {
848
843
  const configValueSource = sources[0];
@@ -956,3 +951,48 @@ function getConfigEnvValue(val, errMsgIntro) {
956
951
  */
957
952
  return val;
958
953
  }
954
+ function getConfigDefinition(configDefinitions, configName, filePathToShowToUser) {
955
+ const configDef = configDefinitions[configName];
956
+ assertConfigExists(configName, Object.keys(configDefinitions), filePathToShowToUser);
957
+ assert(configDef);
958
+ return configDef;
959
+ }
960
+ function getConfigDefinitionOptional(configDefinitions, configName) {
961
+ return configDefinitions[configName] ?? null;
962
+ }
963
+ function isConfigEnv(configDef, configName) {
964
+ const configEnv = configDef.env;
965
+ if (configDef.cumulative) {
966
+ // In principle we could lift that requirement (but it requires non-trivial modifications)
967
+ assertUsage(configEnv.config, `Config ${pc.cyan(configName)} needs its ${pc.cyan('env')} to have ${pc.cyan('{ config: true }')} (because ${pc.cyan(configName)} is a ${pc.cyan('cumulative')} config)`);
968
+ }
969
+ return !!configEnv.config;
970
+ }
971
+ function isGlobalConfig(configName) {
972
+ if (configName === 'prerender')
973
+ return false;
974
+ const configNamesGlobal = getConfigNamesGlobal();
975
+ return arrayIncludes(configNamesGlobal, configName);
976
+ }
977
+ function getConfigNamesGlobal() {
978
+ return Object.keys(configDefinitionsBuiltInGlobal);
979
+ }
980
+ function assertConfigExists(configName, configNamesRelevant, filePathToShowToUser) {
981
+ const configNames = [...configNamesRelevant, ...getConfigNamesGlobal()];
982
+ if (configNames.includes(configName))
983
+ return;
984
+ handleUnknownConfig(configName, configNames, filePathToShowToUser);
985
+ assert(false);
986
+ }
987
+ function sortConfigValueSources(configValueSources, locationIdPage) {
988
+ return Object.fromEntries(Object.entries(configValueSources)
989
+ // Make order deterministic (no other purpose)
990
+ .sort(([, [source1]], [, [source2]]) => source1.definedAt.filePathAbsoluteVite < source2.definedAt.filePathAbsoluteVite ? -1 : 1)
991
+ // Sort after whether the config value was defined by an npm package
992
+ .sort(makeFirst(([, [source]]) => {
993
+ const { importPathAbsolute } = source.definedAt;
994
+ return !!importPathAbsolute && isNpmPackageImport(importPathAbsolute);
995
+ }))
996
+ // Sort after the filesystem inheritance of the config value
997
+ .sort(([, [source1]], [, [source2]]) => reverse(sortAfterInheritanceOrder(source1.locationId, source2.locationId, locationIdPage))));
998
+ }
@@ -5,7 +5,6 @@ export * from '../../utils/getDependencyPackageJson.js';
5
5
  export * from '../../utils/requireResolve.js';
6
6
  export * from '../../utils/arrayIncludes.js';
7
7
  export * from '../../utils/isDev.js';
8
- export * from '../../utils/objectKeys.js';
9
8
  export * from '../../utils/getMostSimilar.js';
10
9
  export * from '../../utils/getRandomId.js';
11
10
  export * from '../../utils/joinEnglish.js';
@@ -13,7 +12,7 @@ export * from '../../utils/escapeRegex.js';
13
12
  export * from '../../utils/stripAnsi.js';
14
13
  export * from '../../utils/trimWithAnsi.js';
15
14
  export * from '../../utils/removeEmptyLines.js';
16
- export * from '../../utils/findUserPackageJsonPath.js';
15
+ export * from '../../utils/findFile.js';
17
16
  export * from '../../utils/getPropAccessNotation.js';
18
17
  export * from '../../utils/mergeCumulativeValues.js';
19
18
  export * from '../../utils/deepEqual.js';
@@ -11,7 +11,6 @@ export * from '../../utils/getDependencyPackageJson.js';
11
11
  export * from '../../utils/requireResolve.js';
12
12
  export * from '../../utils/arrayIncludes.js';
13
13
  export * from '../../utils/isDev.js';
14
- export * from '../../utils/objectKeys.js';
15
14
  export * from '../../utils/getMostSimilar.js';
16
15
  export * from '../../utils/getRandomId.js';
17
16
  export * from '../../utils/joinEnglish.js';
@@ -19,7 +18,7 @@ export * from '../../utils/escapeRegex.js';
19
18
  export * from '../../utils/stripAnsi.js';
20
19
  export * from '../../utils/trimWithAnsi.js';
21
20
  export * from '../../utils/removeEmptyLines.js';
22
- export * from '../../utils/findUserPackageJsonPath.js';
21
+ export * from '../../utils/findFile.js';
23
22
  export * from '../../utils/getPropAccessNotation.js';
24
23
  export * from '../../utils/mergeCumulativeValues.js';
25
24
  export * from '../../utils/deepEqual.js';
@@ -5,7 +5,7 @@ export { runPrerender_forceExit };
5
5
  import '../runtime/page-files/setup.js';
6
6
  import path from 'path';
7
7
  import { route } from '../../shared/route/index.js';
8
- import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs, isPropertyGetter, assertPosixPath, urlToFile, executeHook, isPlainObject, setNodeEnvToProduction, isUserHookError } from './utils.js';
8
+ import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs, isPropertyGetter, assertPosixPath, urlToFile, executeHook, isPlainObject, setNodeEnvToProduction, isUserHookError, assertNodeEnvIsNotDev, getNodeEnv } from './utils.js';
9
9
  import { pLimit } from '../../utils/pLimit.js';
10
10
  import { prerenderPage, prerender404Page, getRenderContext, getPageContextInitEnhanced } from '../runtime/renderPage/renderPageAlreadyRouted.js';
11
11
  import pc from '@brillout/picocolors';
@@ -26,11 +26,11 @@ import { loadUserFilesServerSide } from '../runtime/renderPage/loadUserFilesServ
26
26
  import { getHookFromPageConfig, getHookFromPageConfigGlobal, getHookTimeoutDefault, setIsPrerenderering } from '../../shared/hooks/getHook.js';
27
27
  import { noRouteMatch } from '../../shared/route/noRouteMatch.js';
28
28
  import { getVikeConfig } from '../plugin/plugins/importUserCode/v1-design/getVikeConfig.js';
29
- import { logHintForCjsEsmError } from '../runtime/renderPage/logHintForCjsEsmError.js';
29
+ import { logErrorHint } from '../runtime/renderPage/logErrorHint.js';
30
30
  async function runPrerenderFromAPI(options = {}) {
31
31
  await runPrerender(options, 'prerender()');
32
32
  // - We purposely propagate the error to the user land, so that the error interrupts the user land. It's also, I guess, a nice-to-have that the user has control over the error.
33
- // - We don't use logHintForCjsEsmError() because we don't have control over what happens with the error. For example, if the user land purposely swallows the error then the hint shouldn't be logged. Also, it's best if the hint is shown to the user *after* the error, but we cannot do/guarentee that.
33
+ // - We don't use logErrorHint() because we don't have control over what happens with the error. For example, if the user land purposely swallows the error then the hint shouldn't be logged. Also, it's best if the hint is shown to the user *after* the error, but we cannot do/guarentee that.
34
34
  }
35
35
  async function runPrerenderFromCLI(options) {
36
36
  try {
@@ -38,7 +38,7 @@ async function runPrerenderFromCLI(options) {
38
38
  }
39
39
  catch (err) {
40
40
  console.error(err);
41
- logHintForCjsEsmError(err);
41
+ logErrorHint(err);
42
42
  process.exit(1);
43
43
  }
44
44
  }
@@ -48,7 +48,7 @@ async function runPrerenderFromAutoFullBuild(options) {
48
48
  }
49
49
  catch (err) {
50
50
  console.error(err);
51
- logHintForCjsEsmError(err);
51
+ logErrorHint(err);
52
52
  process.exit(1);
53
53
  }
54
54
  }
@@ -59,7 +59,7 @@ async function runPrerender(options, manuallyTriggered) {
59
59
  if (logLevel === 'info') {
60
60
  console.log(`${pc.cyan(`vike v${projectInfo.projectVersion}`)} ${pc.green('pre-rendering HTML...')}`);
61
61
  }
62
- setNodeEnvToProduction();
62
+ handleNodeEnv();
63
63
  await disableReactStreaming();
64
64
  const viteConfig = await resolveConfig(options.viteConfig || {}, 'vike pre-rendering', 'production');
65
65
  assertLoadedConfig(viteConfig, options);
@@ -713,3 +713,10 @@ function assertIsNotAbort(err, urlOr404) {
713
713
  assert(abortCall);
714
714
  assertUsage(false, `${pc.cyan(abortCall)} thrown${thrownBy} while pre-rendering ${urlOr404} but ${pc.cyan(abortCaller)} isn't supported for pre-rendered pages`);
715
715
  }
716
+ function handleNodeEnv() {
717
+ const assertNodeEnv = () => assertNodeEnvIsNotDev('pre-rendering');
718
+ if (getNodeEnv())
719
+ assertNodeEnv();
720
+ setNodeEnvToProduction();
721
+ assertNodeEnv();
722
+ }
@@ -6,7 +6,7 @@ export { setGlobalContext_viteDevServer };
6
6
  export { setGlobalContext_vitePreviewServer };
7
7
  export { setGlobalContext_viteConfig };
8
8
  export { getRuntimeManifest };
9
- import { assert, assertUsage, getGlobalObject, getNodeEnv, isNodeEnvDev, isPlainObject, objectAssign } from './utils.js';
9
+ import { assert, assertUsage, getGlobalObject, getNodeEnv, getNodeEnvDesc, isNodeEnvDev, isPlainObject, objectAssign } from './utils.js';
10
10
  import { loadImportBuild } from './globalContext/loadImportBuild.js';
11
11
  import { setPageFiles } from '../../shared/getPageFiles.js';
12
12
  import { assertPluginManifest } from '../shared/assertPluginManifest.js';
@@ -151,8 +151,11 @@ function assertNodeEnv(hasViteDevServer) {
151
151
  const nodeEnv = getNodeEnv();
152
152
  if (nodeEnv === null || nodeEnv === 'test')
153
153
  return;
154
- const isDevNodeEnv = isNodeEnvDev();
155
- // - Calling Vite's createServer() is enough for hasViteDevServer to be true, even without actually adding Vite's development middleware to the server: https://github.com/vikejs/vike/issues/792#issuecomment-1516830759
156
- // - We should change this to be a warning if it blocks users (e.g. if a bad-citizen tool sets a wrong process.env.NODE_ENV value).
157
- assertUsage(hasViteDevServer === isDevNodeEnv, `Vite's development server was${hasViteDevServer ? '' : "n't"} instantiated while the environment is set to be a ${isDevNodeEnv ? 'development' : 'production'} environment by ${pc.cyan(`process.env.NODE_ENV === ${JSON.stringify(nodeEnv)}`)} which is contradictory, see https://vike.dev/NODE_ENV`);
154
+ const isDev = isNodeEnvDev();
155
+ // Calling Vite's createServer() is enough for hasViteDevServer to be true, even without actually adding Vite's development middleware to the server: https://github.com/vikejs/vike/issues/792#issuecomment-1516830759
156
+ if (hasViteDevServer === isDev)
157
+ return;
158
+ const nodeEnvDesc = getNodeEnvDesc();
159
+ // We should change this to be a warning if it blocks users (e.g. if a bad-citizen tool sets a wrong process.env.NODE_ENV value)
160
+ assertUsage(false, `Vite's development server was${hasViteDevServer ? '' : "n't"} instantiated while the ${nodeEnvDesc} which is contradictory, see https://vike.dev/NODE_ENV`);
158
161
  }
@@ -85,7 +85,7 @@ async function getHtmlTags(pageContext, injectToStream, injectFilter) {
85
85
  // See https://github.com/vikejs/vike/pull/1271
86
86
  const positionJavaScriptEntry = (() => {
87
87
  if (pageContext._pageContextPromise) {
88
- assertWarning(!injectToStream, "[getHtmlTags()] We recommend against using streaming and a pageContext promise at the same time as progressive hydration won't work", { onlyOnce: true });
88
+ assertWarning(!injectToStream, "[getHtmlTags()] We recommend against using streaming and a pageContext promise at the same time, because progressive hydration won't work.", { onlyOnce: true });
89
89
  // If there is a pageContext._pageContextPromise (which is resolved after the stream has ended) then the pageContext JSON data needs to await for it: https://vike.dev/streaming#initial-data-after-stream-end
90
90
  return 'HTML_END';
91
91
  }
@@ -0,0 +1,8 @@
1
+ export { logErrorHint };
2
+ export { isCjsEsmError };
3
+ export { isKnownError };
4
+ export { getHint };
5
+ declare function logErrorHint(error: unknown): void;
6
+ declare function getHint(error: unknown): null | string;
7
+ declare function isKnownError(error: unknown): false | string;
8
+ declare function isCjsEsmError(error: unknown): boolean | string[];