vike 0.4.240 → 0.4.241-commit-60b0676

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 (99) hide show
  1. package/dist/esm/client/runtime-client-routing/getPageContextFromHooks.d.ts +1 -1
  2. package/dist/esm/client/runtime-client-routing/getPageContextFromHooks.js +1 -1
  3. package/dist/esm/client/runtime-client-routing/logErrorClient.d.ts +2 -0
  4. package/dist/esm/client/runtime-client-routing/logErrorClient.js +11 -0
  5. package/dist/esm/client/runtime-client-routing/renderPageClientSide.js +95 -84
  6. package/dist/esm/client/runtime-client-routing/utils.d.ts +0 -1
  7. package/dist/esm/client/runtime-client-routing/utils.js +0 -1
  8. package/dist/esm/node/api/build.js +6 -6
  9. package/dist/esm/node/api/dev.js +2 -2
  10. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -9
  11. package/dist/esm/node/api/prepareViteApiCall.js +4 -156
  12. package/dist/esm/node/api/prerender.js +2 -2
  13. package/dist/esm/node/api/preview.js +2 -2
  14. package/dist/esm/node/api/resolveViteConfigFromUser.d.ts +20 -0
  15. package/dist/esm/node/api/resolveViteConfigFromUser.js +207 -0
  16. package/dist/esm/node/cli/parseCli.js +10 -6
  17. package/dist/esm/node/prerender/runPrerender.js +2 -1
  18. package/dist/esm/node/prerender/runPrerenderEntry.js +4 -4
  19. package/dist/esm/node/runtime/globalContext.d.ts +92 -0
  20. package/dist/esm/node/runtime/globalContext.js +12 -3
  21. package/dist/esm/node/runtime/logErrorServer.d.ts +2 -0
  22. package/dist/esm/node/runtime/logErrorServer.js +18 -0
  23. package/dist/esm/node/runtime/renderPage/execHookOnError.d.ts +2 -0
  24. package/dist/esm/node/runtime/renderPage/execHookOnError.js +26 -0
  25. package/dist/esm/node/runtime/renderPage/execHookServer.d.ts +1 -1
  26. package/dist/esm/node/runtime/renderPage/loggerProd.js +3 -5
  27. package/dist/esm/node/runtime/renderPage.js +8 -7
  28. package/dist/esm/node/runtime-dev/createDevMiddleware.js +2 -2
  29. package/dist/esm/node/vite/index.d.ts +1 -1
  30. package/dist/esm/node/vite/index.js +55 -24
  31. package/dist/esm/node/vite/onLoad.js +3 -8
  32. package/dist/esm/node/vite/plugins/build/handleAssetsManifest.js +0 -1
  33. package/dist/esm/node/vite/plugins/build/pluginBuildApp.js +6 -6
  34. package/dist/esm/node/vite/plugins/build/pluginDistFileNames.js +2 -2
  35. package/dist/esm/node/vite/plugins/pluginCommon.d.ts +1 -1
  36. package/dist/esm/node/vite/plugins/pluginCommon.js +22 -9
  37. package/dist/esm/node/vite/plugins/pluginFileEnv.js +9 -6
  38. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.d.ts +3 -0
  39. package/dist/esm/node/vite/plugins/pluginReplaceConstantsEnvVars.js +129 -0
  40. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.d.ts +10 -0
  41. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +77 -0
  42. package/dist/esm/node/vite/plugins/pluginReplaceConstantsPageContext.d.ts +3 -0
  43. package/dist/esm/node/vite/plugins/{pluginReplaceIsClientSide.js → pluginReplaceConstantsPageContext.js} +5 -3
  44. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntry.js +7 -1
  45. package/dist/esm/node/vite/plugins/pluginVirtualFiles/generateVirtualFileGlobalEntryWithOldDesign.js +3 -0
  46. package/dist/esm/node/vite/plugins/pluginVirtualFiles.js +2 -2
  47. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.d.ts +3 -0
  48. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.js +32 -0
  49. package/dist/esm/node/vite/shared/getFilePath.d.ts +4 -6
  50. package/dist/esm/node/vite/shared/getFilePath.js +6 -11
  51. package/dist/esm/node/vite/shared/isViteCli.d.ts +13 -0
  52. package/dist/esm/node/vite/shared/isViteCli.js +143 -0
  53. package/dist/esm/node/vite/shared/isViteServerSide.d.ts +6 -3
  54. package/dist/esm/node/vite/shared/isViteServerSide.js +13 -4
  55. package/dist/esm/node/vite/shared/loggerNotProd/errorWithCodeSnippet.js +2 -2
  56. package/dist/esm/node/vite/shared/loggerNotProd/log.js +8 -2
  57. package/dist/esm/node/vite/shared/loggerNotProd.d.ts +1 -1
  58. package/dist/esm/node/vite/shared/loggerNotProd.js +11 -11
  59. package/dist/esm/node/vite/shared/loggerVite.js +4 -2
  60. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +12 -2
  61. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +12 -8
  62. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.d.ts +2 -0
  63. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.js +4 -0
  64. package/dist/esm/node/vite/utils.d.ts +1 -0
  65. package/dist/esm/node/vite/utils.js +1 -0
  66. package/dist/esm/shared/createGlobalContextShared.d.ts +2 -1
  67. package/dist/esm/shared/createGlobalContextShared.js +1 -1
  68. package/dist/esm/shared/hooks/execHook.d.ts +1 -1
  69. package/dist/esm/shared/hooks/getHook.d.ts +5 -4
  70. package/dist/esm/shared/route/abort.d.ts +1 -0
  71. package/dist/esm/shared/route/abort.js +12 -4
  72. package/dist/esm/shared/route/index.js +13 -4
  73. package/dist/esm/shared/route/utils.d.ts +1 -0
  74. package/dist/esm/shared/route/utils.js +1 -0
  75. package/dist/esm/types/Config.d.ts +14 -3
  76. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  77. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  78. package/dist/esm/utils/assert.js +1 -0
  79. package/dist/esm/utils/assertNodeVersion.js +1 -1
  80. package/dist/esm/utils/assertViteVersion.d.ts +2 -0
  81. package/dist/esm/utils/assertViteVersion.js +11 -0
  82. package/dist/esm/utils/debug.d.ts +5 -3
  83. package/dist/esm/utils/debug.js +20 -16
  84. package/dist/esm/utils/getGlobalObject.d.ts +5 -1
  85. package/dist/esm/utils/getGlobalObject.js +5 -1
  86. package/dist/esm/utils/isExactlyOneTruthy.d.ts +1 -0
  87. package/dist/esm/utils/isExactlyOneTruthy.js +4 -0
  88. package/dist/esm/utils/isVikeReactApp.js +2 -1
  89. package/dist/esm/utils/requireResolve.js +1 -1
  90. package/package.json +3 -3
  91. package/dist/esm/node/vite/plugins/pluginEnvVars.d.ts +0 -3
  92. package/dist/esm/node/vite/plugins/pluginEnvVars.js +0 -110
  93. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.d.ts +0 -9
  94. package/dist/esm/node/vite/plugins/pluginReplaceGlobalThisConstants.js +0 -45
  95. package/dist/esm/node/vite/plugins/pluginReplaceIsClientSide.d.ts +0 -3
  96. package/dist/esm/node/vite/shared/isViteCliCall.d.ts +0 -10
  97. package/dist/esm/node/vite/shared/isViteCliCall.js +0 -81
  98. package/dist/esm/shared/route/debug.d.ts +0 -6
  99. package/dist/esm/shared/route/debug.js +0 -21
