vike 0.4.249 → 0.4.250-commit-193dea3

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 (77) hide show
  1. package/bin.js +3 -0
  2. package/dist/client/runtime-client-routing/createPageContextClientSide.d.ts +1 -1
  3. package/dist/client/runtime-client-routing/getPageContext.js +0 -2
  4. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +136 -4
  5. package/dist/client/runtime-client-routing/history.d.ts +1 -1
  6. package/dist/client/runtime-client-routing/history.js +4 -11
  7. package/dist/client/runtime-client-routing/prefetch.d.ts +2 -2
  8. package/dist/client/runtime-client-routing/renderPageClient.d.ts +601 -6
  9. package/dist/client/runtime-client-routing/utils.d.ts +0 -1
  10. package/dist/client/runtime-client-routing/utils.js +0 -1
  11. package/dist/client/runtime-server-routing/createPageContextClientSide.d.ts +2 -6
  12. package/dist/client/runtime-server-routing/createPageContextClientSide.js +1 -21
  13. package/dist/client/runtime-server-routing/entry.js +15 -1
  14. package/dist/client/shared/execHookOnRenderClient.d.ts +4 -1
  15. package/dist/node/vite/index.js +5 -2
  16. package/dist/node/vite/plugins/non-runnable-dev/pluginReplaceConstantsNonRunnableDev.js +38 -13
  17. package/dist/node/vite/plugins/pluginAssertFileEnv.js +22 -13
  18. package/dist/node/vite/plugins/pluginExtractAssets.js +2 -0
  19. package/dist/node/vite/plugins/pluginExtractExportNames.js +2 -0
  20. package/dist/node/vite/plugins/pluginReplaceConstantsEnvVars.js +2 -0
  21. package/dist/node/vite/plugins/pluginReplaceConstantsGlobalThis.js +3 -1
  22. package/dist/node/vite/plugins/pluginReplaceConstantsPageContext.js +2 -0
  23. package/dist/node/vite/plugins/pluginStaticReplace/applyStaticReplace.d.ts +126 -0
  24. package/dist/node/vite/plugins/pluginStaticReplace/applyStaticReplace.js +421 -0
  25. package/dist/node/vite/plugins/pluginStaticReplace.d.ts +4 -0
  26. package/dist/node/vite/plugins/pluginStaticReplace.js +88 -0
  27. package/dist/node/vite/plugins/pluginVirtualFiles.js +73 -113
  28. package/dist/node/vite/plugins/pluginViteConfigVikeExtensions.d.ts +2 -1
  29. package/dist/node/vite/plugins/pluginViteConfigVikeExtensions.js +1 -3
  30. package/dist/node/vite/shared/importString.d.ts +50 -0
  31. package/dist/node/vite/shared/importString.js +63 -0
  32. package/dist/node/vite/shared/loggerDev.d.ts +3 -3
  33. package/dist/node/vite/shared/loggerDev.js +3 -3
  34. package/dist/node/vite/shared/resolveVikeConfigInternal/assertExtensions.d.ts +1 -1
  35. package/dist/node/vite/shared/resolveVikeConfigInternal/configDefinitionsBuiltIn.js +10 -1
  36. package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles.d.ts → crawlPlusFilePaths.d.ts} +2 -2
  37. package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles.js → crawlPlusFilePaths.js} +4 -4
  38. package/dist/node/vite/shared/resolveVikeConfigInternal/{getPlusFilesAll.d.ts → getPlusFilesByLocationId.d.ts} +8 -6
  39. package/dist/node/vite/shared/resolveVikeConfigInternal/{getPlusFilesAll.js → getPlusFilesByLocationId.js} +47 -59
  40. package/dist/node/vite/shared/resolveVikeConfigInternal/loadFileAtConfigTime.d.ts +1 -1
  41. package/dist/node/vite/shared/resolveVikeConfigInternal/pointerImports.js +11 -18
  42. package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +1 -1
  43. package/dist/node/vite/shared/resolveVikeConfigInternal.js +66 -64
  44. package/dist/server/onLoad.js +2 -2
  45. package/dist/server/runtime/logErrorServer.d.ts +2 -2
  46. package/dist/server/runtime/logErrorServer.js +0 -2
  47. package/dist/server/runtime/loggerRuntime.d.ts +3 -2
  48. package/dist/server/runtime/renderPageServer/createHttpResponse.d.ts +4 -2
  49. package/dist/server/runtime/renderPageServer/createHttpResponse.js +16 -8
  50. package/dist/server/runtime/renderPageServer/createPageContextServerSide.d.ts +5 -2
  51. package/dist/server/runtime/renderPageServer/createPageContextServerSide.js +1 -0
  52. package/dist/server/runtime/renderPageServer/csp.js +2 -0
  53. package/dist/server/runtime/renderPageServer/execHookOnError.d.ts +2 -2
  54. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.d.ts +4 -4
  55. package/dist/server/runtime/renderPageServer/handleErrorWithoutErrorPage.js +3 -4
  56. package/dist/server/runtime/renderPageServer/html/serializeContext.d.ts +2 -2
  57. package/dist/server/runtime/renderPageServer/html/stream.js +12 -13
  58. package/dist/server/runtime/renderPageServer/loadPageConfigsLazyServerSide.d.ts +2 -2
  59. package/dist/server/runtime/renderPageServer/log404/index.d.ts +2 -2
  60. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.d.ts +3 -3
  61. package/dist/server/runtime/renderPageServer/renderPageServerAfterRoute.js +2 -2
  62. package/dist/server/runtime/renderPageServer.js +19 -19
  63. package/dist/shared-server-client/hooks/execHook.d.ts +5 -1
  64. package/dist/types/Config/ConfigResolved.d.ts +3 -2
  65. package/dist/types/Config.d.ts +38 -31
  66. package/dist/types/PageConfig.d.ts +1 -1
  67. package/dist/types/index.d.ts +2 -1
  68. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  69. package/dist/utils/PROJECT_VERSION.js +1 -1
  70. package/dist/utils/assert.d.ts +5 -5
  71. package/dist/utils/assert.js +8 -8
  72. package/dist/utils/debug.d.ts +1 -1
  73. package/dist/utils/debug.js +1 -0
  74. package/package.json +9 -7
  75. package/node/cli/bin.js +0 -3
  76. /package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles → crawlPlusFilePaths}/ignorePatternsBuiltIn.d.ts +0 -0
  77. /package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles → crawlPlusFilePaths}/ignorePatternsBuiltIn.js +0 -0
