vike 0.4.241-commit-206146b → 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 (32) hide show
  1. package/dist/esm/node/api/build.js +6 -6
  2. package/dist/esm/node/api/dev.js +2 -2
  3. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -9
  4. package/dist/esm/node/api/prepareViteApiCall.js +4 -156
  5. package/dist/esm/node/api/prerender.js +2 -2
  6. package/dist/esm/node/api/preview.js +2 -2
  7. package/dist/esm/node/api/resolveViteConfigFromUser.d.ts +20 -0
  8. package/dist/esm/node/api/resolveViteConfigFromUser.js +207 -0
  9. package/dist/esm/node/prerender/runPrerenderEntry.js +4 -4
  10. package/dist/esm/node/runtime/logErrorServer.js +5 -4
  11. package/dist/esm/node/runtime-dev/createDevMiddleware.js +2 -2
  12. package/dist/esm/node/vite/index.d.ts +1 -1
  13. package/dist/esm/node/vite/index.js +52 -21
  14. package/dist/esm/node/vite/plugins/build/pluginBuildApp.js +6 -6
  15. package/dist/esm/node/vite/plugins/pluginCommon.d.ts +1 -1
  16. package/dist/esm/node/vite/plugins/pluginCommon.js +9 -7
  17. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.d.ts +3 -0
  18. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.js +32 -0
  19. package/dist/esm/node/vite/shared/isViteCli.d.ts +13 -0
  20. package/dist/esm/node/vite/shared/isViteCli.js +143 -0
  21. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +11 -2
  22. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.d.ts +2 -0
  23. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.js +4 -0
  24. package/dist/esm/node/vite/utils.d.ts +1 -0
  25. package/dist/esm/node/vite/utils.js +1 -0
  26. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  27. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  28. package/dist/esm/utils/isExactlyOneTruthy.d.ts +1 -0
  29. package/dist/esm/utils/isExactlyOneTruthy.js +4 -0
  30. package/package.json +1 -1
  31. package/dist/esm/node/vite/shared/isViteCliCall.d.ts +0 -10
  32. package/dist/esm/node/vite/shared/isViteCliCall.js +0 -81
@@ -7,16 +7,16 @@ import { createBuilder } from 'vite';
7
7
  * https://vike.dev/api#build
8
8
  */
9
9
  async function build(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'build');
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'build');
11
11
  // Pass it to vike:build:pluginBuildApp
12
- if (viteConfigFromUserEnhanced)
13
- viteConfigFromUserEnhanced._viteConfigFromUserEnhanced = viteConfigFromUserEnhanced;
14
- const builder = await createBuilder(viteConfigFromUserEnhanced);
12
+ if (viteConfigFromUserResolved)
13
+ viteConfigFromUserResolved._viteConfigFromUserResolved = viteConfigFromUserResolved;
14
+ const builder = await createBuilder(viteConfigFromUserResolved);
15
15
  // buildApp() is implemented by vike:build:pluginBuildApp
16
16
  await builder.buildApp();
17
17
  return {
18
- /* We don't return `viteConfig` because `viteConfigFromUserEnhanced` is `InlineConfig` not `ResolvedConfig`
19
- viteConfig: viteConfigFromUserEnhanced,
18
+ /* We don't return `viteConfig` because `viteConfigFromUserResolved` is `InlineConfig` not `ResolvedConfig`
19
+ viteConfig: viteConfigFromUserResolved,
20
20
  */
21
21
  };
22
22
  }
@@ -7,8 +7,8 @@ import { createServer } from 'vite';
7
7
  * https://vike.dev/api#dev
8
8
  */
9
9
  async function dev(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'dev');
