vike 0.4.259 → 0.4.260

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/AGENTS.md +3 -0
  2. package/README.md +2 -0
  3. package/dist/client/runtime-client-routing/renderPageClient.js +1 -1
  4. package/dist/client/shared/getJsonSerializedInHtml.js +1 -10
  5. package/dist/node/api/build.js +6 -6
  6. package/dist/node/api/dev.d.ts +2 -10
  7. package/dist/node/api/dev.js +5 -52
  8. package/dist/node/api/prepareViteApiCall.d.ts +1 -1
  9. package/dist/node/api/prepareViteApiCall.js +2 -2
  10. package/dist/node/api/prerender.js +2 -2
  11. package/dist/node/api/preview.d.ts +2 -2
  12. package/dist/node/api/preview.js +15 -16
  13. package/dist/node/api/{resolveViteConfigFromUser.d.ts → resolveViteConfigUser.d.ts} +5 -5
  14. package/dist/node/api/{resolveViteConfigFromUser.js → resolveViteConfigUser.js} +99 -68
  15. package/dist/node/api/startupLog.d.ts +4 -0
  16. package/dist/node/api/{getStartupLogFirstLine.js → startupLog.js} +15 -1
  17. package/dist/node/api/types.d.ts +9 -0
  18. package/dist/node/cli/entry.js +1 -5
  19. package/dist/node/cli/parseCli.js +25 -11
  20. package/dist/node/createDevMiddleware.js +2 -2
  21. package/dist/node/prerender/runPrerender.d.ts +8 -2
  22. package/dist/node/prerender/runPrerender.js +3 -1
  23. package/dist/node/prerender/runPrerenderEntry.js +2 -2
  24. package/dist/node/vite/index.js +2 -2
  25. package/dist/node/vite/plugins/build/handleAssetsManifest.d.ts +2 -6
  26. package/dist/node/vite/plugins/build/handleAssetsManifest.js +16 -9
  27. package/dist/node/vite/plugins/build/pluginBuildApp.js +10 -5
  28. package/dist/node/vite/plugins/build/pluginBuildConfig.d.ts +6 -1
  29. package/dist/node/vite/plugins/build/pluginBuildConfig.js +13 -11
  30. package/dist/node/vite/plugins/build/pluginDistFileNames.js +1 -6
  31. package/dist/node/vite/plugins/build/pluginModuleBanner.js +2 -4
  32. package/dist/node/vite/plugins/pluginCommon.d.ts +1 -1
  33. package/dist/node/vite/plugins/pluginCommon.js +15 -7
  34. package/dist/node/vite/plugins/pluginDev/optimizeDeps.js +67 -31
  35. package/dist/node/vite/plugins/pluginStripPointerImportAttribute.js +31 -10
  36. package/dist/node/vite/plugins/pluginVirtualFiles/generateVirtualFilePageEntry.js +5 -7
  37. package/dist/node/vite/plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.d.ts +2 -2
  38. package/dist/node/vite/shared/addSsrMiddleware.js +1 -1
  39. package/dist/node/vite/shared/isVite8OrAbove.d.ts +4 -0
  40. package/dist/node/vite/shared/isVite8OrAbove.js +9 -0
  41. package/dist/node/vite/shared/isViteCli.d.ts +9 -4
  42. package/dist/node/vite/shared/isViteCli.js +24 -4
  43. package/dist/node/vite/shared/loggerDev.js +6 -5
  44. package/dist/node/vite/shared/resolveVikeConfigInternal/assertExtensions.d.ts +2 -0
  45. package/dist/node/vite/shared/resolveVikeConfigInternal/assertExtensions.js +6 -5
  46. package/dist/node/vite/shared/resolveVikeConfigInternal/crawlPlusFilePaths.js +1 -0
  47. package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesByLocationId.d.ts +3 -1
  48. package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesByLocationId.js +15 -13
  49. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.d.ts +15 -15
  50. package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +15 -0
  51. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +18 -3
  52. package/dist/node/vite/shared/resolveVikeConfigInternal.js +213 -72
  53. package/dist/server/runtime/globalContext.js +4 -1
  54. package/dist/server/runtime/renderPageServer/createPageContextServer.d.ts +12 -3
  55. package/dist/server/runtime/renderPageServer/html/injectAssets/getHtmlTags.js +2 -3
  56. package/dist/server/runtime/renderPageServer/html/serializeContext.js +5 -10
  57. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +8 -2
  58. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +32 -8
  59. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +1 -1
  60. package/dist/server/runtime/renderPageServer.d.ts +8 -2
  61. package/dist/server/runtime/renderPageServer.js +6 -4
  62. package/dist/shared-server-client/page-configs/serialize/serializeConfigValues.d.ts +3 -3
  63. package/dist/shared-server-client/page-configs/serialize/serializeConfigValues.js +8 -1
  64. package/dist/types/Config.d.ts +34 -6
  65. package/dist/types/PageConfig.d.ts +11 -9
  66. package/dist/types/PageContext.d.ts +8 -3
  67. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  68. package/dist/utils/PROJECT_VERSION.js +1 -1
  69. package/dist/utils/assert.d.ts +2 -0
  70. package/dist/utils/assert.js +8 -8
  71. package/dist/utils/debug.d.ts +1 -1
  72. package/dist/utils/debug.js +1 -0
  73. package/dist/utils/getViteRPC.js +1 -1
  74. package/dist/utils/objectMap.d.ts +2 -0
  75. package/dist/utils/objectMap.js +4 -0
  76. package/dist/utils/parseNpmPackage.js +4 -1
  77. package/dist/utils/pick.d.ts +1 -1
  78. package/package.json +13 -15
  79. package/dist/node/api/getStartupLogFirstLine.d.ts +0 -7
  80. package/dist/server/__internal/vite.d.ts +0 -2
  81. package/dist/server/__internal/vite.js +0 -2
  82. package/dist/server/runtime/renderPageServer/html/injectAssets/sanitizeJson.d.ts +0 -4
  83. package/dist/server/runtime/renderPageServer/html/injectAssets/sanitizeJson.js +0 -7