@@ -9,15 +9,17 @@ import pc from '@brillout/picocolors';
9
9
  import { logConfigInfo } from '../shared/loggerDev.js';
10
10
  import { getFilePathToShowToUserModule } from '../shared/getFilePath.js';
11
11
  import { updateUserFiles } from '../../../server/runtime/globalContext.js';
12
- import { isPlusFile } from '../shared/resolveVikeConfigInternal/crawlPlusFiles.js';
12
+ import { isPlusFile } from '../shared/resolveVikeConfigInternal/crawlPlusFilePaths.js';
13
13
  import { isTemporaryBuildFile } from '../shared/resolveVikeConfigInternal/transpileAndExecuteFile.js';
14
14
  import { debugFileChange, getVikeConfigError } from '../../../shared-server-node/getVikeConfigError.js';
15
+ // === Rolldown filter
15
16
  const filterRolldown = {
16
17
  id: {
17
18
  include: new RegExp(`^(${escapeRegex(virtualFileIdPrefix1)}|${escapeRegex(virtualFileIdPrefix2)})`),
18
19
  },
19
20
  };
20
21
  const filterFunction = (id) => isVirtualFileId(id);
22
+ // ===
21
23
  function pluginVirtualFiles() {
22
24
  let config;
23
25
  return [
@@ -38,11 +40,12 @@ function pluginVirtualFiles() {
38
40
  return addVirtualFileIdPrefix(id);
39
41
  },
40
42
  },
43
+ // Vite calls handleHotUpdate() whenever *any file* is modified — including files that aren't in Vite's module graph such as +config.js
41
44
  handleHotUpdate: {
42
45
  async handler(ctx) {
43
46
  debugFileChange('handleHotUpdate()', ctx.file);
44
47
  try {
45
- return await handleHotUpdate(ctx, config);
48
+ return await onFileModified(ctx, config);
46
49
  }
47
50
  catch (err) {
48
51
  // Vite swallows errors thrown by handleHotUpdate()
@@ -73,106 +76,89 @@ function pluginVirtualFiles() {
73
76
  },
74
77
  configureServer: {
75
78
  handler(server) {
76
- handleFileAddRemove(server, config);
79
+ server.watcher.prependListener('add', (file) => onFileCreatedOrRemoved(file, false, server, config));
80
+ server.watcher.prependListener('unlink', (file) => onFileCreatedOrRemoved(file, true, server, config));
77
81
  },
78
82
  },
79
83
  },
80
84
  ];
81
85
  }
82
- function handleFileAddRemove(server, config) {
83
- server.watcher.prependListener('add', (f) => listener(f, false));
84
- server.watcher.prependListener('unlink', (f) => listener(f, true));
85
- return;
86
- async function listener(file, isRemove) {
87
- file = normalizePath(file);
88
- if (isTemporaryBuildFile(file))
89
- return;
90
- const operation = isRemove ? 'removed' : 'created';
91
- debugFileChange('server.watcher', file, operation);
92
- const { moduleGraph } = server;
93
- const isVikeConfigDep = await isVikeConfigDependency(file, moduleGraph);
94
- const reload = () => reloadConfig(file, config, operation, server);
95
- // Config code
96
- if (isVikeConfigDep && !isVikeConfigDep.isProcessedByVite) {
97
- reload();
98
- return;
99
- }
100
- // New or deleted + file
101
- if (isPlusFile(file)) {
102
- reload();
103
- return;
104
- }
105
- // Runtime code => let Vite handle it
106
- if (isVikeConfigDep && isVikeConfigDep.isProcessedByVite) {
107
- assert(existsInViteModuleGraph(file, moduleGraph));
108
- return;
109
- }
110
- // Trick: when importing a file that doesn't exist => we don't know whether `file` is that missing file => we take a leap of faith when the conditions below are met.
86
+ async function onFileModified(ctx, config) {
87
+ const { file, server } = ctx;
88
+ const isAppFile = await isAppDependency(ctx.file, ctx.server.moduleGraph);
89
+ debugFileChange(isAppFile);
90
+ if (!isAppFile)
91
+ return;
92
+ const reloadVikeConfig = () => reloadConfig(file, config, 'modified', server);
93
+ if (isAppFile.isRuntimeDependency) {
94
+ // Ensure we invalidate `file` *before* server.ssrLoadModule() in updateUserFiles()
95
+ // Vite also invalidates it, but *after* handleHotUpdate() and thus after server.ssrLoadModule()
96
+ ctx.modules.forEach((mod) => server.moduleGraph.invalidateModule(mod));
97
+ // Re-running ssrLoadModule() is cheap (Vite uses a cache) => eagerly calling updateUserFiles() makes sense.
98
+ // - Even for SPA apps that don't have (m)any server files? Ideally, we should set `isRuntimeDependency: true` only for server modules (let's do it once Vite has a clear separate per-environment module graphs).
99
+ await updateUserFiles();
100
+ }
101
+ if (isAppFile.isConfigDependency) {
102
+ /* Tailwind breaks this assertion, see https://github.com/vikejs/vike/discussions/1330#discussioncomment-7787238
103
+ const isViteModule = ctx.modules.length > 0
104
+ assert(!isViteModule)
105
+ */
106
+ reloadVikeConfig();
107
+ // Trigger a full page reload. (Because files such as +config.js can potentially modify Vike's virtual files.)
108
+ const vikeVirtualFiles = getVikeVirtualFiles(server);
109
+ return vikeVirtualFiles;
110
+ }
111
+ }
112
+ async function onFileCreatedOrRemoved(file, isRemove, server, config) {
113
+ file = normalizePath(file);
114
+ if (isTemporaryBuildFile(file))
115
+ return;
116
+ const operation = isRemove ? 'removed' : 'created';
117
+ debugFileChange('server.watcher', file, operation);
118
+ const { moduleGraph } = server;
119
+ const isAppFile = await isAppDependency(file, moduleGraph);
120
+ const reloadVikeConfig = () => reloadConfig(file, config, operation, server);
121
+ if (
122
+ // Vike config (non-runtime) code
123
+ isAppFile?.isConfigDependency ||
124
+ // New + file => not tracked yet by Vike (`vikeConfigObject._vikeConfigDependencies`) nor Vite (`moduleGraph`)
125
+ isPlusFile(file) ||
126
+ // Trick: when fixing the path of a relative import => we don't know whether `file` is the imported file => we take a leap of faith when the conditions below are met.
127
+ // - Reloading Vike's config is cheap => eagerly reloading it makes sense when it's in an erroneous state.
111
128
  // - Not sure how reliable that trick is.
112
- // - Reloading Vike's config is cheap and file creation/removal is rare => the trick is worth it.
113
129
  // - Reproduction:
114
130
  // ```bash
115
- // rm someDep.js && sleep 2 && git checkout someDep.js
131
+ // rm someImportedFile.js && sleep 2 && git checkout someImportedFile.js
116
132
  // ```
117
- if (isScriptFile(file) && getVikeConfigError() && !existsInViteModuleGraph(file, moduleGraph)) {
118
- reload();
119
- return;
120
- }
133
+ (isScriptFile(file) && getVikeConfigError())) {
134
+ reloadVikeConfig();
121
135
  }
122
136
  }
123
- function invalidateVikeVirtualFiles(server) {
124
- const vikeVirtualFiles = getVikeVirtualFiles(server);
125
- vikeVirtualFiles.forEach((mod) => {
126
- server.moduleGraph.invalidateModule(mod);
127
- });
128
- }
129
- // Vite calls its hook handleHotUpdate() whenever *any file* is modified — including files that aren't in Vite's module graph such as `pages/+config.js`
130
- async function handleHotUpdate(ctx, config) {
131
- const { file, server } = ctx;
132
- const isVikeConfigDep = await isVikeConfigDependency(ctx.file, ctx.server.moduleGraph);
133
- debugFileChange(isVikeConfigDep);
134
- if (isVikeConfigDep) {
135
- if (!isVikeConfigDep.isProcessedByVite) {
136
- /* Tailwind breaks this assertion, see https://github.com/vikejs/vike/discussions/1330#discussioncomment-7787238
137
- const isViteModule = ctx.modules.length > 0
138
- assert(!isViteModule)
139
- */
140
- reloadConfig(file, config, 'modified', server);
141
- // Files such as `pages/+config.js` can potentially modify Vike's virtual files.
142
- // Triggers a full page reload
143
- const vikeVirtualFiles = getVikeVirtualFiles(server);
144
- return vikeVirtualFiles;
145
- }
146
- else {
147
- // Ensure we invalidate `file` *before* server.ssrLoadModule() in updateUserFiles()
148
- // Vite also invalidates it, but *after* handleHotUpdate() and thus after server.ssrLoadModule()
149
- ctx.modules.forEach((mod) => server.moduleGraph.invalidateModule(mod));
150
- await updateUserFiles();
151
- }
152
- }
153
- }
154
- async function isVikeConfigDependency(filePathAbsoluteFilesystem, moduleGraph) {
155
- // Non-runtime Vike config files such as `pages/+config.js` which aren't processed by Vite.
137
+ async function isAppDependency(filePathAbsoluteFilesystem, moduleGraph) {
138
+ const isAppFile = {};
139
+ // =============================
140
+ // { isConfigDependency: false }
141
+ // =============================
142
+ // Vike config (non-runtime) files such as +config.js which aren't processed by Vite.
156
143
  // - They're missing in Vite's module graph.
157
144
  // - Potentially modifies Vike's virtual files.
158
- // - Same for all `pages/+config.js` dependencies.
145
+ // - Same for all `pages/+config.js` transitive dependencies.
159
146
  assertPosixPath(filePathAbsoluteFilesystem);
160
147
  const vikeConfigObject = await getVikeConfigInternalOptional();
161
148
  if (vikeConfigObject) {
162
149
  const { _vikeConfigDependencies: vikeConfigDependencies } = vikeConfigObject;
163
150
  vikeConfigDependencies.forEach((f) => assertPosixPath(f));
164
- if (vikeConfigDependencies.has(filePathAbsoluteFilesystem))
165
- return { isProcessedByVite: false };
151
+ isAppFile.isConfigDependency = vikeConfigDependencies.has(filePathAbsoluteFilesystem);
166
152
  }
167
- // Runtime Vike config files such as +data.js which are processed by Vite.
153
+ // =============================
154
+ // { isRuntimeDependency: true }
155
+ // =============================
156
+ // Vike runtime files such as +data.js which are processed by Vite.
168
157
  // - They're included in Vite's module graph.
169
158
  // - They never modify Vike's virtual files.
170
- // - Same for all `+data.js` dependencies.
171
- const importers = getImporters(filePathAbsoluteFilesystem, moduleGraph);
172
- const isPlusValueFileDependency = Array.from(importers).some((importer) => importer.file && isPlusFile(importer.file));
173
- if (isPlusValueFileDependency)
174
- return { isProcessedByVite: true };
175
- return null;
159
+ // - Same for all `+data.js` transitive dependencies.
160
+ isAppFile.isRuntimeDependency = existsInViteModuleGraph(filePathAbsoluteFilesystem, moduleGraph);
161
+ return isAppFile;
176
162
  }
177
163
  function reloadConfig(filePath, config, operation, server) {
178
164
  // Ensure server.ssrLoadModule() loads fresh Vike virtual files (`reloadConfig()` > `updateUserFiles()` > `server.ssrLoadModule()`)
@@ -185,6 +171,12 @@ function reloadConfig(filePath, config, operation, server) {
185
171
  reloadVikeConfig();
186
172
  updateUserFiles();
187
173
  }
174
+ function invalidateVikeVirtualFiles(server) {
175
+ const vikeVirtualFiles = getVikeVirtualFiles(server);
176
+ vikeVirtualFiles.forEach((mod) => {
177
+ server.moduleGraph.invalidateModule(mod);
178
+ });
179
+ }
188
180
  function getVikeVirtualFiles(server) {
189
181
  const vikeVirtualFiles = Array.from(server.moduleGraph.urlToModuleMap.keys())
190
182
  .filter((url) => parseVirtualFileId(url))
@@ -195,38 +187,6 @@ function getVikeVirtualFiles(server) {
195
187
  });
196
188
  return vikeVirtualFiles;
197
189
  }
198
- // Get all transitive importers (including the module itself)
199
- function getImporters(file, moduleGraph) {
200
- const importers = new Set();
201
- const mods = moduleGraph.getModulesByFile(file);
202
- if (!mods)
203
- return importers;
204
- for (const mod of mods) {
205
- getModuleImporters(mod).forEach((importer) => {
206
- if (importer)
207
- importers.add(importer);
208
- });
209
- }
210
- return importers;
211
- }
212
- function getModuleImporters(mod, seen = new Set()) {
213
- if (seen.has(mod))
214
- return new Set();
215
- seen.add(mod);
216
- const importers = new Set();
217
- if (mod.id)
218
- importers.add(mod);
219
- // Traverse through the importers (modules that import this module)
220
- for (const importer of mod.importers) {
221
- if (importer.id)
222
- importers.add(importer);
223
- getModuleImporters(importer, seen).forEach((importerTransitive) => {
224
- if (importerTransitive)
225
- importers.add(importerTransitive);
226
- });
227
- }
228
- return importers;
229
- }
230
190
  function existsInViteModuleGraph(file, moduleGraph) {
231
191
  return !!moduleGraph.getModulesByFile(file);
232
192
  }
@@ -1,3 +1,4 @@
1
1
  export { pluginViteConfigVikeExtensions };
2
2
  import type { Plugin } from 'vite';
3
- declare function pluginViteConfigVikeExtensions(): Promise<Plugin[]>;
3
+ import type { VikeConfigInternal } from '../shared/resolveVikeConfigInternal.js';
4
+ declare function pluginViteConfigVikeExtensions(vikeConfig: VikeConfigInternal): Promise<Plugin[]>;
@@ -1,11 +1,9 @@
1
1
  export { pluginViteConfigVikeExtensions };
2
2
  import { mergeConfig } from 'vite';
3
3
  import { assertUsage, isCallable, isObject } from '../utils.js';
4
- import { getVikeConfigInternalEarly } from '../../api/resolveViteConfigFromUser.js';
5
4
  // Apply +vite
6
5
  // - For example, Vike extensions adding Vite plugins
7
- async function pluginViteConfigVikeExtensions() {
8
- const vikeConfig = await getVikeConfigInternalEarly();
6
+ async function pluginViteConfigVikeExtensions(vikeConfig) {
9
7
  if (vikeConfig === null)
10
8
  return [];
11
9
  let viteConfigFromExtensions = {};
@@ -0,0 +1,50 @@
1
+ export { parseImportString };
2
+ export { isImportString };
3
+ export { serializeImportString };
4
+ export type { ImportString };
5
+ export type { ImportStringList };
6
+ export type { ImportStringParsed };
7
+ /** `import:${importPath}:${exportName}`
8
+ * @example import:./Layout:default
9
+ */
10
+ type ImportString = `import:${string}:${string}`;
11
+ type ImportStringList = ImportString | ImportString[];
12
+ type ImportStringParsed = {
13
+ importPath: string;
14
+ exportName: string;
15
+ };
16
+ /**
17
+ * Parse import string in format: import:importPath:exportName
18
+ *
19
+ * @example parseImportString('import:react/jsx-runtime:jsx')
20
+ * // => { importPath: 'react/jsx-runtime', exportName: 'jsx' }
21
+ *
22
+ * @example parseImportString('import:./Layout:default')
23
+ * // => { importPath: './Layout', exportName: 'default' }
24
+ *
25
+ * @example parseImportString('import:./Layout', { legacy: true })
26
+ * // => { importPath: './Layout', exportName: 'default' }
27
+ */
28
+ declare function parseImportString(importString: string, { legacy }?: {
29
+ legacy?: boolean;
30
+ }): null | ImportStringParsed;
31
+ /**
32
+ * Check if a string is an import string (starts with 'import:').
33
+ *
34
+ * @example isImportString('import:react:jsx')
35
+ * // => true
36
+ *
37
+ * @example isImportString('some-other-string')
38
+ * // => false
39
+ */
40
+ declare function isImportString(str: string): str is ImportString;
41
+ /**
42
+ * Serialize import string from importPath and export name.
43
+ *
44
+ * @example serializeImportString({ importPath: 'react/jsx-runtime', exportName: 'jsx' })
45
+ * // => 'import:react/jsx-runtime:jsx'
46
+ *
47
+ * @example serializeImportString({ importPath: './Layout', exportName: 'default' })
48
+ * // => 'import:./Layout:default'
49
+ */
50
+ declare function serializeImportString({ importPath, exportName }: ImportStringParsed): `import:${string}:${string}`;
@@ -0,0 +1,63 @@
1
+ export { parseImportString };
2
+ export { isImportString };
3
+ export { serializeImportString };
4
+ import pc from '@brillout/picocolors';
5
+ import { assert, assertWarning } from '../utils.js';
6
+ const IMPORT = 'import';
7
+ const SEP = ':';
8
+ /**
9
+ * Parse import string in format: import:importPath:exportName
10
+ *
11
+ * @example parseImportString('import:react/jsx-runtime:jsx')
12
+ * // => { importPath: 'react/jsx-runtime', exportName: 'jsx' }
13
+ *
14
+ * @example parseImportString('import:./Layout:default')
15
+ * // => { importPath: './Layout', exportName: 'default' }
16
+ *
17
+ * @example parseImportString('import:./Layout', { legacy: true })
18
+ * // => { importPath: './Layout', exportName: 'default' }
19
+ */
20
+ function parseImportString(importString, { legacy = false } = {}) {
21
+ if (!importString.startsWith(`${IMPORT}${SEP}`))
22
+ return null;
23
+ const parts = importString.split(SEP);
24
+ assert(parts[0] === IMPORT);
25
+ if (legacy && parts.length === 2) {
26
+ assertWarning(false, `Replace ${pc.cyan(importString)} with ${pc.cyan(importString)}${pc.cyan(':default')} (import strings must include the export name)`, { onlyOnce: true });
27
+ const exportName = 'default';
28
+ const importPath = parts[1];
29
+ assert(importPath);
30
+ return { importPath, exportName };
31
+ }
32
+ assert(parts.length >= 3);
33
+ const exportName = parts[parts.length - 1];
34
+ const importPath = parts.slice(1, -1).join(SEP);
35
+ assert(exportName);
36
+ assert(importPath);
37
+ return { importPath, exportName };
38
+ }
39
+ /**
40
+ * Check if a string is an import string (starts with 'import:').
41
+ *
42
+ * @example isImportString('import:react:jsx')
43
+ * // => true
44
+ *
45
+ * @example isImportString('some-other-string')
46
+ * // => false
47
+ */
48
+ function isImportString(str) {
49
+ return !!parseImportString(str, { legacy: true });
50
+ }
51
+ /**
52
+ * Serialize import string from importPath and export name.
53
+ *
54
+ * @example serializeImportString({ importPath: 'react/jsx-runtime', exportName: 'jsx' })
55
+ * // => 'import:react/jsx-runtime:jsx'
56
+ *
57
+ * @example serializeImportString({ importPath: './Layout', exportName: 'default' })
58
+ * // => 'import:./Layout:default'
59
+ */
60
+ function serializeImportString({ importPath, exportName }) {
61
+ const importString = `${IMPORT}${SEP}${importPath}${SEP}${exportName}`;
62
+ return importString;
63
+ }
@@ -2,11 +2,11 @@ export { logVite };
2
2
  export { logConfigInfo };
3
3
  export { logErrorServerDev };
4
4
  export type { LogType };
5
- export type { AddTagsDev };
5
+ export type { AddAssertTagsDev };
6
6
  import { type PageContext_logRuntime } from '../../../server/runtime/loggerRuntime.js';
7
7
  type LogType = 'info' | 'warn' | 'error' | 'error-resolve';
8
8
  declare function logConfigInfo(msg: string, logType: LogType): void;
9
9
  declare function logVite(msg: string, logType: LogType, requestId: number | null, prependViteTag: boolean): void;
10
10
  declare function logErrorServerDev(err: unknown, pageContext: PageContext_logRuntime, errorComesFromVite?: boolean): void;
11
- type AddTagsDev = typeof addTagsDev;
12
- declare function addTagsDev<TagVike extends string, TagType extends string>(tagVike: TagVike, tagType: TagType): `1:37:00 PM ${TagVike}[request(n)]${TagType}`;
11
+ type AddAssertTagsDev = typeof addAssertTagsDev;
12
+ declare function addAssertTagsDev<TagVike extends string, TagType extends string>(tagVike: TagVike, tagType: TagType): `1:37:00 PM ${TagVike}[request(n)]${TagType}`;
@@ -12,7 +12,7 @@ export { logErrorServerDev };
12
12
  import { isAbortError } from '../../../shared-server-client/route/abort.js';
13
13
  import { getViteConfig } from '../../../server/runtime/globalContext.js';
14
14
  import { assertPageContext_logRuntime, setLogRuntimeDev, } from '../../../server/runtime/loggerRuntime.js';
15
- import { setAssertOnBeforeErr, assert, assertIsNotProductionRuntime, colorVike, colorVite, formatHintLog, hasGreen, hasProp, hasRed, hasYellow, isDebugError, stripAnsi, colorError, colorWarning, setAssertAddTagsDev, } from '../utils.js';
15
+ import { setAssertOnBeforeErr, assert, assertIsNotProductionRuntime, colorVike, colorVite, formatHintLog, hasGreen, hasProp, hasRed, hasYellow, isDebugError, stripAnsi, colorError, colorWarning, setAssertAddAssertTagsDev, } from '../utils.js';
16
16
  import { isErrorWithCodeSnippet, getPrettyErrorWithCodeSnippet } from './loggerDev/errorWithCodeSnippet.js';
17
17
  import { getConfigExecutionErrorIntroMsg, getConfigBuildErrorFormatted, } from './resolveVikeConfigInternal/transpileAndExecuteFile.js';
18
18
  import pc from '@brillout/picocolors';
@@ -27,7 +27,7 @@ setAssertOnBeforeErr((err) => {
27
27
  // We must directly apply vite.ssrFixStacktrace() to `assertWarning(..., { showStackTrace: true })` because warnings aren't caught by the try-catch of renderPageServer()
28
28
  applyViteSourceMap(err);
29
29
  });
30
- setAssertAddTagsDev(addTagsDev);
30
+ setAssertAddAssertTagsDev(addAssertTagsDev);
31
31
  // Note shown to user when Vike completely modifies the error message (which is somewhat risky)
32
32
  const errorDebugNote = pc.dim(formatHintLog("Error isn't helpful? See https://vike.dev/debug#verbose-errors"));
33
33
  function logRuntimeInfoDev(msg, pageContext, logType) {
@@ -186,7 +186,7 @@ function getTagSourceOuter(tagSource) {
186
186
  const tagSourceOuter = (!tagSource ? '' : pc.dim(`[${tagSource}]`));
187
187
  return tagSourceOuter;
188
188
  }
189
- function addTagsDev(tagVike, tagType) {
189
+ function addAssertTagsDev(tagVike, tagType) {
190
190
  const timestamp = getTagTimestamp();
191
191
  const tagSource = getTagSource();
192
192
  const tagSourceOuter = getTagSourceOuter(tagSource);
@@ -1,5 +1,5 @@
1
1
  export { assertExtensionsConventions };
2
2
  export { assertExtensionsRequire };
3
- import type { PlusFile } from './getPlusFilesAll.js';
3
+ import type { PlusFile } from './getPlusFilesByLocationId.js';
4
4
  declare function assertExtensionsConventions(plusFile: PlusFile): void;
5
5
  declare function assertExtensionsRequire(plusFiles: PlusFile[]): void;
@@ -2,6 +2,7 @@ export { configDefinitionsBuiltIn };
2
2
  import { assert, assertUsage } from '../../utils.js';
3
3
  import { getConfigDefinedAt, } from '../../../../shared-server-client/page-configs/getConfigDefinedAt.js';
4
4
  import { getConfigValueSourceRelevantAnyEnv, getConfigValueSourcesRelevant, isConfigSourceValueNull, } from '../../plugins/pluginVirtualFiles/getConfigValueSourcesRelevant.js';
5
+ import { getFileSuffixes } from '../../../../shared-server-node/getFileSuffixes.js';
5
6
  const configDefinitionsBuiltIn = {
6
7
  onRenderHtml: {
7
8
  env: { server: true },
@@ -117,7 +118,7 @@ const configDefinitionsBuiltIn = {
117
118
  // Exclude `.ssr.js` hooks (they don't require pageContext.json requests)
118
119
  .filter((source) => {
119
120
  const { definedAt } = source;
120
- if ('filePathAbsoluteVite' in definedAt && definedAt.filePathAbsoluteVite.includes('.ssr.')) {
121
+ if ('fileName' in definedAt && getFileSuffixes(definedAt.fileName).includes('ssr')) {
121
122
  return false;
122
123
  }
123
124
  return true;
@@ -270,6 +271,14 @@ const configDefinitionsBuiltIn = {
270
271
  env: { server: true },
271
272
  cumulative: true,
272
273
  },
274
+ staticReplace: {
275
+ env: { config: true },
276
+ cumulative: true,
277
+ global: true,
278
+ /* TODO
279
+ vite: true,
280
+ */
281
+ },
273
282
  };
274
283
  function getConfigEnv(pageConfig, configName) {
275
284
  const source = getConfigValueSourceRelevantAnyEnv(configName, pageConfig);
@@ -1,7 +1,7 @@
1
- export { crawlPlusFiles };
1
+ export { crawlPlusFilePaths };
2
2
  export { isPlusFile };
3
3
  export { getPlusFileValueConfigName };
4
- declare function crawlPlusFiles(userRootDir: string): Promise<{
4
+ declare function crawlPlusFilePaths(userRootDir: string): Promise<{
5
5
  filePathAbsoluteUserRootDir: string;
6
6
  }[]>;
7
7
  declare function isPlusFile(filePath: string): boolean;
@@ -1,4 +1,4 @@
1
- export { crawlPlusFiles };
1
+ export { crawlPlusFilePaths };
2
2
  export { isPlusFile };
3
3
  export { getPlusFileValueConfigName };
4
4
  import { assertPosixPath, assert, scriptFileExtensionPattern, assertIsNotProductionRuntime, isVersionMatch, isScriptFile, scriptFileExtensionList, createDebug, deepEqual, assertUsage, assertFilePathAbsoluteFilesystem, assertWarning, hasProp, isNotNullish, getGlobalObject, } from '../../utils.js';
@@ -10,14 +10,14 @@ import { isTemporaryBuildFile } from './transpileAndExecuteFile.js';
10
10
  import { getEnvVarObject } from '../getEnvVarObject.js';
11
11
  import pc from '@brillout/picocolors';
12
12
  import picomatch from 'picomatch';
13
- import { ignorePatternsBuiltIn } from './crawlPlusFiles/ignorePatternsBuiltIn.js';
13
+ import { ignorePatternsBuiltIn } from './crawlPlusFilePaths/ignorePatternsBuiltIn.js';
14
14
  const execA = promisify(exec);
15
15
  const debug = createDebug('vike:crawl');
16
16
  assertIsNotProductionRuntime();
17
- const globalObject = getGlobalObject('getVikeConfig/crawlPlusFiles.ts', {
17
+ const globalObject = getGlobalObject('getVikeConfig/crawlPlusFilePaths.ts', {
18
18
  gitIsNotUsable: false,
19
19
  });
20
- async function crawlPlusFiles(userRootDir) {
20
+ async function crawlPlusFilePaths(userRootDir) {
21
21
  assertPosixPath(userRootDir);
22
22
  assertFilePathAbsoluteFilesystem(userRootDir);
23
23
  const userSettings = getUserSettings();
@@ -1,4 +1,4 @@
1
- export { getPlusFilesAll };
1
+ export { getPlusFilesByLocationId };
2
2
  export type { PlusFileValue };
3
3
  export type { PlusFile };
4
4
  export type { PlusFilesByLocationId };
@@ -7,21 +7,23 @@ import { type EsbuildCache } from './transpileAndExecuteFile.js';
7
7
  import { PointerImportLoaded } from './loadFileAtConfigTime.js';
8
8
  import type { FilePathResolved } from '../../../../types/FilePath.js';
9
9
  type PlusFile = PlusFileConfig | PlusFileValue;
10
- type PlusFileCommons = {
10
+ type PlusFileCommon = {
11
11
  locationId: LocationId;
12
12
  filePath: FilePathResolved;
13
13
  };
14
- type PlusFileConfig = PlusFileCommons & {
14
+ /** +config.js */
15
+ type PlusFileConfig = PlusFileCommon & {
15
16
  isConfigFile: true;
16
17
  fileExportsByConfigName: Record<string, // configName
17
18
  unknown>;
18
19
  pointerImportsByConfigName: Record<string, // configName
19
- PointerImportLoaded>;
20
+ PointerImportLoaded[]>;
20
21
  isExtensionConfig: boolean;
21
22
  extendsFilePaths: string[];
22
23
  isNotLoaded?: undefined;
23
24
  };
24
- type PlusFileValue = PlusFileCommons & {
25
+ /** +{configName}.js */
26
+ type PlusFileValue = PlusFileCommon & {
25
27
  isConfigFile: false;
26
28
  configName: string;
27
29
  } & ({
@@ -34,4 +36,4 @@ type PlusFileValue = PlusFileCommons & {
34
36
  isExtensionConfig?: undefined;
35
37
  };
36
38
  type PlusFilesByLocationId = Record<LocationId, PlusFile[]>;
37
- declare function getPlusFilesAll(userRootDir: string, esbuildCache: EsbuildCache): Promise<PlusFilesByLocationId>;
39
+ declare function getPlusFilesByLocationId(userRootDir: string, esbuildCache: EsbuildCache): Promise<PlusFilesByLocationId>;