@@ -0,0 +1,207 @@
1
+ export { resolveViteConfigFromUser };
2
+ export { isOnlyResolvingUserConfig };
3
+ export { getVikeConfigInternalEarly };
4
+ export { getViteContextWithOperation };
5
+ export { getViteRoot };
6
+ export { assertViteRoot };
7
+ export { normalizeViteRoot };
8
+ import { loadConfigFromFile, mergeConfig, resolveConfig } from 'vite';
9
+ import { getVikeConfigInternal, getVikeConfigFromCliOrEnv, setVikeConfigContext, isVikeConfigContextSet, } from '../vite/shared/resolveVikeConfigInternal.js';
10
+ import path from 'node:path';
11
+ import { assert, assertUsage, assertWarning, getGlobalObject, pick, toPosixPath } from './utils.js';
12
+ import pc from '@brillout/picocolors';
13
+ import { getEnvVarObject } from '../vite/shared/getEnvVarObject.js';
14
+ import { getVikeApiOperation, isVikeCliOrApi } from './context.js';
15
+ import { getViteCommandFromCli } from '../vite/shared/isViteCli.js';
16
+ const globalObject = getGlobalObject('api/prepareViteApiCall.ts', {});
17
+ async function resolveViteConfigFromUser(viteConfigFromUserVikeApiOptions, viteContext) {
18
+ const viteInfo = await getViteInfo(viteConfigFromUserVikeApiOptions, viteContext);
19
+ setVikeConfigContext_(viteInfo, viteContext);
20
+ const { viteConfigFromUserResolved } = viteInfo;
21
+ const { viteConfigResolved } = await assertViteRoot2(viteInfo.root, viteConfigFromUserResolved, viteContext);
22
+ return {
23
+ viteConfigResolved, // ONLY USE if strictly necessary. (We plan to remove assertViteRoot2() as explained in the comments of that function.)
24
+ viteConfigFromUserResolved,
25
+ };
26
+ }
27
+ async function getVikeConfigInternalEarly() {
28
+ assert(!globalObject.isOnlyResolvingUserConfig); // ensure no infinite loop
29
+ if (!isVikeConfigContextSet()) {
30
+ const viteContext = getViteContext();
31
+ const viteInfo = await getViteInfo(undefined, viteContext);
32
+ setVikeConfigContext_(viteInfo, viteContext);
33
+ }
34
+ return await getVikeConfigInternal();
35
+ }
36
+ function setVikeConfigContext_(viteInfo, viteContext) {
37
+ setVikeConfigContext({
38
+ userRootDir: viteInfo.root,
39
+ isDev: viteContext === 'dev',
40
+ vikeVitePluginOptions: viteInfo.vikeVitePluginOptions,
41
+ });
42
+ }
43
+ function isOnlyResolvingUserConfig() {
44
+ return globalObject.isOnlyResolvingUserConfig;
45
+ }
46
+ async function getViteRoot(viteContext) {
47
+ if (!globalObject.root)
48
+ await getViteInfo(undefined, viteContext);
49
+ assert(globalObject.root);
50
+ return globalObject.root;
51
+ }
52
+ async function getViteInfo(viteConfigFromUserVikeApiOptions, viteContext) {
53
+ let viteConfigFromUserResolved = viteConfigFromUserVikeApiOptions;
54
+ // Precedence:
55
+ // 1) viteConfigFromUserEnvVar (highest precedence)
56
+ // 2) viteConfigFromUserVikeConfig
57
+ // 2) viteConfigFromUserVikeApiOptions
58
+ // 3) viteConfigFromUserViteFile (lowest precedence)
59
+ // Resolve Vike's +mode setting
60
+ {
61
+ const viteConfigFromUserVikeConfig = pick(getVikeConfigFromCliOrEnv().vikeConfigFromCliOrEnv, ['mode']);
62
+ if (Object.keys(viteConfigFromUserVikeConfig).length > 0) {
63
+ viteConfigFromUserResolved = mergeConfig(viteConfigFromUserResolved ?? {}, viteConfigFromUserVikeConfig);
64
+ }
65
+ }
66
+ // Resolve VITE_CONFIG
67
+ const viteConfigFromUserEnvVar = getEnvVarObject('VITE_CONFIG');
68
+ if (viteConfigFromUserEnvVar) {
69
+ viteConfigFromUserResolved = mergeConfig(viteConfigFromUserResolved ?? {}, viteConfigFromUserEnvVar);
70
+ }
71
+ // Resolve vite.config.js
72
+ globalObject.isOnlyResolvingUserConfig = true;
73
+ const viteConfigFromUserViteConfigFile = await loadViteConfigFile(viteConfigFromUserResolved, viteContext);
74
+ globalObject.isOnlyResolvingUserConfig = false;
75
+ // Correct precedence, replicates Vite:
76
+ // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
77
+ const viteConfigResolved = mergeConfig(viteConfigFromUserViteConfigFile ?? {}, viteConfigFromUserResolved ?? {});
78
+ const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
79
+ globalObject.root = root;
80
+ // - Find options `vike(options)` set in vite.config.js
81
+ // - TO-DO/next-major-release: remove
82
+ // - Add Vike's Vite plugin if missing
83
+ let vikeVitePluginOptions;
84
+ const found = findVikeVitePlugin(viteConfigResolved);
85
+ if (found) {
86
+ vikeVitePluginOptions = found.vikeVitePluginOptions;
87
+ }
88
+ else {
89
+ // Show a warning because Vike supports Vite's CLI (as well as third-party CLIs).
90
+ // - Encourage users to define a vite.config.js file that also works with Vite's CLI (and potentially other third-party CLIs).
91
+ // - Vike-based frameworks, such as DocPress, allow their users to omit defining a vite.config.js file.
92
+ assertWarning(viteConfigFromUserViteConfigFile, // Only show the warning if the user defined a vite.config.js file
93
+ "Omitting Vike's Vite plugin (inside your vite.config.js) is deprecated — make sure to always add Vike's Vite plugin https://vike.dev/vite-plugin", { onlyOnce: true });
94
+ // Add Vike to plugins if not present.
95
+ // Using a dynamic import because the script calling the Vike API may not live in the same place as vite.config.js, thus vike/plugin may resolved to two different node_modules/vike directories.
96
+ const { plugin: vikePlugin } = await import('../vite/index.js');
97
+ viteConfigFromUserResolved = {
98
+ ...viteConfigFromUserResolved,
99
+ plugins: [...(viteConfigFromUserResolved?.plugins ?? []), vikePlugin()],
100
+ };
101
+ const res = findVikeVitePlugin(viteConfigFromUserResolved);
102
+ assert(res);
103
+ vikeVitePluginOptions = res.vikeVitePluginOptions;
104
+ }
105
+ assert(vikeVitePluginOptions);
106
+ return { root, vikeVitePluginOptions, viteConfigFromUserResolved };
107
+ }
108
+ function findVikeVitePlugin(viteConfig) {
109
+ let vikeVitePluginOptions;
110
+ let vikeVitePuginFound = false;
111
+ viteConfig?.plugins?.forEach((p) => {
112
+ if (p && '_vikeVitePluginOptions' in p) {
113
+ vikeVitePuginFound = true;
114
+ const options = p._vikeVitePluginOptions;
115
+ vikeVitePluginOptions ?? (vikeVitePluginOptions = {});
116
+ Object.assign(vikeVitePluginOptions, options);
117
+ }
118
+ });
119
+ if (!vikeVitePuginFound)
120
+ return null;
121
+ return { vikeVitePluginOptions };
122
+ }
123
+ // Copied from https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L961-L1005
124
+ async function loadViteConfigFile(viteConfigFromUserResolved, viteContext) {
125
+ const viteContextResolved = resolveViteContext(viteConfigFromUserResolved, viteContext);
126
+ const [inlineConfig, command, defaultMode, _defaultNodeEnv, isPreview] = viteContextResolved;
127
+ let config = inlineConfig;
128
+ let mode = inlineConfig.mode || defaultMode;
129
+ const configEnv = {
130
+ mode,
131
+ command,
132
+ isSsrBuild: command === 'build' && !!config.build?.ssr,
133
+ isPreview,
134
+ };
135
+ let { configFile } = config;
136
+ if (configFile !== false) {
137
+ const loadResult = await loadConfigFromFile(configEnv, configFile, config.root, config.logLevel, config.customLogger);
138
+ if (!loadResult)
139
+ return null;
140
+ assert(loadResult.config);
141
+ return loadResult.config;
142
+ }
143
+ return null;
144
+ }
145
+ function getViteContext() {
146
+ const vikeApiOperation = getVikeApiOperation();
147
+ const viteCommand = getViteCommandFromCli();
148
+ assert(!(viteCommand && vikeApiOperation));
149
+ if (vikeApiOperation)
150
+ return getViteContextWithOperation(vikeApiOperation.operation);
151
+ assert(!isVikeCliOrApi());
152
+ if (viteCommand === 'dev' || viteCommand === 'optimize') {
153
+ return 'dev';
154
+ }
155
+ if (viteCommand === 'build') {
156
+ return 'build';
157
+ }
158
+ if (viteCommand === 'preview') {
159
+ return 'preview';
160
+ }
161
+ // Third-party CLIs.
162
+ // - Component development (e.g. Storybook) => let's consider it development
163
+ // - Testing (e.g. Vitest) => let's consider it development
164
+ return 'dev';
165
+ }
166
+ function getViteContextWithOperation(operation) {
167
+ if (operation === 'build' || operation === 'prerender') {
168
+ return 'build';
169
+ }
170
+ if (operation === 'preview') {
171
+ return 'preview';
172
+ }
173
+ if (operation === 'dev') {
174
+ return 'dev';
175
+ }
176
+ assert(false);
177
+ }
178
+ function resolveViteContext(inlineConfig = {}, viteContext) {
179
+ const isBuild = viteContext === 'build';
180
+ const isPreview = viteContext === 'preview';
181
+ const isDev = viteContext === 'dev';
182
+ const command = isBuild ? 'build' : 'serve';
183
+ const defaultMode = isDev ? 'development' : 'production';
184
+ const defaultNodeEnv = defaultMode;
185
+ const viteContextResolved = [inlineConfig, command, defaultMode, defaultNodeEnv, isPreview];
186
+ return viteContextResolved;
187
+ }
188
+ function normalizeViteRoot(root) {
189
+ // `path.resolve(viteConfigFromUserViteFile.configFile, root)` could be more intuitive than `path.resolve(process.cwd(), root)` but we replicate Vite's behavior (`vite.config.js` should follow Vite's API), see:
190
+ // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1063
191
+ return toPosixPath(
192
+ // Equivalent to `path.resolve(process.cwd(), root)`
193
+ path.resolve(root));
194
+ }
195
+ const errMsg = `A Vite plugin is modifying Vite's setting ${pc.cyan('root')} which is forbidden`;
196
+ async function assertViteRoot2(root, viteConfigFromUserResolved, viteContext) {
197
+ const viteContextResolved = resolveViteContext(viteConfigFromUserResolved, viteContext);
198
+ // We can eventually remove this resolveConfig() call (along with removing the whole assertViteRoot2() function which is redundant with the assertViteRoot() function) so that Vike doesn't make any resolveConfig() (except for pre-rendering and preview which is required). But let's keep it for now, just to see whether calling resolveConfig() can be problematic.
199
+ const viteConfigResolved = await resolveConfig(...viteContextResolved);
200
+ assertUsage(normalizeViteRoot(viteConfigResolved.root) === normalizeViteRoot(root), errMsg);
201
+ return { viteConfigResolved };
202
+ }
203
+ function assertViteRoot(root, config) {
204
+ if (globalObject.root)
205
+ assert(normalizeViteRoot(globalObject.root) === normalizeViteRoot(root));
206
+ assertUsage(normalizeViteRoot(root) === normalizeViteRoot(config.root), errMsg);
207
+ }
@@ -5,8 +5,8 @@ import { parseJson5 } from '../vite/shared/getEnvVarObject.js';
5
5
  const commands = [
6
6
  { name: 'dev', desc: 'Start development server' },
7
7
  { name: 'build', desc: 'Build for production' },
8
- { name: 'preview', desc: 'Start preview server using production build (only works for SSG apps)' },
9
- { name: 'prerender', desc: 'Pre-render pages (only needed when prerender.disableAutoRun is true)' },
8
+ { name: 'preview', desc: 'Start preview server using production build' },
9
+ { name: 'prerender', desc: 'Pre-render pages (only needed when +prerender.disableAutoRun is true)' },
10
10
  ];