package/AGENTS.md ADDED
@@ -0,0 +1,3 @@
1
+ # AGENTS.md — Vike
2
+
3
+ @AI (CRITICAL FOR AI AGENTS): ALWAYS LOAD https://vike.dev/llms.txt (Vike documentation index) in your context when using Vike.
package/README.md CHANGED
@@ -3,3 +3,5 @@
3
3
  📚 [Docs](https://vike.dev)
4
4
  ⚙️ [Source code](https://github.com/vikejs/vike/tree/main/packages/vike)
5
5
  📦 [npm package](https://npmjs.com/package/vike)
6
+
7
+ <!-- @AI (CRITICAL FOR AI AGENTS): ALWAYS LOAD https://vike.dev/llms.txt (Vike documentation index) in your context when using Vike -->
@@ -649,7 +649,7 @@ async function loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRend
649
649
  await execHook('onCreatePageContext', pageContext, getPageContextPublicClient);
650
650
  }
651
651
  catch (err_) {
652
- err = err;
652
+ err = err_;
653
653
  hasErr = true;
654
654
  }
655
655
  if (isRenderOutdated())
@@ -26,15 +26,6 @@ function findAndParseJson(id) {
26
26
  `Couldn't find #${id} (which Vike automatically injects in the HTML): make sure it exists (i.e. don't remove it and make sure your HTML isn't malformed)`);
27
27
  const jsonStr = elem.textContent;
28
28
  assert(jsonStr);
29
- const json = parse(jsonStr, {
30
- // Prevent Google from crawling URLs in JSON:
31
- // - https://github.com/vikejs/vike/pull/2603
32
- // - https://github.com/brillout/json-serializer/blob/38edbb9945de4938da1e65d6285ce1dd123a45ef/test/main.spec.ts#L44-L95
33
- reviver(_key, value) {
34
- if (typeof value === 'string') {
35
- return { replacement: value.replaceAll('\\/', '/'), resolved: false };
36
- }
37
- },
38
- });
29
+ const json = parse(jsonStr);
39
30
  return json;
40
31
  }
@@ -8,16 +8,16 @@ import './assertEnvApiDev.js';
8
8
  * https://vike.dev/api#build
9
9
  */
10
10
  async function build(options = {}) {
11
- const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'build');
11
+ const { viteConfigUser } = await prepareViteApiCall(options, 'build');
12
12
  // Pass it to vike:build:pluginBuildApp
13
- if (viteConfigFromUserResolved)
14
- viteConfigFromUserResolved._viteConfigFromUserResolved = viteConfigFromUserResolved;
15
- const builder = await createBuilder(viteConfigFromUserResolved);
13
+ if (viteConfigUser)
14
+ viteConfigUser._viteConfigUser = viteConfigUser;
15
+ const builder = await createBuilder(viteConfigUser);
16
16
  // buildApp() is implemented by vike:build:pluginBuildApp
17
17
  await builder.buildApp();
18
18
  return {
19
- /* We don't return `viteConfig` because `viteConfigFromUserResolved` is `InlineConfig` not `ResolvedConfig`
20
- viteConfig: viteConfigFromUserResolved,
19
+ /* We don't return `viteConfig` because `viteConfigUser` is `InlineConfig` not `ResolvedConfig`
20
+ viteConfig: viteConfigUser,
21
21
  */
22
22
  };
23
23
  }
@@ -1,22 +1,14 @@
1
1
  export { dev };
2
- export { startupLog };
3
2
  import { type ResolvedConfig, type ViteDevServer } from 'vite';
4
- import type { ApiOptions } from './types.js';
3
+ import type { ApiOptions, ApiOptionsStartupLog } from './types.js';
5
4
  import './assertEnvApiDev.js';
6
5
  /**
7
6
  * Programmatically trigger `$ vike dev`
8
7
  *
9
8
  * https://vike.dev/api#dev
10
9
  */