11
- const server = await createServer(viteConfigFromUserEnhanced);
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'dev');
11
+ const server = await createServer(viteConfigFromUserResolved);
12
12
  return {
13
13
  viteServer: server,
14
14
  viteConfig: server.config,
@@ -1,13 +1,6 @@
1
1
  export { prepareViteApiCall };
2
- export { getViteRoot };
3
- export { assertViteRoot };
4
- export { normalizeViteRoot };
5
- import type { InlineConfig, ResolvedConfig } from 'vite';
6
2
  import type { ApiOptions, ApiOperation } from './types.js';
7
3
  declare function prepareViteApiCall(options: ApiOptions, operation: ApiOperation): Promise<{
8
- viteConfigResolved: ResolvedConfig;
9
- viteConfigFromUserEnhanced: InlineConfig | undefined;
4
+ viteConfigResolved: import("vite").ResolvedConfig;
5
+ viteConfigFromUserResolved: import("vite").InlineConfig | undefined;
10
6
  }>;
11
- declare function getViteRoot(operation: ApiOperation): Promise<string>;
12
- declare function normalizeViteRoot(root: string): string;
13
- declare function assertViteRoot(root: string, config: ResolvedConfig): void;
@@ -1,168 +1,16 @@
1
1
  export { prepareViteApiCall };
2
- export { getViteRoot };
3
- export { assertViteRoot };
4
- export { normalizeViteRoot };
5
- import { loadConfigFromFile, mergeConfig, resolveConfig } from 'vite';
6
2
  import { clearContextVikeApiOperation, setContextVikeApiOperation } from './context.js';
7
- import { getVikeConfigInternal, getVikeConfigFromCliOrEnv, setVikeConfigContext, } from '../vite/shared/resolveVikeConfigInternal.js';
8
- import path from 'node:path';
9
- import { assert, assertUsage, getGlobalObject, isObject, pick, toPosixPath } from './utils.js';
10
- import pc from '@brillout/picocolors';
11
3
  import { clearGlobalContext } from '../runtime/globalContext.js';
12
- import { getEnvVarObject } from '../vite/shared/getEnvVarObject.js';
13
- const globalObject = getGlobalObject('api/prepareViteApiCall.ts', {});
4
+ import { getViteContextWithOperation, resolveViteConfigFromUser } from './resolveViteConfigFromUser.js';
14
5
  async function prepareViteApiCall(options, operation) {
15
6
  clear();
16
7
  setContextVikeApiOperation(operation, options);
17
- const viteConfigFromUserApiOptions = options.viteConfig;
18
- return resolveConfigs(viteConfigFromUserApiOptions, operation);
8
+ const viteConfigFromUserVikeApiOptions = options.viteConfig;
9
+ const viteContext = getViteContextWithOperation(operation);
10
+ return resolveViteConfigFromUser(viteConfigFromUserVikeApiOptions, viteContext);
19
11
  }
20
12
  // For subsequent API calls, e.g. calling prerender() after build()
21
13
  function clear() {
22
14
  clearContextVikeApiOperation();
23
15
  clearGlobalContext();
24
16
  }
25
- async function resolveConfigs(viteConfigFromUserApiOptions, operation) {
26
- const viteInfo = await getViteInfo(viteConfigFromUserApiOptions, operation);
27
- setVikeConfigContext({
28
- userRootDir: viteInfo.root,
29
- isDev: operation === 'dev',
30
- vikeVitePluginOptions: viteInfo.vikeVitePluginOptions,
31
- });
32
- const vikeConfig = await getVikeConfigInternal();
33
- const viteConfigFromUserEnhanced = applyVikeViteConfig(viteInfo.viteConfigFromUserEnhanced, vikeConfig);
34
- const { viteConfigResolved } = await assertViteRoot2(viteInfo.root, viteConfigFromUserEnhanced, operation);
35
- return {
36
- viteConfigResolved, // ONLY USE if strictly necessary. (We plan to remove assertViteRoot2() as explained in the comments of that function.)
37
- viteConfigFromUserEnhanced,
38
- };
39
- }
40
- // Apply +vite
41
- // - For example, Vike extensions adding Vite plugins
42
- function applyVikeViteConfig(viteConfigFromUserEnhanced, vikeConfig) {
43
- const viteConfigs = vikeConfig._from.configsCumulative.vite;
44
- if (!viteConfigs)
45
- return viteConfigFromUserEnhanced;
46
- viteConfigs.values.forEach((v) => {
47
- assertUsage(isObject(v.value), `${v.definedAt} should be an object`);
48
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, v.value);
49
- assertUsage(!findVikeVitePlugin(v.value), "Using the +vite setting to add Vike's Vite plugin is forbidden");
50
- });
51
- return viteConfigFromUserEnhanced;
52
- }
53
- async function getViteRoot(operation) {
54
- if (!globalObject.root)
55
- await getViteInfo(undefined, operation);
56
- assert(globalObject.root);
57
- return globalObject.root;
58
- }
59
- async function getViteInfo(viteConfigFromUserApiOptions, operation) {
60
- let viteConfigFromUserEnhanced = viteConfigFromUserApiOptions;
61
- // Precedence:
62
- // 1) viteConfigFromUserEnvVar (highest precedence)
63
- // 2) viteConfigFromUserVikeConfig
64
- // 2) viteConfigFromUserApiOptions
65
- // 3) viteConfigFromUserViteFile (lowest precedence)
66
- // Resolve Vike's +mode setting
67
- {
68
- const viteConfigFromUserVikeConfig = pick(getVikeConfigFromCliOrEnv().vikeConfigFromCliOrEnv, ['mode']);
69
- if (Object.keys(viteConfigFromUserVikeConfig).length > 0) {
70
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserVikeConfig);
71
- }
72
- }
73
- // Resolve VITE_CONFIG
74
- const viteConfigFromUserEnvVar = getEnvVarObject('VITE_CONFIG');
75
- if (viteConfigFromUserEnvVar) {
76
- viteConfigFromUserEnhanced = mergeConfig(viteConfigFromUserEnhanced ?? {}, viteConfigFromUserEnvVar);
77
- }
78
- // Resolve vite.config.js
79
- const viteConfigFromUserViteFile = await loadViteConfigFile(viteConfigFromUserEnhanced, operation);
80
- // Correct precedence, replicates Vite:
81
- // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
82
- const viteConfigResolved = mergeConfig(viteConfigFromUserViteFile ?? {}, viteConfigFromUserEnhanced ?? {});
83
- const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
84
- globalObject.root = root;
85
- // - Find options `vike(options)` set in vite.config.js
86
- // - TO-DO/next-major-release: remove
87
- // - Add Vike's Vite plugin if missing
88
- let vikeVitePluginOptions;
89
- const found = findVikeVitePlugin(viteConfigResolved);
90
- if (found) {
91
- vikeVitePluginOptions = found.vikeVitePluginOptions;
92
- }
93
- else {
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
- viteConfigFromUserEnhanced = {
98
- ...viteConfigFromUserEnhanced,
99
- plugins: [...(viteConfigFromUserEnhanced?.plugins ?? []), vikePlugin()],
100
- };
101
- const res = findVikeVitePlugin(viteConfigFromUserEnhanced);
102
- assert(res);
103
- vikeVitePluginOptions = res.vikeVitePluginOptions;
104
- }
105
- assert(vikeVitePluginOptions);
106
- return { root, vikeVitePluginOptions, viteConfigFromUserEnhanced };
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(viteConfigFromUserApiOptions, operation) {
125
- const [inlineConfig, command, defaultMode, _defaultNodeEnv, isPreview] = getResolveConfigArgs(viteConfigFromUserApiOptions, operation);
126
- let config = inlineConfig;
127
- let mode = inlineConfig.mode || defaultMode;
128
- const configEnv = {
129
- mode,
130
- command,
131
- isSsrBuild: command === 'build' && !!config.build?.ssr,
132
- isPreview,
133
- };
134
- let { configFile } = config;
135
- if (configFile !== false) {
136
- const loadResult = await loadConfigFromFile(configEnv, configFile, config.root, config.logLevel, config.customLogger);
137
- return loadResult?.config;
138
- }
139
- return null;
140
- }
141
- function getResolveConfigArgs(viteConfig = {}, operation) {
142
- const inlineConfig = viteConfig;
143
- const command = operation === 'build' || operation === 'prerender' ? 'build' : 'serve';
144
- const defaultMode = operation === 'dev' ? 'development' : 'production';
145
- const defaultNodeEnv = defaultMode;
146
- const isPreview = operation === 'preview';
147
- return [inlineConfig, command, defaultMode, defaultNodeEnv, isPreview];
148
- }
149
- function normalizeViteRoot(root) {
150
- // `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:
151
- // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1063
152
- return toPosixPath(
153
- // Equivalent to `path.resolve(process.cwd(), root)`
154
- path.resolve(root));
155
- }
156
- const errMsg = `A Vite plugin is modifying Vite's setting ${pc.cyan('root')} which is forbidden`;
157
- async function assertViteRoot2(root, viteConfigFromUserEnhanced, operation) {
158
- const args = getResolveConfigArgs(viteConfigFromUserEnhanced, operation);
159
- // 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.
160
- const viteConfigResolved = await resolveConfig(...args);
161
- assertUsage(normalizeViteRoot(viteConfigResolved.root) === normalizeViteRoot(root), errMsg);
162
- return { viteConfigResolved };
163
- }
164
- function assertViteRoot(root, config) {
165
- if (globalObject.root)
166
- assert(normalizeViteRoot(globalObject.root) === normalizeViteRoot(root));
167
- assertUsage(normalizeViteRoot(root) === normalizeViteRoot(config.root), errMsg);
168
- }
@@ -7,8 +7,8 @@ import { prepareViteApiCall } from './prepareViteApiCall.js';
7
7
  * https://vike.dev/api#prerender