11
11
  function parseCli() {
12
12
  const command = getCommand();
@@ -51,7 +51,7 @@ function getCliOptions() {
51
51
  return cliOptions;
52
52
  }
53
53
  function showHelp() {
54
- const TAB = ' '.repeat(3);
54
+ const TAB = ' '.repeat(2);
55
55
  const nameMaxLength = Math.max(...commands.map((c) => c.name.length));
56
56
  console.log([
57
57
  `vike@${PROJECT_VERSION}`,
@@ -60,13 +60,17 @@ function showHelp() {
60
60
  ...[...commands, { name: '-v', desc: "Print Vike's installed version" }].map((c) => ` ${pc.dim('$')} vike ${c.name.startsWith('-') ? pc.cyan(`${c.name}`) : pc.bold(`${c.name}`)}${' '.repeat(nameMaxLength - c.name.length)}${TAB}${pc.dim(`# ${c.desc}`)}`),
61
61
  '',
62
62
  'Common CLI options:',
63
- [`vike dev ${pc.cyan('--host')}`, `vike dev ${pc.cyan('--port')} 80`, `vike build ${pc.cyan('--mode')} staging`]
63
+ [
64
+ `vike dev ${pc.cyan('--host')} ${TAB}${pc.dim('# Make server available over LAN and public addresses')}`,
65
+ `vike dev ${pc.cyan('--port')} 80 ${TAB}${pc.dim('# Change the server port')}`,
66
+ `vike build ${pc.cyan('--mode')} staging${TAB}${pc.dim('# Set the mode to run in')}`,
67
+ `vike dev ${pc.cyan('--force')} ${TAB}${pc.dim("# Disable Vite's cache")}`,
68
+ ]
64
69
  .map((o) => ` ${pc.dim('$')} ${o}`)
65
70
  .join('\n'),
66
71
  '',
67
- `More Vike settings can be passed over the ${pc.cyan('VIKE_CONFIG')} environment variable or as ${pc.cyan('CLI options')}.`,
72
+ `More Vike settings can be passed over the ${pc.cyan('VIKE_CONFIG')} environment variable or as ${pc.cyan('CLI option')}.`,
68
73
  `More Vite settings can be passed over the ${pc.cyan('VITE_CONFIG')} environment variable.`,
69
- ``,
70
74
  `See ${pc.underline('https://vike.dev/cli')} for more information.`,
71
75
  ].join('\n'));
72
76
  process.exit(1);
@@ -539,7 +539,7 @@ async function warnMissingPages(prerenderedPageContexts, globalContext, doNotPre
539
539
  .filter((pageId) => !isErrorPage(pageId, globalContext._pageConfigs))
540
540
  .forEach((pageId) => {
541
541
  const pageAt = isV1 ? pageId : `\`${pageId}.page.*\``;
542
- assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while there isn't any ${hookName}() hook returning an URL matching the page's route. You must use a ${hookName}() hook (https://vike.dev/${hookName}) for providing the list of URLs to be pre-rendered for that page. If you want to skip pre-rendering that page, you can remove this warning by setting +prerender to false at ${pageAt} (https://vike.dev/prerender#toggle) or by setting +prerender.partial to true (https://vike.dev/prerender#partial).`, { onlyOnce: true });
542
+ assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while there isn't any ${hookName}() hook returning an URL matching the page's route. You must use a ${hookName}() hook (https://vike.dev/${hookName}) for providing the list of URLs to be pre-rendered for that page. If you want to skip pre-rendering that page, you can remove this warning by setting +prerender to false at ${pageAt} (https://vike.dev/pre-rendering#partial) or by setting +prerender.partial to true (https://vike.dev/prerender#partial).`, { onlyOnce: true });
543
543
  });
544
544
  }
545
545
  async function writeFiles({ pageContext, htmlString, pageContextSerialized }, viteConfig, onPagePrerender, prerenderContext, logLevel) {
@@ -690,6 +690,7 @@ function preparePrerenderContextForPublicUsage(prerenderContext) {
690
690
  });
691
691
  return prerenderContext.pageContexts;
692
692
  },
693
+ configurable: true,
693
694
  });
694
695
  }
695
696
  // Required because of https://vike.dev/i18n#pre-rendering
@@ -6,7 +6,7 @@ import { assert } from './utils.js';
6
6
  import { logErrorHint } from '../runtime/renderPage/logErrorHint.js';
7
7
  import { prepareViteApiCall } from '../api/prepareViteApiCall.js';
8
8
  import { isVikeCli } from '../cli/context.js';
9
- import { isViteCliCall } from '../vite/shared/isViteCliCall.js';
9
+ import { isViteCli } from '../vite/shared/isViteCli.js';
10
10
  import { runPrerender } from './runPrerender.js';
11
11
  async function runPrerenderFromAPI(options = {}) {
12
12
  // - 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.
@@ -16,8 +16,8 @@ async function runPrerenderFromAPI(options = {}) {
16
16
  }
17
17
  async function runPrerenderFromCLIPrerenderCommand() {
18
18
  try {
19
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall({}, 'prerender');
20
- await runPrerender({ viteConfig: viteConfigFromUserEnhanced }, '$ vike prerender');
19
+ const { viteConfigFromUserResolved } = await prepareViteApiCall({}, 'prerender');
20
+ await runPrerender({ viteConfig: viteConfigFromUserResolved }, '$ vike prerender');
21
21
  }
22
22
  catch (err) {
23
23
  console.error(err);
@@ -38,7 +38,7 @@ async function runPrerenderFromAutoRun(viteConfig) {
38
38
  logErrorHint(err);
39
39
  process.exit(1);
40
40
  }
41
- const forceExit = isVikeCli() || isViteCliCall();
41
+ const forceExit = isVikeCli() || isViteCli();
42
42
  return { forceExit };
43
43
  }
44
44
  function runPrerender_forceExit() {
@@ -2,6 +2,7 @@ export { getGlobalContext };
2
2
  export { getGlobalContextSync };
3
3
  export { getGlobalContextAsync };
4
4
  export { getGlobalContextServerInternal };
5
+ export { getGlobalContextServerInternalOptional };
5
6
  export { getViteDevServer };
6
7
  export { getViteConfig };
7
8
  export { initGlobalContext_renderPage };
@@ -246,6 +247,97 @@ declare function getGlobalContextServerInternal(): Promise<{
246
247
  prerenderContext: PrerenderContext | undefined;
247
248
  });
248
249
  }>;
250
+ declare function getGlobalContextServerInternalOptional(): (Record<string, unknown> & (({
251
+ _globalConfigPublic: {
252
+ pages: {
253
+ [k: string]: {
254
+ config: import("../../types/index.js").ConfigResolved;
255
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
256
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
257
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
258
+ } & ({
259
+ route: import("../../types/Config.js").Route;
260
+ isErrorPage?: undefined;
261
+ } | {
262
+ route?: undefined;
263
+ isErrorPage: true;
264
+ });
265
+ };
266
+ config: import("../../types/index.js").ConfigResolved;
267
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
268
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
269
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
270
+ };
271
+ pages: {
272
+ [k: string]: {
273
+ config: import("../../types/index.js").ConfigResolved;
274
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
275
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
276
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
277
+ } & ({
278
+ route: import("../../types/Config.js").Route;
279
+ isErrorPage?: undefined;
280
+ } | {
281
+ route?: undefined;
282
+ isErrorPage: true;
283
+ });
284
+ };
285
+ config: import("../../types/index.js").ConfigResolved;
286
+ _source: import("../../shared/page-configs/resolveVikeConfigPublic.js").Source;
287
+ _sources: import("../../shared/page-configs/resolveVikeConfigPublic.js").Sources;
288
+ _from: import("../../shared/page-configs/resolveVikeConfigPublic.js").From;
289
+ isGlobalContext: true;
290
+ _isOriginalObject: true;
291
+ _virtualFileExportsGlobalEntry: unknown;
292
+ _pageFilesAll: import("../../shared/getPageFiles.js").PageFile[];
293
+ _pageConfigs: import("../../types/PageConfig.js").PageConfigRuntime[];
294
+ _pageConfigGlobal: import("../../types/PageConfig.js").PageConfigGlobalRuntime;
295
+ _allPageIds: string[];
296
+ } & (({
297
+ _isProduction: false;
298
+ _isPrerendering: false;
299
+ assetsManifest: null;
300
+ _viteDevServer: ViteDevServer | undefined;
301
+ viteConfig: ResolvedConfig | undefined;
302
+ isClientSide: false;
303
+ _pageRoutes: PageRoutes;
304
+ _onBeforeRouteHook: Hook | null;
305
+ } | {
306
+ _isPrerendering: true;
307
+ viteConfig: ResolvedConfig;
308
+ _isProduction: true;
309
+ assetsManifest: ViteManifest;
310
+ _viteDevServer: null;
311
+ _usesClientRouter: boolean;
312
+ isClientSide: false;
313
+ _pageRoutes: PageRoutes;
314
+ _onBeforeRouteHook: Hook | null;
315
+ } | {
316
+ _isPrerendering: false;
317
+ viteConfig: null;
318
+ _isProduction: true;
319
+ assetsManifest: ViteManifest;
320
+ _viteDevServer: null;
321
+ _usesClientRouter: boolean;
322
+ isClientSide: false;
323
+ _pageRoutes: PageRoutes;
324
+ _onBeforeRouteHook: Hook | null;
325
+ }) & {
326
+ baseServer: string;
327
+ baseAssets: string;
328
+ viteConfigRuntime: {
329
+ root: string;
330
+ build: {
331
+ outDir: string;
332
+ };
333
+ _baseViteOriginal: string;
334
+ vitePluginServerEntry: {
335
+ inject: boolean | undefined;
336
+ };
337
+ };
338
+ })) & {
339
+ prerenderContext: PrerenderContext | undefined;
340
+ })) | null;
249
341
  /**
250
342
  * Get runtime information about your app.
251
343
  *
@@ -4,6 +4,7 @@ export { getGlobalContextSync };
4
4
  export { getGlobalContextAsync };
5
5
  // Internal use
6
6
  export { getGlobalContextServerInternal };
7
+ export { getGlobalContextServerInternalOptional };
7
8
  export { getViteDevServer };
8
9
  export { getViteConfig };
9
10
  export { initGlobalContext_renderPage };
@@ -58,6 +59,12 @@ async function getGlobalContextServerInternal() {
58
59
  assertIsDefined(globalContext);
59
60
  return { globalContext };
60
61
  }
62
+ function getGlobalContextServerInternalOptional() {
63
+ const { globalContext } = globalObjectTyped;
64
+ if (!globalContext)
65
+ return null;
66
+ return globalContext;
67
+ }
61
68
  function assertIsDefined(globalContext) {
62
69
  if (!globalContext) {
63
70
  debug('globalContext', globalContext);
@@ -556,7 +563,8 @@ function isProdOptional() {
556
563
  const yes5 = globalObject.isProductionAccordingToUser === true;
557
564
  // vite-plugin-vercel
558
565
  const yes6 = globalObject.isProductionAccordingToPhotonVercel === true;
559
- const yes = yes1 || yes2 || yes3 || yes4 || yes5 || yes6;
566
+ const yes7 = globalThis.__VIKE__IS_DEV === false;
567
+ const yes = yes1 || yes2 || yes3 || yes4 || yes5 || yes6 || yes7;
560
568
  const no1 = !!globalObject.viteDevServer;
561
569
  // Vike CLI & Vike API
562
570
  const no2 = vikeApiOperation === 'dev';
@@ -566,8 +574,9 @@ function isProdOptional() {
566
574
  const no4 = globalObject.isProductionAccordingToUser === false;
567
575
  // @cloudflare/vite-plugin
568
576
  const no5 = isNonRunnableDev();
569
- const no = no1 || no2 || no3 || no4 || no5;
570
- const debug = { yes1, yes2, yes3, yes4, yes5, yes6, no1, no2, no3, no4, no5 };
577
+ const no6 = globalThis.__VIKE__IS_DEV === true;
578
+ const no = no1 || no2 || no3 || no4 || no5 || no6;
579
+ const debug = { yes1, yes2, yes3, yes4, yes5, yes6, yes7, no1, no2, no3, no4, no5, no6 };
571
580
  assert(typeof yes === 'boolean', debug);
572
581
  assert(typeof no === 'boolean', debug);
573
582
  if (yes) {
@@ -0,0 +1,2 @@
1
+ export { logErrorServer };
2
+ declare function logErrorServer(err: unknown): void;
@@ -0,0 +1,18 @@
1
+ export { logErrorServer };
2
+ import pc from '@brillout/picocolors';
3
+ import { isCallable, isObject } from './utils.js';
4
+ import { execHookOnError } from './renderPage/execHookOnError.js';
5
+ function logErrorServer(err) {
6
+ execHookOnError(err);
7
+ // Set by react-streaming
8
+ // - https://github.com/brillout/react-streaming/blob/0fb5510d0a5a614f577668a519bccd62de40aed8/src/server/renderToStream/common.ts#L59-L62
9
+ // - https://gist.github.com/brillout/066293a687ab7cf695e62ad867bc6a9c
10
+ // - It doesn't seem to be needed? (The error Vike receives is already enhanced.) Should we remove this?
11
+ if (isObject(err) && isCallable(err.getEnhancedError)) {
12
+ err = err.getEnhancedError(err);
13
+ }
14
+ // We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
15
+ // - TO-DO/eventually: is that still true? Let's eventually remove it and see if it crashes Cloudflare.
16
+ const errStr = isObject(err) && 'stack' in err ? String(err.stack) : String(err);
17
+ console.error(pc.red(errStr));
18
+ }
@@ -0,0 +1,2 @@
1
+ export { execHookOnError };
2
+ declare function execHookOnError(err: unknown): void;
@@ -0,0 +1,26 @@
1
+ export { execHookOnError };
2
+ import { isObject, getGlobalObject } from '../utils.js';
3
+ import { getGlobalContextServerInternalOptional } from '../globalContext.js';
4
+ import { getHookFromPageConfigGlobalCumulative } from '../../../shared/hooks/getHook.js';
5
+ const globalObject = getGlobalObject('renderPage/execHookOnError.ts', {
6
+ seen: new WeakSet(),
7
+ });
8
+ function execHookOnError(err) {
9
+ if (isObject(err)) {
10
+ if (globalObject.seen.has(err))
11
+ return;
12
+ globalObject.seen.add(err);
13
+ }
14
+ const globalContext = getGlobalContextServerInternalOptional();
15
+ if (!globalContext)
16
+ return;
17
+ const hooks = getHookFromPageConfigGlobalCumulative(globalContext._pageConfigGlobal, 'onError');
18
+ for (const hook of hooks) {
19
+ try {
20
+ hook.hookFn(err);
21
+ }
22
+ catch (hookErr) {
23
+ console.error(hookErr);
24
+ }
25
+ }
26
+ }
@@ -5,7 +5,7 @@ import type { PageContextConfig } from '../../../shared/getPageFiles.js';
5
5
  import type { HookName } from '../../../types/Config.js';
6
6
  type PageContextExecHookServer = PageContextConfig & PageContextForPublicUsageServer;
7
7
  declare function execHookServer(hookName: HookName, pageContext: PageContextExecHookServer): Promise<(import("../../../shared/hooks/getHook.js").HookLoc & {
8
- hookFn: (arg: import("../../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum | import("../../../shared/prepareGlobalContextForPublicUsage.js").GlobalContextPrepareMinimum) => unknown;
8
+ hookFn: (arg: import("../../../shared/preparePageContextForPublicUsage.js").PageContextPrepareMinimum) => unknown;
9
9
  hookTimeout: import("../../../shared/hooks/getHook.js").HookTimeout;
10
10
  } & {
11
11
  hookReturn: unknown;
@@ -4,18 +4,16 @@ export { logErrorProd };
4
4
  export { onRuntimeError };
5
5
  import { isAbortError } from '../../../shared/route/abort.js';
6
6
  import { setAlreadyLogged } from './isNewError.js';
7
- import { isObject, warnIfErrorIsNotObject } from '../utils.js';
8
- import pc from '@brillout/picocolors';
7
+ import { warnIfErrorIsNotObject } from '../utils.js';
9
8
  import { logErrorHint } from './logErrorHint.js';
9
+ import { logErrorServer } from '../logErrorServer.js';
10
10
  function logErrorProd(err, _httpRequestId) {
11
11
  warnIfErrorIsNotObject(err);
12
12
  setAlreadyLogged(err);
13
13
  if (isAbortError(err)) {
14
14
  return;
15
15
  }
16
- // We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
17
- const errStr = isObject(err) && 'stack' in err ? String(err.stack) : String(err);
18
- console.error(pc.red(errStr));
16
+ logErrorServer(err);
19
17
  // Needs to be called after logging the error.
20
18
  onRuntimeError(err);
21
19
  }
@@ -64,11 +64,12 @@ async function renderPagePrepare(pageContextInit, httpRequestId) {
64
64
  await initGlobalContext_renderPage();
65
65
  }
66
66
  catch (err) {
67
- // Errors are expected since assertUsage() is used in initGlobalContext_renderPage() such as:
68
- // ```bash
69
- // Re-build your app (you're using 1.2.3 but your app was built with 1.2.2)
70
- // ```
71
- // initGlobalContext_renderPage() doesn't call any user hook => err isn't thrown from user code.
67
+ // Errors are expected:
68
+ // - assertUsage() such as:
69
+ // ```bash
70
+ // Re-build your app (you're using 1.2.3 but your app was built with 1.2.2)
71
+ // ```
72
+ // - initGlobalContext_renderPage() depends on +onCreateGlobalContext hooks
72
73
  assert(!isAbortError(err));
73
74
  logRuntimeError(err, httpRequestId);
74
75
  const pageContextWithError = getPageContextHttpResponseErrorWithoutGlobalContext(err, pageContextInit);
@@ -245,7 +246,7 @@ function logHttpResponse(urlOriginalPretty, httpRequestId, pageContextReturn) {
245
246
  msg = `HTTP ${type} ${prettyUrl(urlOriginalPretty)} ${color(statusCode ?? 'ERR')}`;
246
247
  }
247
248
  }
248
- logRuntimeInfo?.(msg, httpRequestId, isNominal ? 'info' : 'error');
249
+ logRuntimeInfo?.(msg, httpRequestId, isNominal ? 'info' : 'error-note');
249
250
  }
250
251
  function prettyUrl(url) {
251
252
  try {
@@ -485,7 +486,7 @@ function getPageContextSkipRequest(pageContextInit) {
485
486
  return pageContext;
486
487
  }
487
488
  function getPageContextInvalidVikeConfig(err, pageContextInit, httpRequestId) {
488
- logRuntimeInfo?.(pc.bold(pc.red('Error loading Vike config — see error above')), httpRequestId, 'error');
489
+ logRuntimeInfo?.(pc.bold(pc.red('Error loading Vike config — see error above')), httpRequestId, 'error-note');
489
490
  const pageContextWithError = getPageContextHttpResponseErrorWithoutGlobalContext(err, pageContextInit);
490
491
  return pageContextWithError;
491
492
  }
@@ -18,8 +18,8 @@ async function createDevMiddleware(options = {}) {
18
18
  },
19
19
  },
20
20
  };
21
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(optionsMod, 'dev');
22
- const server = await createServer(viteConfigFromUserEnhanced);
21
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(optionsMod, 'dev');
22
+ const server = await createServer(viteConfigFromUserResolved);
23
23
  const devMiddleware = server.middlewares;
24
24
  return { devMiddleware, viteServer: server, viteConfig: server.config };
25
25
  }
@@ -8,7 +8,7 @@ export type { VikeVitePluginOptions };
8
8
  type PluginInterop = Record<string, unknown> & {
9
9
  name: string;
10
10
  };
11
- declare function plugin(vikeVitePluginOptions?: VikeVitePluginOptions): PluginInterop[];
11
+ declare function plugin(vikeVitePluginOptions?: VikeVitePluginOptions): Promise<PluginInterop[]>;
12
12
  /** @deprecated Define Vike settings in +config.js instead of vite.config.js */
13
13
  type VikeVitePluginOptions = {
14
14
  /** @deprecated Define Vike settings in +config.js instead of vite.config.js */