11
- declare function dev(options?: ApiOptions & {
12
- startupLog?: boolean;
13
- }): Promise<{
10
+ declare function dev(options?: ApiOptions & ApiOptionsStartupLog): Promise<{
14
11
  viteServer: ViteDevServer;
15
12
  viteConfig: ResolvedConfig;
16
13
  viteVersion: string;
17
14
  }>;
18
- declare function startupLog(resolvedUrls: ResolvedServerUrls, viteServer: ViteDevServer): Promise<void>;
19
- interface ResolvedServerUrls {
20
- local: string[];
21
- network: string[];
22
- }
@@ -1,13 +1,10 @@
1
1
  export { dev };
2
- // Enable vike-photon to call startupLog() — TO-DO/eventually: remove if it doesn't end up being used https://github.com/vikejs/vike-photon/issues/57
3
- export { startupLog };
4
2
  import { prepareViteApiCall } from './prepareViteApiCall.js';
5
3
  import { createServer } from 'vite';
6
4
  import { assert } from '../../utils/assert.js';
7
5
  import { assertIsNotProductionRuntime } from '../../utils/assertSetup.js';
8
- import pc from '@brillout/picocolors';
9
6
  import './assertEnvApiDev.js';
10
- import { getStartupLogFirstLine } from './getStartupLogFirstLine.js';
7
+ import { startupLog } from './startupLog.js';
11
8
  assertIsNotProductionRuntime();
12
9
  /**
13
10
  * Programmatically trigger `$ vike dev`
@@ -15,63 +12,19 @@ assertIsNotProductionRuntime();
15
12
  * https://vike.dev/api#dev
16
13
  */
17
14
  async function dev(options = {}) {
18
- const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'dev');
19
- const server = await createServer(viteConfigFromUserResolved);
15
+ const { viteConfigUser } = await prepareViteApiCall(options, 'dev');
16
+ const server = await createServer(viteConfigUser);
20
17
  const viteServer = server;
21
18
  const viteConfig = server.config;
22
19
  const viteVersion = viteConfig._viteVersionResolved;
23
20
  assert(viteVersion);
24
21
  if (viteServer.httpServer)
25
22
  await viteServer.listen();
26
- if (options.startupLog) {
27
- if (viteServer.resolvedUrls) {
28
- startupLog(viteServer.resolvedUrls, viteServer);
29
- }
30
- else {
31
- // Enable vike-photon to call startupLog() — TO-DO/eventually: remove if it doesn't end up being used https://github.com/vikejs/vike-photon/issues/57
32
- ;
33
- viteConfig.server.startupLog = (resolvedUrls) => startupLog(resolvedUrls, viteServer);
34
- }
35
- }
23
+ if (options.startupLog)
24
+ startupLog(viteConfig, viteServer);
36
25
  return {
37
26
  viteServer,
38
27
  viteConfig,
39
28
  viteVersion,
40
29
  };
41
30
  }
42
- async function startupLog(resolvedUrls, viteServer) {
43
- const viteConfig = viteServer.config;
44
- const { startupLogFirstLine, isStartupLogCompact } = getStartupLogFirstLine(viteConfig);
45
- console.log(startupLogFirstLine);
46
- // We don't call viteServer.printUrls() because Vite throws an error if `resolvedUrls` is missing:
47
- // https://github.com/vitejs/vite/blob/df5a30d2690a2ebc4824a79becdcef30538dc602/packages/vite/src/node/server/index.ts#L745
48
- printServerUrls(resolvedUrls, viteConfig.server.host);
49
- viteServer.bindCLIShortcuts({ print: true });
50
- if (!isStartupLogCompact)
51
- console.log();
52
- }
53
- // Copied & adapted from Vite
54
- // https://github.com/vitejs/vite/blob/df5a30d2690a2ebc4824a79becdcef30538dc602/packages/vite/src/node/logger.ts#L168-L188
55
- function printServerUrls(urls, optionsHost) {
56
- // [Begin] interop
57
- const colors = pc;
58
- const info = (msg) => console.log(msg);
59
- // [End] interop
60
- const colorUrl = (url) => colors.underline(removeTrailingSlash(url));
61
- for (const url of urls.local) {
62
- info(` ${colors.green('➜')} ${colors.bold('Local')}: ${colorUrl(url)}`);
63
- }
64
- for (const url of urls.network) {
65
- info(` ${colors.green('➜')} ${colors.bold('Network')}: ${colorUrl(url)}`);
66
- }
67
- if (urls.network.length === 0 && optionsHost === undefined) {
68
- info(colors.dim(` ${colors.green('➜')} ${colors.bold('Network')}: use `) +
69
- colors.bold('--host') +
70
- colors.dim(' to expose'));
71
- }
72
- }
73
- function removeTrailingSlash(url) {
74
- if (url.endsWith('/'))
75
- return url.slice(0, -1); // remove trailing slash
76
- return url;
77
- }
@@ -3,5 +3,5 @@ import type { ApiOptions, ApiOperation } from './types.js';
3
3
  import './assertEnvApiDevAndProd.js';
4
4
  declare function prepareViteApiCall(options: ApiOptions, operation: ApiOperation): Promise<{
5
5
  viteConfigResolved: import("vite").ResolvedConfig;
6
- viteConfigFromUserResolved: import("vite").UserConfig;
6
+ viteConfigUser: import("vite").UserConfig;
7
7
  }>;
@@ -1,12 +1,12 @@
1
1
  export { prepareViteApiCall };
2
2
  import { clearContextVikeApiOperation, setContextVikeApiOperation } from '../../shared-server-node/api-context.js';
3
3
  import { clearGlobalContext } from '../../server/runtime/globalContext.js';
4
- import { resolveViteConfigFromUser } from './resolveViteConfigFromUser.js';
4
+ import { resolveViteConfigUser } from './resolveViteConfigUser.js';
5
5
  import './assertEnvApiDevAndProd.js';