8
8
  */
9
9
  async function prerender(options = {}) {
10
- const { viteConfigFromUserEnhanced } = await prepareViteApiCall(options, 'prerender');
11
- options.viteConfig = viteConfigFromUserEnhanced;
10
+ const { viteConfigFromUserResolved } = await prepareViteApiCall(options, 'prerender');
11
+ options.viteConfig = viteConfigFromUserResolved;
12
12
  const { viteConfig } = await runPrerenderFromAPI(options);
13
13
  return {
14
14
  viteConfig,
@@ -13,7 +13,7 @@ import path from 'node:path';
13
13
  */
14
14
  async function preview(options = {}) {
15
15
  onSetupPreview();
16
- const { viteConfigFromUserEnhanced, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
16
+ const { viteConfigFromUserResolved, viteConfigResolved } = await prepareViteApiCall(options, 'preview');
17
17
  if (viteConfigResolved.vitePluginServerEntry?.inject) {
18
18
  const outDir = getOutDirs(viteConfigResolved, undefined).outDirRoot;
19
19
  const { outServerIndex } = await importServerProductionIndex({ outDir });
@@ -24,7 +24,7 @@ async function preview(options = {}) {
24
24
  };
25
25
  }
26
26
  else {
27
- const server = await previewVite(viteConfigFromUserEnhanced);
27
+ const server = await previewVite(viteConfigFromUserResolved);
28
28
  return {
29
29
  viteServer: server,
30
30
  viteConfig: server.config,
@@ -0,0 +1,20 @@
1
+ export { resolveViteConfigFromUser };
2
+ export { isOnlyResolvingUserConfig };
3
+ export { getVikeConfigInternalEarly };
4
+ export { getViteContextWithOperation };
5
+ export { getViteRoot };
6
+ export { assertViteRoot };
7
+ export { normalizeViteRoot };
8
+ import type { InlineConfig, ResolvedConfig } from 'vite';
9
+ import type { ApiOperation } from './types.js';
10
+ declare function resolveViteConfigFromUser(viteConfigFromUserVikeApiOptions: InlineConfig | undefined, viteContext: ViteContext): Promise<{
11
+ viteConfigResolved: ResolvedConfig;
12
+ viteConfigFromUserResolved: InlineConfig | undefined;
13
+ }>;
14
+ declare function getVikeConfigInternalEarly(): Promise<import("../vite/shared/resolveVikeConfigInternal.js").VikeConfigInternal>;
15
+ declare function isOnlyResolvingUserConfig(): boolean | undefined;
16
+ declare function getViteRoot(viteContext: ViteContext): Promise<string>;
17
+ type ViteContext = 'build' | 'preview' | 'dev';
18
+ declare function getViteContextWithOperation(operation: ApiOperation): ViteContext;
19
+ declare function normalizeViteRoot(root: string): string;
20
+ declare function assertViteRoot(root: string, config: ResolvedConfig): void;
@@ -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
+ }
@@ -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() {
@@ -4,10 +4,11 @@ import { isCallable, isObject } from './utils.js';
4
4
  import { execHookOnError } from './renderPage/execHookOnError.js';
5
5
  function logErrorServer(err) {
6
6
  execHookOnError(err);
7
- // TODO https://gist.github.com/brillout/066293a687ab7cf695e62ad867bc6a9c
8
- if (isObject(err) &&
9
- // Set by react-streaming
10
- isCallable(err.getEnhancedError)) {
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)) {
11
12
  err = err.getEnhancedError(err);
12
13
  }
13
14
  // We ensure we print a string; Cloudflare Workers doesn't seem to properly stringify `Error` objects.
@@ -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 */
@@ -6,7 +6,7 @@ export { getVikeConfig } from './shared/resolveVikeConfigInternal.js';
6
6
  export { PROJECT_VERSION as version } from './utils.js';
7
7
  import { getClientEntrySrcDev } from './shared/getClientEntrySrcDev.js';
8
8
  import { setGetClientEntrySrcDev } from '../runtime/renderPage/getPageAssets/retrievePageAssetsDev.js';
9
- import { assertIsNotProductionRuntime, assertUsage } from './utils.js';
9
+ import { assertIsNotProductionRuntime, assertUsage, isVitest } from './utils.js';
10
10
  import pc from '@brillout/picocolors';
11
11
  import { pluginPreview } from './plugins/pluginPreview.js';
12
12
  import { pluginDev } from './plugins/pluginDev.js';
@@ -31,31 +31,40 @@ import { pluginProdBuildEntry } from './plugins/build/pluginProdBuildEntry.js';
31
31
  import { pluginBuildConfig } from './plugins/build/pluginBuildConfig.js';
32
32
  import { pluginModuleBanner } from './plugins/build/pluginModuleBanner.js';
33
33
  import { pluginReplaceConstantsNonRunnableDev } from './plugins/non-runnable-dev/pluginReplaceConstantsNonRunnableDev.js';
34
+ import { isVikeCliOrApi } from '../api/context.js';
35
+ import { pluginViteConfigVikeExtensions } from './plugins/pluginViteConfigVikeExtensions.js';
36
+ import { isOnlyResolvingUserConfig } from '../api/resolveViteConfigFromUser.js';
34
37
  // We don't call this in ./onLoad.ts to avoid a cyclic dependency with utils.ts
35
38
  setGetClientEntrySrcDev(getClientEntrySrcDev);
36
39
  assertIsNotProductionRuntime();
37
40
  // Return `PluginInterop` instead of `Plugin` to avoid type mismatch upon different Vite versions
38
41
  function plugin(vikeVitePluginOptions = {}) {
39
- const plugins = [
40
- ...pluginCommon(vikeVitePluginOptions),
41
- ...pluginVirtualFiles(),
42
- ...pluginDev(),
43
- ...pluginBuild(),
44
- ...pluginPreview(),
45
- ...pluginExtractAssets(),
46
- ...pluginExtractExportNames(),
47
- ...pluginSetGlobalContext(),
48
- ...pluginBaseUrls(),
49
- ...pluginReplaceConstantsEnvVars(),
50
- ...pluginFileEnv(),
51
- ...pluginWorkaroundCssModuleHmr(),
52
- ...pluginWorkaroundVite6HmrRegression(),
53
- ...pluginReplaceConstantsPageContext(),
54
- ...pluginReplaceConstantsGlobalThis(),
55
- ...pluginNonRunnabeDev(),
56
- ];
57
- Object.assign(plugins, { _vikeVitePluginOptions: vikeVitePluginOptions });
58
- return plugins;
42
+ const promise = (async () => {
43
+ if (skip())
44
+ return [];
45
+ const plugins = [
46
+ ...pluginCommon(vikeVitePluginOptions),
47
+ ...pluginVirtualFiles(),
48
+ ...pluginDev(),
49
+ ...pluginBuild(),
50
+ ...pluginPreview(),
51
+ ...pluginExtractAssets(),
52
+ ...pluginExtractExportNames(),
53
+ ...pluginSetGlobalContext(),
54
+ ...pluginBaseUrls(),
55
+ ...pluginReplaceConstantsEnvVars(),
56
+ ...pluginFileEnv(),
57
+ ...pluginWorkaroundCssModuleHmr(),
58
+ ...pluginWorkaroundVite6HmrRegression(),
59
+ ...pluginReplaceConstantsPageContext(),
60
+ ...pluginReplaceConstantsGlobalThis(),
61
+ ...pluginNonRunnabeDev(),
62
+ ...(await pluginViteConfigVikeExtensions()),
63
+ ];
64
+ return plugins;
65
+ })();
66
+ Object.assign(promise, { _vikeVitePluginOptions: vikeVitePluginOptions });
67
+ return promise;
59
68
  }
60
69
  function pluginBuild() {
61
70
  return [
@@ -71,6 +80,28 @@ function pluginBuild() {
71
80
  function pluginNonRunnabeDev() {
72
81
  return [...pluginViteRPC(), ...pluginReplaceConstantsNonRunnableDev()];
73
82
  }
83
+ function skip() {
84
+ // Early resolving of user Vite configs
85
+ if (isOnlyResolvingUserConfig()) {
86
+ return true;
87
+ }
88
+ // For Vitest, we only add Vike's Vite plugin if Vike's JavaScript API is used.
89
+ // - In the context of running unit tests with Vitest, Vike's Vite plugin doesn't add any value AFAICT.
90
+ // - If the user calls Vike's JavaScript API inside Vitest (e.g. `build()` inside `beforeAll()`) => vite.config.js is loaded twice: once by Vitest and once by Vike => problematic because Vitest's environment is `development` whereas Vike's `build()` environment is `production` => the globalContext.ts isProd() function throws an assertion fail (I don't know why the two globalContext.ts instances aren't independent from each other) => that's why we skip Vike's Vite plugin when it's Vitest that loads vite.config.js
91
+ // - When calling `$ vitest` Vitest loads vite.config.js if it lives at process.cwd()
92
+ // - The user is supposed to use Vike's API instead of Vite's API. Vike supports Vite's API only for third parties (e.g. Vitest or Storybook).
93
+ // - https://vike.dev/vitest
94
+ if (
95
+ /* Maybe also all third party tools such as Storybook?
96
+ !isViteCli() &&
97
+ /*/
98
+ isVitest() &&
99
+ ///*/
100
+ !isVikeCliOrApi()) {
101
+ return true;
102
+ }
103
+ return false;
104
+ }
74
105
  // Error upon wrong usage
75
106
  Object.defineProperty(plugin, 'apply', {
76
107
  enumerable: true,
@@ -3,7 +3,7 @@ import { runPrerender_forceExit } from '../../../prerender/runPrerenderEntry.js'
3
3
  import { resolveOutDir } from '../../shared/getOutDirs.js';
4
4
  import { assert, assertWarning, getGlobalObject, onSetupBuild } from '../../utils.js';
5
5
  import { isPrerenderAutoRunEnabled, wasPrerenderRun } from '../../../prerender/context.js';
6
- import { isViteCliCall, getViteConfigFromCli } from '../../shared/isViteCliCall.js';
6
+ import { isViteCli, getViteConfigForBuildFromCli } from '../../shared/isViteCli.js';
7
7
  import pc from '@brillout/picocolors';
8
8
  import { logErrorHint } from '../../../runtime/renderPage/logErrorHint.js';
9
9
  import { getVikeConfigInternal } from '../../shared/resolveVikeConfigInternal.js';
@@ -142,7 +142,7 @@ async function triggerPrerendering(config, viteEnv, bundle) {
142
142
  }
143
143
  async function abortViteBuildSsr() {
144
144
  const vikeConfig = await getVikeConfigInternal();
145
- if (vikeConfig.config.disableAutoFullBuild !== true && isViteCliCall() && getViteConfigFromCli()?.build.ssr) {
145
+ if (vikeConfig.config.disableAutoFullBuild !== true && isViteCli() && getViteConfigForBuildFromCli()?.build.ssr) {
146
146
  assertWarning(false, `The CLI call ${pc.cyan('$ vite build --ssr')} is superfluous since ${pc.cyan('$ vite build')} also builds the server-side. If you want two separate build steps then use https://vike.dev/disableAutoFullBuild or use Vite's ${pc.cyan('build()')} API.`, { onlyOnce: true });
147
147
  process.exit(0);
148
148
  }
@@ -150,7 +150,7 @@ async function abortViteBuildSsr() {
150
150
  function isDisabled(vikeConfig) {
151
151
  const { disableAutoFullBuild } = vikeConfig.config;
152
152
  if (disableAutoFullBuild === undefined || disableAutoFullBuild === 'prerender') {
153
- const isUserUsingViteApi = !isViteCliCall() && !isVikeCliOrApi();
153
+ const isUserUsingViteApi = !isViteCli() && !isVikeCliOrApi();
154
154
  return isUserUsingViteApi;
155
155
  }
156
156
  else {
@@ -161,9 +161,9 @@ function isPrerenderForceExit() {
161
161
  return globalObject.forceExit;
162
162
  }
163
163
  function getFullBuildInlineConfig(config) {
164
- const configFromCli = !isViteCliCall() ? null : getViteConfigFromCli();
165
- if (config._viteConfigFromUserEnhanced) {
166
- return config._viteConfigFromUserEnhanced;
164
+ const configFromCli = !isViteCli() ? null : getViteConfigForBuildFromCli();
165
+ if (config._viteConfigFromUserResolved) {
166
+ return config._viteConfigFromUserResolved;
167
167
  }
168
168
  else {
169
169
  return {
@@ -7,7 +7,7 @@ declare module 'vite' {
7
7
  _isDev?: boolean;
8
8
  _rootResolvedEarly?: string;
9
9
  _baseViteOriginal?: string;
10
- _viteConfigFromUserEnhanced?: InlineConfig;
10
+ _viteConfigFromUserResolved?: InlineConfig;
11
11
  }
12
12
  }
13
13
  declare global {
@@ -1,13 +1,13 @@
1
1
  export { pluginCommon };
2
- import { assert, assertUsage, assertWarning, hasProp, isDevCheck, isDocker, isObject, isVitest } from '../utils.js';
2
+ import { assert, assertUsage, assertWarning, hasProp, isDevCheck, isDocker, isExactlyOneTruthy, isObject, isVitest, } from '../utils.js';
3
3
  import { assertRollupInput } from './build/pluginBuildConfig.js';
4
4
  import { installRequireShim_setUserRootDir } from '@brillout/require-shim';
5
5
  import pc from '@brillout/picocolors';
6
6
  import { assertResolveAlias } from './pluginCommon/assertResolveAlias.js';
7
- import { isViteCliCall } from '../shared/isViteCliCall.js';
7
+ import { isViteCli } from '../shared/isViteCli.js';
8
8
  import { isVikeCliOrApi } from '../../api/context.js';
9
9
  import { getVikeConfigInternal, setVikeConfigContext } from '../shared/resolveVikeConfigInternal.js';
10
- import { assertViteRoot, getViteRoot, normalizeViteRoot } from '../../api/prepareViteApiCall.js';
10
+ import { assertViteRoot, getViteRoot, normalizeViteRoot } from '../../api/resolveViteConfigFromUser.js';
11
11
  import { temp_disablePrerenderAutoRun } from '../../prerender/context.js';
12
12
  const pluginName = 'vike:pluginCommon';
13
13
  globalThis.__VIKE__IS_PROCESS_SHARED_WITH_VITE = true;
@@ -20,12 +20,14 @@ function pluginCommon(vikeVitePluginOptions) {
20
20
  order: 'pre',
21
21
  async handler(configFromUser, env) {
22
22
  const isDev = isDevCheck(env);
23
- const operation = env.command === 'build' ? 'build' : env.isPreview ? 'preview' : 'dev';
23
+ const isBuild = env.command === 'build';
24
+ const isPreview = env.isPreview;
25
+ assert(isExactlyOneTruthy(isDev, isBuild, isPreview));
26
+ const viteContext = isBuild ? 'build' : isPreview ? 'preview' : 'dev';
24
27
  const rootResolvedEarly = configFromUser.root
25
28
  ? normalizeViteRoot(configFromUser.root)
26
- : await getViteRoot(operation);
29
+ : await getViteRoot(viteContext);
27
30
  assert(rootResolvedEarly);
28
- // TO-DO/next-major-release: we can remove setVikeConfigContext() call here since with Vike's CLI it's already called at vike/node/api/prepareViteApiCall.ts
29
31
  setVikeConfigContext({ userRootDir: rootResolvedEarly, isDev, vikeVitePluginOptions });
30
32
  const vikeConfig = await getVikeConfigInternal();
31
33
  return {
@@ -132,7 +134,7 @@ function assertSingleInstance(config) {
132
134
  function assertVikeCliOrApi(config) {
133
135
  if (isVikeCliOrApi())
134
136
  return;
135
- if (isViteCliCall()) {
137
+ if (isViteCli()) {
136
138
  assert(!isVitest());
137
139
  return;
138
140
  }
@@ -0,0 +1,3 @@
1
+ export { pluginViteConfigVikeExtensions };
2
+ import type { Plugin } from 'vite';
3
+ declare function pluginViteConfigVikeExtensions(): Promise<Plugin[]>;
@@ -0,0 +1,32 @@
1
+ export { pluginViteConfigVikeExtensions };
2
+ import { mergeConfig } from 'vite';
3
+ import { assertUsage, isObject } from '../utils.js';
4
+ import { getVikeConfigInternalEarly } from '../../api/resolveViteConfigFromUser.js';
5
+ // Apply +vite
6
+ // - For example, Vike extensions adding Vite plugins
7
+ async function pluginViteConfigVikeExtensions() {
8
+ const vikeConfig = await getVikeConfigInternalEarly();
9
+ if (vikeConfig === null)
10
+ return [];
11
+ let viteConfigFromExtensions = {};
12
+ const viteConfigsExtensions = vikeConfig._from.configsCumulative.vite;
13
+ if (!viteConfigsExtensions)
14
+ return [];
15
+ viteConfigsExtensions.values.forEach((v) => {
16
+ assertUsage(isObject(v.value), `${v.definedAt} should be an object`);
17
+ viteConfigFromExtensions = mergeConfig(viteConfigFromExtensions, v.value);
18
+ });
19
+ const pluginsFromExtensions = (viteConfigFromExtensions.plugins ?? []);
20
+ delete viteConfigFromExtensions.plugins;
21
+ return [
22
+ ...pluginsFromExtensions,
23
+ {
24
+ name: 'vike:pluginViteConfigVikeExtensions',
25
+ config: {
26
+ handler(_config) {
27
+ return viteConfigFromExtensions;
28
+ },
29
+ },
30
+ },
31
+ ];
32
+ }
@@ -0,0 +1,13 @@
1
+ export { isViteCli };
2
+ export { getViteConfigForBuildFromCli };
3
+ export { getViteCommandFromCli };
4
+ declare function isViteCli(): boolean;
5
+ type ConfigFromCli = {
6
+ root: undefined | string;
7
+ configFile: undefined | string;
8
+ } & Record<string, unknown> & {
9
+ build: Record<string, unknown>;
10
+ };
11
+ type ViteCommand = 'dev' | 'build' | 'optimize' | 'preview';
12
+ declare function getViteCommandFromCli(): ViteCommand | null;
13
+ declare function getViteConfigForBuildFromCli(): null | ConfigFromCli;
@@ -0,0 +1,143 @@
1
+ export { isViteCli };
2
+ export { getViteConfigForBuildFromCli };
3
+ export { getViteCommandFromCli };
4
+ import { assert, isObject, toPosixPath } from '../utils.js';
5
+ import { cac } from 'cac';
6
+ const desc = 'vike:vite-cli-simulation';
7
+ function isViteCli() {
8
+ let execPath = process.argv[1];
9
+ assert(execPath);
10
+ execPath = toPosixPath(execPath);
11
+ return (
12
+ // pnpm
13
+ execPath.endsWith('/bin/vite.js') ||
14
+ // npm & yarn
15
+ execPath.endsWith('/.bin/vite') ||
16
+ // Global install
17
+ execPath.endsWith('/bin/vite'));
18
+ }
19
+ function getViteCommandFromCli() {
20
+ if (!isViteCli())
21
+ return null;
22
+ let command;
23
+ const setCommand = (cmd) => {
24
+ assert(command === undefined);
25
+ command = cmd;
26
+ };
27
+ // Copied & adapted from Vite
28
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L186-L188
29
+ const cli = cac(desc);
30
+ // dev
31
+ cli
32
+ .command('[root]', desc)
33
+ .alias('serve')
34
+ .alias('dev')
35
+ .action(() => {
36
+ setCommand('dev');
37
+ });
38
+ // build
39
+ cli.command('build [root]', desc).action(() => {
40
+ setCommand('build');
41
+ });
42
+ // optimize
43
+ cli.command('optimize [root]', desc).action(() => {
44
+ setCommand('optimize');
45
+ });
46
+ // preview
47
+ cli.command('preview [root]', desc).action(() => {
48
+ setCommand('preview');
49
+ });
50
+ cli.parse();
51
+ assert(command);
52
+ return command;
53
+ }
54
+ function getViteConfigForBuildFromCli() {
55
+ if (!isViteCli())
56
+ return null;
57
+ // Copied & adapted from Vite
58
+ const cli = cac(desc);
59
+ // Common configs
60
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L169-L182
61
+ cli
62
+ .option('-c, --config <file>', desc)
63
+ .option('--base <path>', desc)
64
+ .option('-l, --logLevel <level>', desc)
65
+ .option('--clearScreen', desc)
66
+ .option('--configLoader <loader>', desc)
67
+ .option('-d, --debug [feat]', desc)
68
+ .option('-f, --filter <filter>', desc)
69
+ .option('-m, --mode <mode>', desc);
70
+ // Build configs
71
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L286-L322
72
+ cli
73
+ .command('build [root]', desc)
74
+ .option('--target <target>', desc)
75
+ .option('--outDir <dir>', desc)
76
+ .option('--assetsDir <dir>', desc)
77
+ .option('--assetsInlineLimit <number>', desc)
78
+ .option('--ssr [entry]', desc)
79
+ .option('--sourcemap', desc)
80
+ .option('--minify [minifier]', desc)
81
+ .option('--manifest [name]', desc)
82
+ .option('--ssrManifest [name]', desc)
83
+ .option('--emptyOutDir', desc)
84
+ .option('-w, --watch', desc)
85
+ .option('--app', desc)
86
+ .action((root, options) => {
87
+ assert(isObject(options));
88
+ assert(root === undefined || typeof root === 'string');
89
+ assert(options.config === undefined || typeof options.config === 'string');
90
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L331-L346
91
+ const buildOptions = cleanGlobalCLIOptions(cleanBuilderCLIOptions(options));
92
+ configFromCli = {
93
+ root,
94
+ base: options.base,
95
+ mode: options.mode,
96
+ configFile: options.config,
97
+ configLoader: options.configLoader,
98
+ logLevel: options.logLevel,
99
+ clearScreen: options.clearScreen,
100
+ build: buildOptions,
101
+ ...(options.app ? { builder: {} } : {}),
102
+ };
103
+ });
104
+ let configFromCli = null;
105
+ cli.parse();
106
+ return configFromCli;
107
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L99
108
+ function cleanGlobalCLIOptions(options) {
109
+ const ret = { ...options };
110
+ delete ret['--'];
111
+ delete ret.c;
112
+ delete ret.config;
113
+ delete ret.base;
114
+ delete ret.l;
115
+ delete ret.logLevel;
116
+ delete ret.clearScreen;
117
+ delete ret.configLoader;
118
+ delete ret.d;
119
+ delete ret.debug;
120
+ delete ret.f;
121
+ delete ret.filter;
122
+ delete ret.m;
123
+ delete ret.mode;
124
+ delete ret.force;
125
+ delete ret.w;
126
+ // convert the sourcemap option to a boolean if necessary
127
+ if ('sourcemap' in ret) {
128
+ const sourcemap = ret.sourcemap;
129
+ ret.sourcemap = sourcemap === 'true' ? true : sourcemap === 'false' ? false : ret.sourcemap;
130
+ }
131
+ if ('watch' in ret) {
132
+ const watch = ret.watch;
133
+ ret.watch = watch ? {} : undefined;
134
+ }
135
+ return ret;
136
+ }
137
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L141
138
+ function cleanBuilderCLIOptions(options) {
139
+ const ret = { ...options };
140
+ delete ret.app;
141
+ return ret;
142
+ }
143
+ }
@@ -141,6 +141,15 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
141
141
  return resolved;
142
142
  }
143
143
  assert(resolved.path);
144
+ // Built-in modules e.g. node:fs
145
+ if (resolved.path === args.path) {
146
+ const isPointerImport = false;
147
+ pointerImports[args.path] = isPointerImport;
148
+ if (debug.isActivated)
149
+ debug('onResolve() [built-in module]', { args, resolved });
150
+ assert(resolved.external);
151
+ return resolved;
152
+ }
144
153
  const importPathResolved = toPosixPath(resolved.path);
145
154
  const importPathOriginal = args.path;
146
155
  // Esbuild resolves path aliases.
@@ -185,7 +194,7 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
185
194
  // User-land config code (i.e. not runtime code) => let esbuild transpile it
186
195
  assert(!isPointerImport && !isNpmPkgImport);
187
196
  if (debug.isActivated)
188
- debug('onResolved()', { args, resolved, isPointerImport, isExternal });
197
+ debug('onResolve() [non-external]', { args, resolved, isPointerImport, isExternal });
189
198
  return resolved;
190
199
  }
191
200
  let importPathTranspiled;
@@ -217,7 +226,7 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
217
226
  }
218
227
  }
219
228
  if (debug.isActivated)
220
- debug('onResolved()', { args, resolved, importPathTranspiled, isPointerImport, isExternal });
229
+ debug('onResolve() [external]', { args, resolved, importPathTranspiled, isPointerImport, isExternal });
221
230
  assert(isExternal);
222
231
  assert(
223
232
  // Import of runtime code => handled by Vike
@@ -4,6 +4,7 @@ export { getVikeConfigInternal };
4
4
  export { getVikeConfigInternalOptional };
5
5
  export { getVikeConfigInternalSync };
6
6
  export { setVikeConfigContext };
7
+ export { isVikeConfigContextSet };
7
8
  export { reloadVikeConfig };
8
9
  export { isV1Design };
9
10
  export { getConfVal };
@@ -45,6 +46,7 @@ declare function getVikeConfigInternalSync(): VikeConfigInternal;
45
46
  declare function getVikeConfig(config: ResolvedConfig | UserConfig): VikeConfig;
46
47
  type VikeConfig = Pick<VikeConfigInternal, 'config' | 'pages' | 'prerenderContext'>;
47
48
  declare function setVikeConfigContext(vikeConfigCtx_: VikeConfigContext): void;
49
+ declare function isVikeConfigContextSet(): boolean;
48
50
  declare function getVikeConfigInternalOptional(): Promise<null | VikeConfigInternal>;
49
51
  declare function isV1Design(): boolean;
50
52
  declare function getVikeConfigFromCliOrEnv(): {
@@ -5,6 +5,7 @@ export { getVikeConfigInternal };
5
5
  export { getVikeConfigInternalOptional };
6
6
  export { getVikeConfigInternalSync };
7
7
  export { setVikeConfigContext };
8
+ export { isVikeConfigContextSet };
8
9
  export { reloadVikeConfig };
9
10
  export { isV1Design };
10
11
  export { getConfVal };
@@ -83,6 +84,9 @@ function setVikeConfigContext(vikeConfigCtx_) {
83
84
  // If the user changes Vite's `config.root` => Vite completely reloads itself => setVikeConfigContext() is called again
84
85
  globalObject.vikeConfigCtx = vikeConfigCtx_;
85
86
  }
87
+ function isVikeConfigContextSet() {
88
+ return !!globalObject.vikeConfigCtx;
89
+ }
86
90
  async function getOrResolveVikeConfig(userRootDir, isDev, vikeVitePluginOptions, doNotRestartViteOnError) {
87
91
  if (!globalObject.vikeConfigPromise) {
88
92
  resolveVikeConfigInternal_withErrorHandling(userRootDir, isDev, vikeVitePluginOptions, doNotRestartViteOnError);
@@ -20,3 +20,4 @@ export * from '../../utils/isVitest.js';
20
20
  export * from '../../utils/rollupSourceMap.js';
21
21
  export * from '../../utils/isImportPath.js';
22
22
  export * from '../../utils/virtualFileId.js';
23
+ export * from '../../utils/isExactlyOneTruthy.js';
@@ -27,3 +27,4 @@ export * from '../../utils/isVitest.js';
27
27
  export * from '../../utils/rollupSourceMap.js';
28
28
  export * from '../../utils/isImportPath.js';
29
29
  export * from '../../utils/virtualFileId.js';
30
+ export * from '../../utils/isExactlyOneTruthy.js';
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.241-commit-206146b";
1
+ export declare const PROJECT_VERSION: "0.4.241-commit-60b0676";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.241-commit-206146b';
2
+ export const PROJECT_VERSION = '0.4.241-commit-60b0676';
@@ -0,0 +1 @@
1
+ export declare function isExactlyOneTruthy(...values: unknown[]): boolean;
@@ -0,0 +1,4 @@
1
+ // Aka XOR
2
+ export function isExactlyOneTruthy(...values) {
3
+ return values.filter(Boolean).length === 1;
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.241-commit-206146b",
3
+ "version": "0.4.241-commit-60b0676",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {
@@ -1,10 +0,0 @@
1
- export { isViteCliCall };
2
- export { getViteConfigFromCli };
3
- declare function isViteCliCall(): boolean;
4
- type ConfigFromCli = {
5
- root: undefined | string;
6
- configFile: undefined | string;
7
- } & Record<string, unknown> & {
8
- build: Record<string, unknown>;
9
- };
10
- declare function getViteConfigFromCli(): null | ConfigFromCli;
@@ -1,81 +0,0 @@
1
- export { isViteCliCall };
2
- export { getViteConfigFromCli };
3
- import { assert, isObject, toPosixPath } from '../utils.js';
4
- import { cac } from 'cac';
5
- function isViteCliCall() {
6
- let execPath = process.argv[1];
7
- assert(execPath);
8
- execPath = toPosixPath(execPath);
9
- return (
10
- // pnpm
11
- execPath.endsWith('/bin/vite.js') ||
12
- // npm & yarn
13
- execPath.endsWith('/.bin/vite') ||
14
- // Global install
15
- execPath.endsWith('/bin/vite'));
16
- }
17
- function getViteConfigFromCli() {
18
- if (!isViteCliCall())
19
- return null;
20
- // Copied and adapted from https://github.com/vitejs/vite/blob/8d0a9c1ab8ddd26973509ca230b29604e872e2cd/packages/vite/src/node/cli.ts#L137-L197
21
- const cli = cac('vike:vite-simulation');
22
- const desc = 'FAKE_CLI';
23
- cli
24
- .option('-c, --config <file>', desc)
25
- .option('--base <path>', desc)
26
- .option('-l, --logLevel <level>', desc)
27
- .option('--clearScreen', desc)
28
- .option('-d, --debug [feat]', desc)
29
- .option('-f, --filter <filter>', desc)
30
- .option('-m, --mode <mode>', desc);
31
- cli
32
- .command('build [root]', desc)
33
- .option('--target <target>', desc)
34
- .option('--outDir <dir>', desc)
35
- .option('--assetsDir <dir>', desc)
36
- .option('--assetsInlineLimit <number>', desc)
37
- .option('--ssr [entry]', desc)
38
- .option('--sourcemap', desc)
39
- .option('--minify [minifier]', desc)
40
- .option('--manifest [name]', desc)
41
- .option('--ssrManifest [name]', desc)
42
- .option('--force', desc)
43
- .option('--emptyOutDir', desc)
44
- .option('-w, --watch', desc)
45
- .action((root, options) => {
46
- assert(isObject(options));
47
- const buildOptions = cleanOptions(options);
48
- assert(root === undefined || typeof root === 'string');
49
- assert(options.config === undefined || typeof options.config === 'string');
50
- configFromCli = {
51
- root,
52
- base: options.base,
53
- mode: options.mode,
54
- configFile: options.config,
55
- logLevel: options.logLevel,
56
- clearScreen: options.clearScreen,
57
- optimizeDeps: { force: options.force },
58
- build: buildOptions,
59
- };
60
- });
61
- let configFromCli = null;
62
- cli.parse();
63
- return configFromCli;
64
- function cleanOptions(options) {
65
- const ret = { ...options };
66
- delete ret['--'];
67
- delete ret.c;
68
- delete ret.config;
69
- delete ret.base;
70
- delete ret.l;
71
- delete ret.logLevel;
72
- delete ret.clearScreen;
73
- delete ret.d;
74
- delete ret.debug;
75
- delete ret.f;
76
- delete ret.filter;
77
- delete ret.m;
78
- delete ret.mode;
79
- return ret;
80
- }
81
- }