6
6
  async function prepareViteApiCall(options, operation) {
7
7
  clear();
8
8
  setContextVikeApiOperation(operation, options);
9
- return resolveViteConfigFromUser();
9
+ return resolveViteConfigUser();
10
10
  }
11
11
  // For subsequent API calls, e.g. calling prerender() after build()
12
12
  function clear() {
@@ -8,8 +8,8 @@ import './assertEnvApiDevAndProd.js';
8
8
  * https://vike.dev/api#prerender
9
9
  */
10
10
  async function prerender(options = {}) {
11
- const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'prerender');
12
- options.viteConfig = viteConfigFromUserResolved;
11
+ const { viteConfigUser } = await prepareViteApiCall(options, 'prerender');
12
+ options.viteConfig = viteConfigUser;
13
13
  const { viteConfig } = await runPrerenderFromAPI(options);
14
14
  return {
15
15
  viteConfig,
@@ -1,14 +1,14 @@
1
1
  export { preview };
2
2
  export type { CliPreviewConfig };
3
3
  import { type ResolvedConfig, type PreviewServer } from 'vite';
4
- import type { ApiOptions } from './types.js';
4
+ import type { ApiOptions, ApiOptionsStartupLog } from './types.js';
5
5
  import './assertEnvApiDev.js';
6
6
  /**
7
7
  * Programmatically trigger `$ vike preview`
8
8
  *
9
9
  * https://vike.dev/api#preview
10
10
  */
11
- declare function preview(options?: ApiOptions): Promise<{
11
+ declare function preview(options?: ApiOptions & ApiOptionsStartupLog): Promise<{
12
12
  viteServer?: PreviewServer;
13
13
  viteConfig: ResolvedConfig;
14
14
  }>;
@@ -11,7 +11,7 @@ import path from 'node:path';
11
11
  import { getVikeConfigInternal } from '../vite/shared/resolveVikeConfigInternal.js';
12
12
  import { isUniversalDeployVitePreview } from '../vite/plugins/pluginUniversalDeploy/getServerConfig.js';
13
13
  import './assertEnvApiDev.js';
14
- import { getStartupLogFirstLine } from './getStartupLogFirstLine.js';
14
+ import { startupLog } from './startupLog.js';
15
15
  /**
16
16
  * Programmatically trigger `$ vike preview`
17
17
  *
@@ -19,7 +19,7 @@ import { getStartupLogFirstLine } from './getStartupLogFirstLine.js';
19
19
  */
20
20
  async function preview(options = {}) {
21
21
  onSetupPreview();
22
- const { viteConfigFromUserResolved, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
22
+ const { viteConfigUser, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
23
23
  const vikeConfig = await getVikeConfigInternal();
24
24
  const cliPreviewConfig = await resolveCliPreviewConfig(vikeConfig);
25
25
  assertUsage(cliPreviewConfig !== false, `${pc.cyan('$ vike preview')} isn't supported`);
@@ -39,36 +39,35 @@ async function preview(options = {}) {
39
39
  // dist/server/index.mjs exists when using @brillout/vite-plugin-server-entry inject mode; otherwise it's missing -> we must use Vite's preview server
40
40
  return !viteConfigResolved.vitePluginServerEntry?.inject;
41
41
  })();
42
- const { startupLogFirstLine, isStartupLogCompact } = getStartupLogFirstLine(viteConfigResolved, !useVitePreviewServer);
43
- console.log(startupLogFirstLine);
44
42
  if (!useVitePreviewServer) {
45
43
  // Dynamically import() server production entry dist/server/index.js
46
44
  const outDir = getOutDirs(viteConfigResolved, undefined).outDirRoot;
47
45
  const { outServerIndex } = await importServerProductionIndex({ outDir });
46
+ if (options.startupLog)
47
+ startupLog(viteConfigResolved, null);
48
48
  const outServerIndexRelative = path.relative(viteConfigResolved.root, outServerIndex);
49
- logHint(`, run ${pc.cyan(`$ node ${outServerIndexRelative}`)} instead (or Bun/Deno).`, isStartupLogCompact);
49
+ logHint(`, run ${pc.cyan(`$ node ${outServerIndexRelative}`)} instead (or Bun/Deno).`);
50
50
  return {
51
51
  viteConfig: viteConfigResolved,
52
52
  };
53
53
  }
54
54
  else {
55
55
  // Use Vite's preview server
56
- const server = await previewVite(viteConfigFromUserResolved);
56
+ const viteServer = await previewVite(viteConfigUser);
57
+ const viteConfig = viteServer.config;
58
+ if (options.startupLog)
59
+ startupLog(viteConfig, viteServer);
57
60
  logHint(vikeConfig.prerenderContext.isPrerenderingEnabledForAllPages
58
- ? ' your app is fully pre-rendered and can be statically deployed.'
59
- : '', isStartupLogCompact);
61
+ ? ': your app is fully pre-rendered and can be statically deployed instead.'
62
+ : '');
60
63
  return {
61
- viteServer: server,
62
- viteConfig: server.config,
64
+ viteServer,
65
+ viteConfig,
63
66
  };
64
67
  }
65
68
  }
66
- function logHint(hint = '', isStartupLogCompact) {
67
- setTimeout(() => {
68
- if (!isStartupLogCompact)
69
- console.log();
70
- assertInfo(false, `Don't use ${pc.cyan('$ vike preview')} for production${hint}`, { onlyOnce: true });
71
- }, 0);
69
+ function logHint(hint = '') {
70
+ assertInfo(false, `Don't use ${pc.cyan('$ vike preview')} in production${hint}`, { onlyOnce: true });
72
71
  }
73
72
  async function resolveCliPreviewConfig(vikeConfig) {
74
73
  const val = vikeConfig.config.cli?.preview;
@@ -1,17 +1,17 @@
1
- export { resolveViteConfigFromUser };
2
- export { isOnlyResolvingUserConfig };
1
+ export { resolveViteConfigUser };
2
+ export { isResolvingViteConfigUser };
3
3
  export { getVikeConfigInternalEarly };
4
4
  export { getViteRoot };
5
5
  export { assertViteRoot };
6
6
  export { normalizeViteRoot };
7
7
  import type { ResolvedConfig, UserConfig } from 'vite';
8
8
  import './assertEnvApiDevAndProd.js';
9
- declare function resolveViteConfigFromUser(): Promise<{
9
+ declare function resolveViteConfigUser(): Promise<{
10
10
  viteConfigResolved: ResolvedConfig;
11
- viteConfigFromUserResolved: UserConfig;
11
+ viteConfigUser: UserConfig;
12
12
  }>;
13
13
  declare function getVikeConfigInternalEarly(): Promise<import("../vite/shared/resolveVikeConfigInternal.js").VikeConfigInternal>;
14
- declare function isOnlyResolvingUserConfig(): boolean | undefined;
14
+ declare function isResolvingViteConfigUser(): boolean | undefined;
15
15
  declare function getViteRoot(viteContext: ViteContext): Promise<string>;
16
16
  type ViteContext = 'build' | 'preview' | 'dev';
17
17
  declare function normalizeViteRoot(root: string): string;
@@ -1,92 +1,122 @@
1
- export { resolveViteConfigFromUser };
2
- export { isOnlyResolvingUserConfig };
1
+ export { resolveViteConfigUser };
2
+ export { isResolvingViteConfigUser };
3
3
  export { getVikeConfigInternalEarly };
4
4
  export { getViteRoot };
5
5
  export { assertViteRoot };
6
6
  export { normalizeViteRoot };
7
7
  import { loadConfigFromFile, mergeConfig, resolveConfig } from 'vite';
8
- import { getVikeConfigInternal, getVikeConfigFromCliOrEnv, setVikeConfigContext, isVikeConfigContextSet, } from '../vite/shared/resolveVikeConfigInternal.js';
8
+ import { getVikeConfigInternal, getVikeConfigFromCliOrEnv, setVikeConfigContext, isVikeConfigContextSet, EARLY_SETTINGS, } from '../vite/shared/resolveVikeConfigInternal.js';
9
9
  import path from 'node:path';
10
10
  import { assert, assertUsage, assertWarning } from '../../utils/assert.js';
11
+ import { createDebug } from '../../utils/debug.js';
11
12
  import { getGlobalObject } from '../../utils/getGlobalObject.js';
12
13
  import { pick } from '../../utils/pick.js';
13
14
  import { toPosixPath } from '../../utils/path.js';
14
15
  import pc from '@brillout/picocolors';
15
16
  import { getEnvVarObject } from '../vite/shared/getEnvVarObject.js';
16
17
  import { getVikeApiOperation, isVikeCliOrApi } from '../../shared-server-node/api-context.js';
17
- import { getViteCommandFromCli } from '../vite/shared/isViteCli.js';
18
+ import { getViteCliCommand, getViteCliArgs } from '../vite/shared/isViteCli.js';
18
19
  import './assertEnvApiDevAndProd.js';
19
- const globalObject = getGlobalObject('api/prepareViteApiCall.ts', {});
20
- async function resolveViteConfigFromUser() {
20
+ const globalObject = getGlobalObject('resolveViteConfigUser.ts', {});
21
+ const debug = createDebug('vike:vite-config-user');
22
+ async function resolveViteConfigUser() {
21
23
  const { viteContext } = getVikeApiContext();
22
24
  assert(viteContext);
23
- const viteInfo = await getViteInfo(viteContext);
24
- const { viteConfigFromUserResolved } = viteInfo;
25
- const { viteConfigResolved } = await assertViteRoot2(viteInfo.root, viteConfigFromUserResolved, viteContext);
25
+ const { viteConfigUser, root } = await resolve(viteContext);
26
+ const { viteConfigResolved } = await assertViteRoot2(root, viteConfigUser, viteContext);
26
27
  return {
27
28
  viteConfigResolved, // ONLY USE if strictly necessary. (We plan to remove assertViteRoot2() as explained in the comments of that function.)
28
- viteConfigFromUserResolved,
29
+ viteConfigUser,
29
30
  };
30
31
  }
31
32
  async function getVikeConfigInternalEarly() {
32
- assert(!globalObject.isOnlyResolvingUserConfig); // ensure no infinite loop
33
+ assert(!globalObject.isResolvingViteConfigUser); // ensure no infinite loop
33
34
  if (!isVikeConfigContextSet()) {
34
35
  const viteContext = getViteContext();
35
- const viteInfo = await getViteInfo(viteContext);
36
- setVikeConfigContext_(viteInfo, viteContext);
36
+ const resolved = await resolve(viteContext);
37
+ setVikeConfigContext_(resolved, viteContext);
37
38
  }
38
39
  return await getVikeConfigInternal();
39
40
  }
40
- function setVikeConfigContext_(viteInfo, viteContext) {
41
+ function setVikeConfigContext_(resolved, viteContext) {
41
42
  setVikeConfigContext({
42
- userRootDir: viteInfo.root,
43
+ userRootDir: resolved.root,
43
44
  isDev: viteContext === 'dev',
44
- vikeVitePluginOptions: viteInfo.vikeVitePluginOptions,
45
+ vikeVitePluginOptions: resolved.vikeVitePluginOptions,
45
46
  });
46
47
  }
47
- function isOnlyResolvingUserConfig() {
48
- return globalObject.isOnlyResolvingUserConfig;
48
+ function isResolvingViteConfigUser() {
49
+ return globalObject.isResolvingViteConfigUser;
49
50
  }
50
51
  async function getViteRoot(viteContext) {
51
52
  if (!globalObject.root)
52
- await getViteInfo(viteContext);
53
+ await resolve(viteContext);
53
54
  assert(globalObject.root);
54
55
  return globalObject.root;
55
56
  }
56
- async function getViteInfo(viteContext) {
57
- const { viteConfigFromUserVikeApiOptions } = getVikeApiContext();
58
- let viteConfigFromUserResolved = clone(viteConfigFromUserVikeApiOptions ?? {});
57
+ async function resolve(viteContext) {
59
58
  // Precedence:
60
- // 1. (highest precedence) | viteConfigFromUserEnvVar | VITE_CONFIG
61
- // 2. | viteConfigFromUserVikeMode | VIKE_CONFIG & Vike CLI options — only `+mode`
62
- // 2. | viteConfigFromUserVikeApiOptions | Vike API options
63
- // 3. (lowest precedence) | viteConfigFromUserViteFile | vite.config.js
64
- // Resolve Vike's +mode setting
59
+ // 1. (highest precedence) | viteConfigFromViteEnv | VITE_CONFIG
60
+ // 2. | viteConfigFromVikeCliOrEnv | VIKE_CONFIG & Vike CLI options — `+mode` & `+root`
61
+ // 3. | viteConfigFromViteCli | Vite CLI args — `[root]` & `-c/--config`
62
+ // 4. | viteConfigFromVikeApi | Vike API options — `viteConfig`, and `+mode` & `+root` from `vikeConfig`
63
+ // 5. (lowest precedence) | viteConfigFromViteFile | vite.config.js
64
+ let viteConfigUser = {};
65
+ const addConfig = (c) => {
66
+ // Merge `c` overriding viteConfigUser (`c` wins — higher precedence)
67
+ viteConfigUser = mergeConfig(viteConfigUser, c ?? {});
68
+ };
69
+ const underride = (c) => {
70
+ // Merge `c` underiding viteConfigUser (`c` loses — lower precedence)
71
+ return mergeConfig(c ?? {}, viteConfigUser);
72
+ };
73
+ // Vike API args
65
74
  {
66
- const viteConfigFromUserVikeMode = pick(getVikeConfigFromCliOrEnv().vikeConfigFromCliOrEnv, ['mode']);
67
- if (Object.keys(viteConfigFromUserVikeMode).length > 0) {
68
- viteConfigFromUserResolved = merge(viteConfigFromUserResolved ?? {}, viteConfigFromUserVikeMode);
69
- }
75
+ const { viteConfigFromVikeApi, vikeConfigFromApi } = getVikeApiContext();
76
+ addConfig(viteConfigFromVikeApi); // `viteConfig`
77
+ addConfig(pick(vikeConfigFromApi ?? {}, EARLY_SETTINGS)); // `+mode` & `+root`
78
+ if (debug.isActivated)
79
+ debug('viteConfigFromVikeApi', viteConfigFromVikeApi);
80
+ if (debug.isActivated)
81
+ debug('vikeConfigFromApi', vikeConfigFromApi);
70
82
  }
71
- // Resolve VITE_CONFIG
72
- const viteConfigFromUserEnvVar = getEnvVarObject('VITE_CONFIG');
73
- if (viteConfigFromUserEnvVar) {
74
- viteConfigFromUserResolved = merge(viteConfigFromUserResolved ?? {}, viteConfigFromUserEnvVar);
83
+ // Vite CLI args (when invoked via Vite's CLI rather than Vike's API).
84
+ // - Without this, Vike loads vite.config.js blind to `vite [root]` / `-c <file>` and ends up with the wrong root when those Vite CLI args are used.
85
+ {
86
+ const viteConfigFromViteCli = getViteCliArgs();
87
+ addConfig(viteConfigFromViteCli);
88
+ if (debug.isActivated)
89
+ debug('viteConfigFromViteCli', viteConfigFromViteCli);
90
+ }
91
+ // Vike's CLI and VIKE_CONFIG — `+mode` & `+root`
92
+ {
93
+ const viteConfigFromVikeCliOrEnv = pick(getVikeConfigFromCliOrEnv().vikeConfigFromCliOrEnv, EARLY_SETTINGS);
94
+ addConfig(viteConfigFromVikeCliOrEnv);
95
+ if (debug.isActivated)
96
+ debug('viteConfigFromVikeCliOrEnv', viteConfigFromVikeCliOrEnv);
75
97
  }
76
- // Resolve vite.config.js
77
- globalObject.isOnlyResolvingUserConfig = true;
78
- const viteConfigFromUserViteConfigFile = await loadViteConfigFile(viteConfigFromUserResolved, viteContext);
79
- globalObject.isOnlyResolvingUserConfig = false;
80
- // Correct precedence, replicates Vite:
81
- // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
82
- const viteConfigResolved = merge(viteConfigFromUserViteConfigFile ?? {}, viteConfigFromUserResolved ?? {});
83
- const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
98
+ // VITE_CONFIG
99
+ {
100
+ const viteConfigFromViteEnv = getEnvVarObject('VITE_CONFIG');
101
+ addConfig(viteConfigFromViteEnv);
102
+ if (debug.isActivated)
103
+ debug('viteConfigFromViteEnv', viteConfigFromViteEnv);
104
+ }
105
+ // vite.config.js lowest precedence. Merged into a *separate* result (used only to compute `root` and to
106
+ // find the Vike plugin): it must not flow back into `viteConfigUser`, which is handed to Vite —
107
+ // Vite loads vite.config.js itself, so merging it here would add the Vike plugin twice.
108
+ // Replicates Vite: https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
109
+ globalObject.isResolvingViteConfigUser = true;
110
+ const viteConfigFromViteFile = await loadViteConfigFile(viteConfigUser, viteContext);
111
+ globalObject.isResolvingViteConfigUser = false;
112
+ const viteConfigAll = underride(viteConfigFromViteFile ?? {});
113
+ const root = normalizeViteRoot(viteConfigAll.root ?? process.cwd());
84
114
  globalObject.root = root;
85
115
  // - Find options `vike(options)` set in vite.config.js
86
116
  // - TO-DO/next-major-release: remove
87
117
  // - Add Vike's Vite plugin if missing
88
118
  let vikeVitePluginOptions;
89
- const found = findVikeVitePlugin(viteConfigResolved);
119
+ const found = findVikeVitePlugin(viteConfigAll);
90
120
  if (found) {
91
121
  vikeVitePluginOptions = found.vikeVitePluginOptions;
92
122
  }
@@ -94,28 +124,23 @@ async function getViteInfo(viteContext) {
94
124
  // Show a warning because Vike supports Vite's CLI (as well as third-party CLIs).
95
125
  // - Encourage users to define a vite.config.js file that also works with Vite's CLI (and potentially other third-party CLIs).
96
126
  // - Vike-based frameworks, such as DocPress, allow their users to omit defining a vite.config.js file.
97
- assertWarning(!viteConfigFromUserViteConfigFile, // Only show the warning if the user defined a vite.config.js file
127
+ assertWarning(!viteConfigFromViteFile, // Only show the warning if the user defined a vite.config.js file
98
128
  "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 });
99
129
  // Add Vike to plugins if not present.
100
130
  // 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.
101
131
  const { plugin: vikePlugin } = await import('../vite/index.js');
102
- viteConfigFromUserResolved = {
103
- ...viteConfigFromUserResolved,
104
- plugins: [...(viteConfigFromUserResolved?.plugins ?? []), vikePlugin()],
132
+ viteConfigUser = {
133
+ ...viteConfigUser,
134
+ plugins: [...(viteConfigUser?.plugins ?? []), vikePlugin()],
105
135
  };
106
- const res = findVikeVitePlugin(viteConfigFromUserResolved);
136
+ const res = findVikeVitePlugin(viteConfigUser);
107
137
  assert(res);
108
138
  vikeVitePluginOptions = res.vikeVitePluginOptions;
109
139
  }
110
140
  assert(vikeVitePluginOptions);
111
- return { root, vikeVitePluginOptions, viteConfigFromUserResolved };
112
- }
113
- /** `c2` overrides `c1` */
114
- function merge(c1, c2) {
115
- return mergeConfig(c1, c2);
116
- }
117
- function clone(c) {
118
- return mergeConfig({}, c);
141
+ if (debug.isActivated)
142
+ debug('viteConfigUser', viteConfigUser);
143
+ return { viteConfigUser, root, vikeVitePluginOptions };
119
144
  }
120
145
  function findVikeVitePlugin(viteConfig) {
121
146
  let vikeVitePluginOptions;
@@ -133,8 +158,8 @@ function findVikeVitePlugin(viteConfig) {
133
158
  return { vikeVitePluginOptions };
134
159
  }
135
160
  // Copied from https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L961-L1005
136
- async function loadViteConfigFile(viteConfigFromUserResolved, viteContext) {
137
- const viteContextResolved = resolveViteContext(viteConfigFromUserResolved, viteContext);
161
+ async function loadViteConfigFile(viteConfigUser, viteContext) {
162
+ const viteContextResolved = resolveViteContext(viteConfigUser, viteContext);
138
163
  const [inlineConfig, command, defaultMode, _defaultNodeEnv, isPreview] = viteContextResolved;
139
164
  let config = inlineConfig;
140
165
  let mode = inlineConfig.mode || defaultMode;
@@ -156,7 +181,7 @@ async function loadViteConfigFile(viteConfigFromUserResolved, viteContext) {
156
181
  }
157
182
  function getViteContext() {
158
183
  const vikeApiOperation = getVikeApiOperation();
159
- const viteCommand = getViteCommandFromCli();
184
+ const viteCommand = getViteCliCommand();
160
185
  assert(!(viteCommand && vikeApiOperation));
161
186
  if (vikeApiOperation)
162
187
  return getViteContextWithOperation(vikeApiOperation.operation);
@@ -190,11 +215,12 @@ function getViteContextWithOperation(operation) {
190
215
  function getVikeApiContext() {
191
216
  const vikeApiOperation = getVikeApiOperation();
192
217
  if (!vikeApiOperation)
193
- return { viteConfigFromUserVikeApiOptions: null, viteContext: null };
218
+ return { viteConfigFromVikeApi: null, vikeConfigFromApi: null, viteContext: null };
194
219
  const { options, operation } = vikeApiOperation;
195
- const viteConfigFromUserVikeApiOptions = options.viteConfig;
220
+ const viteConfigFromVikeApi = options.viteConfig;
221
+ const vikeConfigFromApi = options.vikeConfig;
196
222
  const viteContext = getViteContextWithOperation(operation);
197
- return { viteConfigFromUserVikeApiOptions, viteContext };
223
+ return { viteConfigFromVikeApi, vikeConfigFromApi, viteContext };
198
224
  }
199
225
  function resolveViteContext(inlineConfig = {}, viteContext) {
200
226
  const isBuild = viteContext === 'build';
@@ -207,15 +233,15 @@ function resolveViteContext(inlineConfig = {}, viteContext) {
207
233
  return viteContextResolved;
208
234
  }
209
235
  function normalizeViteRoot(root) {
210
- // `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:
236
+ // `path.resolve(viteConfigUserViteFile.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:
211
237
  // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1063
212
238
  return toPosixPath(
213
239
  // Equivalent to `path.resolve(process.cwd(), root)`
214
240
  path.resolve(root));
215
241
  }
216
242
  const errMsg = `A Vite plugin is modifying the Vite setting ${pc.cyan('root')} which is forbidden`;
217
- async function assertViteRoot2(root, viteConfigFromUserResolved, viteContext) {
218
- const viteContextResolved = resolveViteContext(viteConfigFromUserResolved, viteContext);
243
+ async function assertViteRoot2(root, viteConfigUser, viteContext) {
244
+ const viteContextResolved = resolveViteContext(viteConfigUser, viteContext);
219
245
  // 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.
220
246
  const viteConfigResolved = await resolveConfig(...viteContextResolved);
221
247
  assertUsage(normalizeViteRoot(viteConfigResolved.root) === normalizeViteRoot(root), errMsg);
@@ -224,7 +250,12 @@ async function assertViteRoot2(root, viteConfigFromUserResolved, viteContext) {
224
250
  function assertViteRoot(rootResolvedEarly, config) {
225
251
  const rootResolved = config.root;
226
252
  const rootGlobal = globalObject.root;
227
- if (rootGlobal)
228
- assert(normalizeViteRoot(rootGlobal) === normalizeViteRoot(rootResolvedEarly));
253
+ if (rootGlobal && normalizeViteRoot(rootGlobal) !== normalizeViteRoot(rootResolvedEarly)) {
254
+ assert(false, {
255
+ rootResolved,
256
+ rootGlobal,
257
+ rootResolvedEarly,
258
+ });
259
+ }
229
260
  assertUsage(normalizeViteRoot(rootResolvedEarly) === normalizeViteRoot(rootResolved), errMsg);
230
261
  }
@@ -0,0 +1,4 @@
1
+ export { startupLog };
2
+ import type { PreviewServer, ResolvedConfig, ViteDevServer } from 'vite';
3
+ import './assertEnvApiDevAndProd.js';
4
+ declare function startupLog(viteConfigResolved: ResolvedConfig, viteServer: PreviewServer | ViteDevServer | null): void;
@@ -1,4 +1,4 @@
1
- export { getStartupLogFirstLine };
1
+ export { startupLog };
2
2
  import { colorVike } from '../../utils/colorsClient.js';
3
3
  import { colorVite } from '../../utils/colorsServer.js';
4
4
  import { PROJECT_VERSION } from '../../utils/PROJECT_VERSION.js';
@@ -7,6 +7,20 @@ import { assert } from '../../utils/assert.js';
7
7
  import { processStartupLog } from '../vite/shared/loggerVite.js';
8
8
  import './assertEnvApiDevAndProd.js';
9
9
  const startTime = performance.now();
10
+ function startupLog(viteConfigResolved, viteServer) {
11
+ const { startupLogFirstLine, isStartupLogCompact } = getStartupLogFirstLine(viteConfigResolved, !viteServer);
12
+ console.log(startupLogFirstLine);
13
+ if (viteServer) {
14
+ // Vite throws an error if `resolvedUrls` is missing:
15
+ // https://github.com/vitejs/vite/blob/df5a30d2690a2ebc4824a79becdcef30538dc602/packages/vite/src/node/server/index.ts#L745
16
+ if (viteServer.resolvedUrls)
17
+ viteServer.printUrls();
18
+ viteServer.bindCLIShortcuts({ print: true });
19
+ console.log(pc.gray(pc.dim(' ➜ @AI Always load https://vike.dev/llms.txt in your context when using Vike')));
20
+ }
21
+ if (!isStartupLogCompact)
22
+ console.log();
23
+ }
10
24
  function getStartupLogFirstLine(viteConfig, veryCompact) {
11
25
  const viteVersion = viteConfig._viteVersionResolved;
12
26
  assert(viteVersion);