vike 0.4.248 → 0.4.249-commit-775a43e

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 (34) hide show
  1. package/dist/client/runtime-client-routing/getPageContext.js +0 -2
  2. package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +8 -8
  3. package/dist/client/runtime-client-routing/renderPageClient.d.ts +4 -4
  4. package/dist/node/api/utils.d.ts +2 -2
  5. package/dist/node/api/utils.js +2 -2
  6. package/dist/node/vite/plugins/build/pluginBuildConfig.js +2 -2
  7. package/dist/node/vite/plugins/pluginVirtualFiles.js +70 -112
  8. package/dist/node/vite/shared/loggerDev.d.ts +3 -0
  9. package/dist/node/vite/shared/loggerDev.js +29 -13
  10. package/dist/node/vite/shared/loggerVite.js +3 -3
  11. package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesAll.d.ts +1 -1
  12. package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesAll.js +8 -6
  13. package/dist/node/vite/shared/resolveVikeConfigInternal.js +25 -23
  14. package/dist/server/runtime/asyncHook.d.ts +2 -2
  15. package/dist/server/runtime/asyncHook.js +2 -2
  16. package/dist/server/utils.d.ts +2 -2
  17. package/dist/server/utils.js +2 -2
  18. package/dist/types/Config.d.ts +3 -2
  19. package/dist/utils/PROJECT_VERSION.d.ts +1 -1
  20. package/dist/utils/PROJECT_VERSION.js +1 -1
  21. package/dist/utils/assert.d.ts +7 -4
  22. package/dist/utils/assert.js +65 -50
  23. package/dist/utils/colorsClient.d.ts +6 -0
  24. package/dist/utils/colorsClient.js +16 -0
  25. package/dist/utils/{colors.js → colorsServer.js} +2 -0
  26. package/dist/utils/formatHintLog.js +1 -1
  27. package/dist/utils/getBetterError.js +11 -7
  28. package/dist/utils/shallowClone.d.ts +2 -0
  29. package/dist/utils/shallowClone.js +11 -0
  30. package/dist/utils/trimWithAnsi.js +1 -1
  31. package/package.json +4 -4
  32. package/dist/utils/colorVike.d.ts +0 -2
  33. package/dist/utils/colorVike.js +0 -5
  34. /package/dist/utils/{colors.d.ts → colorsServer.d.ts} +0 -0
@@ -1,8 +1,6 @@
1
1
  export { getPageContext };
2
2
  export { providePageContext };
3
3
  // TO-DO/eventually: create new setting `+asyncHook: true` that sets the default value of the `asyncHook` parameter below to `true`
4
- // TODO/next-release: update vike-{react,vue,solid} usage
5
- // TODO/next-release: contact Da-Jin about `window.history.state?.vike` https://vike.dev/navigate#history-pushstate
6
4
  import { getPageContext_sync, providePageContext } from '../../shared-server-client/hooks/execHook.js';
7
5
  import { getPageContextClient } from './renderPageClient.js';
8
6
  function getPageContext({ asyncHook } = {}) {
@@ -136,7 +136,7 @@ declare function getPageContextFromHooksClient_firstRender(pageContext: PageCont
136
136
  url: string;
137
137
  pageExports: Record<string, unknown>;
138
138
  isBaseMissing?: true;
139
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
139
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
140
140
  isClientSide: true;
141
141
  isPrerendering: false;
142
142
  } & {
@@ -152,7 +152,7 @@ declare function getPageContextFromHooksClient_firstRender(pageContext: PageCont
152
152
  urlParsed: import("./utils.js").UrlPublic;
153
153
  urlPathname: string;
154
154
  url: string;
155
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
155
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
156
156
  previousPageContext: {
157
157
  pageId: string;
158
158
  } | null;
@@ -204,7 +204,7 @@ declare function getPageContextFromHooksClient_firstRender(pageContext: PageCont
204
204
  url: string;
205
205
  pageExports: Record<string, unknown>;
206
206
  isBaseMissing?: true;
207
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
207
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
208
208
  isClientSide: true;
209
209
  isPrerendering: false;
210
210
  } & {
@@ -220,7 +220,7 @@ declare function getPageContextFromHooksClient_firstRender(pageContext: PageCont
220
220
  urlParsed: import("./utils.js").UrlPublic;
221
221
  urlPathname: string;
222
222
  url: string;
223
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
223
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
224
224
  previousPageContext: {
225
225
  pageId: string;
226
226
  } | null;
@@ -362,7 +362,7 @@ declare function getPageContextFromHooksClient(pageContext: {
362
362
  url: string;
363
363
  pageExports: Record<string, unknown>;
364
364
  isBaseMissing?: true;
365
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
365
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
366
366
  isClientSide: true;
367
367
  isPrerendering: false;
368
368
  } & {
@@ -378,7 +378,7 @@ declare function getPageContextFromHooksClient(pageContext: {
378
378
  urlParsed: import("./utils.js").UrlPublic;
379
379
  urlPathname: string;
380
380
  url: string;
381
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
381
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
382
382
  previousPageContext: {
383
383
  pageId: string;
384
384
  } | null;
@@ -428,7 +428,7 @@ declare function getPageContextFromHooksClient(pageContext: {
428
428
  url: string;
429
429
  pageExports: Record<string, unknown>;
430
430
  isBaseMissing?: true;
431
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
431
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
432
432
  isClientSide: true;
433
433
  isPrerendering: false;
434
434
  } & {
@@ -444,7 +444,7 @@ declare function getPageContextFromHooksClient(pageContext: {
444
444
  urlParsed: import("./utils.js").UrlPublic;
445
445
  urlPathname: string;
446
446
  url: string;
447
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
447
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
448
448
  previousPageContext: {
449
449
  pageId: string;
450
450
  } | null;
@@ -149,7 +149,7 @@ declare function renderPageClient(renderArgs: RenderArgs): Promise<({
149
149
  url: string;
150
150
  pageExports: Record<string, unknown>;
151
151
  isBaseMissing?: true;
152
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
152
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
153
153
  isClientSide: true;
154
154
  isPrerendering: false;
155
155
  } & {
@@ -165,7 +165,7 @@ declare function renderPageClient(renderArgs: RenderArgs): Promise<({
165
165
  urlParsed: import("./utils.js").UrlPublic;
166
166
  urlPathname: string;
167
167
  url: string;
168
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
168
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
169
169
  previousPageContext: {
170
170
  pageId: string;
171
171
  } | null;
@@ -300,7 +300,7 @@ declare function getPageContextBegin(isForErrorPage: boolean, { urlOriginal, isB
300
300
  url: string;
301
301
  pageExports: Record<string, unknown>;
302
302
  isBaseMissing?: true;
303
- }, "exports" | "pageId" | "pageExports" | "config" | "Page" | "data" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "routeParams" | "abortReason"> & {
303
+ }, "pageExports" | "exports" | "pageId" | "config" | "Page" | "data" | "routeParams" | "source" | "sources" | "from" | "configEntries" | "exportsAll" | "abortReason"> & {
304
304
  isClientSide: true;
305
305
  isPrerendering: false;
306
306
  } & {
@@ -316,7 +316,7 @@ declare function getPageContextBegin(isForErrorPage: boolean, { urlOriginal, isB
316
316
  urlParsed: import("./utils.js").UrlPublic;
317
317
  urlPathname: string;
318
318
  url: string;
319
- }, ("globalContext" | "Page" | "data") | "previousPageContext" | "pageContextsAborted"> & {
319
+ }, "pageContextsAborted" | "previousPageContext" | ("globalContext" | "Page" | "data")> & {
320
320
  previousPageContext: {
321
321
  pageId: string;
322
322
  } | null;
@@ -6,6 +6,6 @@ export * from '../../utils/assertVersion.js';
6
6
  export * from '../../utils/pick.js';
7
7
  export * from '../../utils/assertSetup.js';
8
8
  export * from '../../utils/isCallable.js';
9
- export * from '../../utils/colors.js';
10
- export * from '../../utils/colorVike.js';
9
+ export * from '../../utils/colorsServer.js';
10
+ export * from '../../utils/colorsClient.js';
11
11
  export * from '../../utils/PROJECT_VERSION.js';
@@ -10,6 +10,6 @@ export * from '../../utils/assertVersion.js';
10
10
  export * from '../../utils/pick.js';
11
11
  export * from '../../utils/assertSetup.js';
12
12
  export * from '../../utils/isCallable.js';
13
- export * from '../../utils/colors.js';
14
- export * from '../../utils/colorVike.js';
13
+ export * from '../../utils/colorsServer.js';
14
+ export * from '../../utils/colorsClient.js';
15
15
  export * from '../../utils/PROJECT_VERSION.js';
@@ -1,7 +1,7 @@
1
1
  export { pluginBuildConfig };
2
2
  export { assertRollupInput };
3
3
  export { analyzeClientEntries };
4
- import { assert, addOnBeforeAssertLog, removeFileExtension, unique, assertUsage, injectRollupInputs, normalizeRollupInput, onSetupBuild, assertIsImportPathNpmPackage, requireResolveDistFile, } from '../../utils.js';
4
+ import { assert, setAssertOnBeforeLog, removeFileExtension, unique, assertUsage, injectRollupInputs, normalizeRollupInput, onSetupBuild, assertIsImportPathNpmPackage, requireResolveDistFile, } from '../../utils.js';
5
5
  import { getVikeConfigInternal } from '../../shared/resolveVikeConfigInternal.js';
6
6
  import { findPageFiles } from '../../shared/findPageFiles.js';
7
7
  import { generateVirtualFileId } from '../../../../shared-server-node/virtualFileId.js';
@@ -203,7 +203,7 @@ function addLogHook() {
203
203
  'rendering chunks (',
204
204
  'computing gzip size ('
205
205
  ];
206
- addOnBeforeAssertLog(() => {
206
+ setAssertOnBeforeLog(() => {
207
207
  // Using viteTransientLogs is very conservative as clearing the current line is low risk. (We can assume that important messages, such as errors, include a trailing new line. Usually, only transient messages have no trailing new lines.)
208
208
  if (viteTransientLogs.some((s) => lastLog?.startsWith(s))) {
209
209
  process.stdout.clearLine(0);
@@ -38,11 +38,12 @@ function pluginVirtualFiles() {
38
38
  return addVirtualFileIdPrefix(id);
39
39
  },
40
40
  },
41
+ // Vite calls handleHotUpdate() whenever *any file* is modified — including files that aren't in Vite's module graph such as +config.js
41
42
  handleHotUpdate: {
42
43
  async handler(ctx) {
43
44
  debugFileChange('handleHotUpdate()', ctx.file);
44
45
  try {
45
- return await handleHotUpdate(ctx, config);
46
+ return await onFileModified(ctx, config);
46
47
  }
47
48
  catch (err) {
48
49
  // Vite swallows errors thrown by handleHotUpdate()
@@ -73,106 +74,89 @@ function pluginVirtualFiles() {
73
74
  },
74
75
  configureServer: {
75
76
  handler(server) {
76
- handleFileAddRemove(server, config);
77
+ server.watcher.prependListener('add', (file) => onFileCreatedOrRemoved(file, false, server, config));
78
+ server.watcher.prependListener('unlink', (file) => onFileCreatedOrRemoved(file, true, server, config));
77
79
  },
78
80
  },
79
81
  },
80
82
  ];
81
83
  }
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.
84
+ async function onFileModified(ctx, config) {
85
+ const { file, server } = ctx;
86
+ const isAppFile = await isAppDependency(ctx.file, ctx.server.moduleGraph);
87
+ debugFileChange(isAppFile);
88
+ if (!isAppFile)
89
+ return;
90
+ const reloadVikeConfig = () => reloadConfig(file, config, 'modified', server);
91
+ if (isAppFile.isRuntimeDependency) {
92
+ // Ensure we invalidate `file` *before* server.ssrLoadModule() in updateUserFiles()
93
+ // Vite also invalidates it, but *after* handleHotUpdate() and thus after server.ssrLoadModule()
94
+ ctx.modules.forEach((mod) => server.moduleGraph.invalidateModule(mod));
95
+ // Re-running ssrLoadModule() is cheap (Vite uses a cache) => eagerly calling updateUserFiles() makes sense.
96
+ // - 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).
97
+ await updateUserFiles();
98
+ }
99
+ if (isAppFile.isConfigDependency) {
100
+ /* Tailwind breaks this assertion, see https://github.com/vikejs/vike/discussions/1330#discussioncomment-7787238
101
+ const isViteModule = ctx.modules.length > 0
102
+ assert(!isViteModule)
103
+ */
104
+ reloadVikeConfig();
105
+ // Trigger a full page reload. (Because files such as +config.js can potentially modify Vike's virtual files.)
106
+ const vikeVirtualFiles = getVikeVirtualFiles(server);
107
+ return vikeVirtualFiles;
108
+ }
109
+ }
110
+ async function onFileCreatedOrRemoved(file, isRemove, server, config) {
111
+ file = normalizePath(file);
112
+ if (isTemporaryBuildFile(file))
113
+ return;
114
+ const operation = isRemove ? 'removed' : 'created';
115
+ debugFileChange('server.watcher', file, operation);
116
+ const { moduleGraph } = server;
117
+ const isAppFile = await isAppDependency(file, moduleGraph);
118
+ const reloadVikeConfig = () => reloadConfig(file, config, operation, server);
119
+ if (
120
+ // Vike config (non-runtime) code
121
+ isAppFile?.isConfigDependency ||
122
+ // New + file => not tracked yet by Vike (`vikeConfigObject._vikeConfigDependencies`) nor Vite (`moduleGraph`)
123
+ isPlusFile(file) ||
124
+ // 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.
125
+ // - Reloading Vike's config is cheap => eagerly reloading it makes sense when it's in an erroneous state.
111
126
  // - 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
127
  // - Reproduction:
114
128
  // ```bash
115
- // rm someDep.js && sleep 2 && git checkout someDep.js
129
+ // rm someImportedFile.js && sleep 2 && git checkout someImportedFile.js
116
130
  // ```
117
- if (isScriptFile(file) && getVikeConfigError() && !existsInViteModuleGraph(file, moduleGraph)) {
118
- reload();
119
- return;
120
- }
131
+ (isScriptFile(file) && getVikeConfigError())) {
132
+ reloadVikeConfig();
121
133
  }
122
134
  }
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.
135
+ async function isAppDependency(filePathAbsoluteFilesystem, moduleGraph) {
136
+ const isAppFile = {};
137
+ // =============================
138
+ // { isConfigDependency: false }
139
+ // =============================
140
+ // Vike config (non-runtime) files such as +config.js which aren't processed by Vite.
156
141
  // - They're missing in Vite's module graph.
157
142
  // - Potentially modifies Vike's virtual files.
158
- // - Same for all `pages/+config.js` dependencies.
143
+ // - Same for all `pages/+config.js` transitive dependencies.
159
144
  assertPosixPath(filePathAbsoluteFilesystem);
160
145
  const vikeConfigObject = await getVikeConfigInternalOptional();
161
146
  if (vikeConfigObject) {
162
147
  const { _vikeConfigDependencies: vikeConfigDependencies } = vikeConfigObject;
163
148
  vikeConfigDependencies.forEach((f) => assertPosixPath(f));
164
- if (vikeConfigDependencies.has(filePathAbsoluteFilesystem))
165
- return { isProcessedByVite: false };
149
+ isAppFile.isConfigDependency = vikeConfigDependencies.has(filePathAbsoluteFilesystem);
166
150
  }
167
- // Runtime Vike config files such as +data.js which are processed by Vite.
151
+ // =============================
152
+ // { isRuntimeDependency: true }
153
+ // =============================
154
+ // Vike runtime files such as +data.js which are processed by Vite.
168
155
  // - They're included in Vite's module graph.
169
156
  // - 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;
157
+ // - Same for all `+data.js` transitive dependencies.
158
+ isAppFile.isRuntimeDependency = existsInViteModuleGraph(filePathAbsoluteFilesystem, moduleGraph);
159
+ return isAppFile;
176
160
  }
177
161
  function reloadConfig(filePath, config, operation, server) {
178
162
  // Ensure server.ssrLoadModule() loads fresh Vike virtual files (`reloadConfig()` > `updateUserFiles()` > `server.ssrLoadModule()`)
@@ -185,6 +169,12 @@ function reloadConfig(filePath, config, operation, server) {
185
169
  reloadVikeConfig();
186
170
  updateUserFiles();
187
171
  }
172
+ function invalidateVikeVirtualFiles(server) {
173
+ const vikeVirtualFiles = getVikeVirtualFiles(server);
174
+ vikeVirtualFiles.forEach((mod) => {
175
+ server.moduleGraph.invalidateModule(mod);
176
+ });
177
+ }
188
178
  function getVikeVirtualFiles(server) {
189
179
  const vikeVirtualFiles = Array.from(server.moduleGraph.urlToModuleMap.keys())
190
180
  .filter((url) => parseVirtualFileId(url))
@@ -195,38 +185,6 @@ function getVikeVirtualFiles(server) {
195
185
  });
196
186
  return vikeVirtualFiles;
197
187
  }
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
188
  function existsInViteModuleGraph(file, moduleGraph) {
231
189
  return !!moduleGraph.getModulesByFile(file);
232
190
  }
@@ -2,8 +2,11 @@ export { logVite };
2
2
  export { logConfigInfo };
3
3
  export { logErrorServerDev };
4
4
  export type { LogType };
5
+ export type { AddTagsDev };
5
6
  import { type PageContext_logRuntime } from '../../../server/runtime/loggerRuntime.js';
6
7
  type LogType = 'info' | 'warn' | 'error' | 'error-resolve';
7
8
  declare function logConfigInfo(msg: string, logType: LogType): void;
8
9
  declare function logVite(msg: string, logType: LogType, requestId: number | null, prependViteTag: boolean): void;
9
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}`;
@@ -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 { addOnBeforeAssertErr, assert, assertIsNotProductionRuntime, colorVike, colorVite, formatHintLog, hasGreen, hasProp, hasRed, hasYellow, isDebugError, stripAnsi, } from '../utils.js';
15
+ import { setAssertOnBeforeErr, assert, assertIsNotProductionRuntime, colorVike, colorVite, formatHintLog, hasGreen, hasProp, hasRed, hasYellow, isDebugError, stripAnsi, colorError, colorWarning, setAssertAddTagsDev, } 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';
@@ -20,13 +20,14 @@ import { isUserHookError } from '../../../shared-server-client/hooks/execHook.js
20
20
  import { getViteDevServer } from '../../../server/runtime/globalContext.js';
21
21
  import { logErrorServer } from '../../../server/runtime/logErrorServer.js';
22
22
  import { getBetterError } from '../../../utils/getBetterError.js';
23
- import { getHttpRequestId_withAsyncHook } from '../../../server/runtime/asyncHook.js';
23
+ import { getRequestId_withAsyncHook } from '../../../server/runtime/asyncHook.js';
24
24
  assertIsNotProductionRuntime();
25
25
  setLogRuntimeDev(logErrorServerDev, logRuntimeInfoDev);
26
- addOnBeforeAssertErr((err) => {
26
+ 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
- applyViteSourceMapToStackTrace(err);
28
+ applyViteSourceMap(err);
29
29
  });
30
+ setAssertAddTagsDev(addTagsDev);
30
31
  // Note shown to user when Vike completely modifies the error message (which is somewhat risky)
31
32
  const errorDebugNote = pc.dim(formatHintLog("Error isn't helpful? See https://vike.dev/debug#verbose-errors"));
32
33
  function logRuntimeInfoDev(msg, pageContext, logType) {
@@ -44,7 +45,7 @@ function logVite(msg, logType, requestId, prependViteTag) {
44
45
  }
45
46
  function logErrorServerDev(err, pageContext, errorComesFromVite = false) {
46
47
  assertPageContext_logRuntime(pageContext);
47
- applyViteSourceMapToStackTrace(err);
48
+ applyViteSourceMap(err);
48
49
  // Skip `throw render()` / `throw redirect()`
49
50
  if (isAbortError(err) && !isDebugError()) {
50
51
  return;
@@ -96,7 +97,7 @@ function logErrorServerDev(err, pageContext, errorComesFromVite = false) {
96
97
  }
97
98
  }
98
99
  if (tagSource) {
99
- const errIntro = pc.bold(pc.red(`[Error] ${errorComesFromVite ? 'Transpilation error' : 'An error was thrown'}:`));
100
+ const errIntro = colorError(`[Error] ${errorComesFromVite ? 'Transpilation error' : 'An error was thrown'}:`);
100
101
  const prepend = `${getTagsError(errIntro, tagSource)}${errIntro}\n`;
101
102
  const errBetter = getBetterError(err, { message: { prepend } });
102
103
  logErr(errBetter);
@@ -128,7 +129,7 @@ function logDev(msg, logType, tagSource, tagTool, doNotAddTags) {
128
129
  assert(false);
129
130
  }
130
131
  function getTagSource(requestId = null) {
131
- const requestIdFromStore = getHttpRequestId_withAsyncHook();
132
+ const requestIdFromStore = getRequestId_withAsyncHook();
132
133
  if (requestIdFromStore !== null) {
133
134
  if (requestId === null) {
134
135
  requestId = requestIdFromStore;
@@ -143,7 +144,7 @@ function getTagSource(requestId = null) {
143
144
  const tagSource = `request-${requestId}`;
144
145
  return tagSource;
145
146
  }
146
- function applyViteSourceMapToStackTrace(thing) {
147
+ function applyViteSourceMap(thing) {
147
148
  if (isDebugError())
148
149
  return;
149
150
  if (!hasProp(thing, 'stack'))
@@ -160,20 +161,35 @@ function getTagsError(msg, tagSource) {
160
161
  function getTags(msg, tagTool, tagSource, logType) {
161
162
  const tagToolColored = (() => {
162
163
  if (logType === 'error' && !hasRed(msg))
163
- return pc.bold(pc.red(tagTool));
164
+ return colorError(tagTool);
164
165
  if (logType === 'error-resolve' && !hasGreen(msg))
165
166
  return pc.bold(pc.green(tagTool));
166
167
  if (logType === 'warn' && !hasYellow(msg))
167
- return pc.yellow(tagTool);
168
+ return colorWarning(tagTool);
168
169
  if (tagTool === '[vite]')
169
170
  return colorVite(tagTool);
170
171
  if (tagTool === '[vike]')
171
172
  return colorVike(tagTool);
172
173
  assert(false);
173
174
  })();
174
- const timestamp = pc.dim(new Date().toLocaleTimeString());
175
+ const timestamp = getTagTimestamp();
175
176
  const whitespace = (/\s|\[/.test(stripAnsi(msg)[0]) ? '' : ' ');
176
- const tagSourceStr = (!tagSource ? '' : pc.dim(`[${tagSource}]`));
177
- const tags = `${timestamp} ${tagToolColored}${tagSourceStr}${whitespace}`;
177
+ const tagSourceOuter = getTagSourceOuter(tagSource);
178
+ const tags = `${timestamp} ${tagToolColored}${tagSourceOuter}${whitespace}`;
178
179
  return tags;
179
180
  }
181
+ function getTagTimestamp() {
182
+ const timestamp = pc.dim(new Date().toLocaleTimeString());
183
+ return timestamp;
184
+ }
185
+ function getTagSourceOuter(tagSource) {
186
+ const tagSourceOuter = (!tagSource ? '' : pc.dim(`[${tagSource}]`));
187
+ return tagSourceOuter;
188
+ }
189
+ function addTagsDev(tagVike, tagType) {
190
+ const timestamp = getTagTimestamp();
191
+ const tagSource = getTagSource();
192
+ const tagSourceOuter = getTagSourceOuter(tagSource);
193
+ const tagsDev = `${timestamp} ${tagVike}${tagSourceOuter}${tagType}`;
194
+ return tagsDev;
195
+ }
@@ -5,7 +5,7 @@ export { swallowViteLogForceOptimization_disable };
5
5
  export { swallowViteLogConnected };
6
6
  export { swallowViteLogConnected_clean };
7
7
  import { assert, getGlobalObject, isDebugError, removeEmptyLines, trimWithAnsi, trimWithAnsiTrailOnly, } from '../utils.js';
8
- import { getHttpRequestId_withAsyncHook } from '../../../server/runtime/asyncHook.js';
8
+ import { getRequestId_withAsyncHook } from '../../../server/runtime/asyncHook.js';
9
9
  import { logErrorServerDev, logVite } from './loggerDev.js';
10
10
  const globalObject = getGlobalObject('vite/shared/loggerDev.ts', {
11
11
  processStartupLog_isCompact: null,
@@ -43,7 +43,7 @@ function intercept(loggerType, config) {
43
43
  // - It doesn't format error code snippets.
44
44
  // - It only shows error.message which means that crucial information such as error.id isn't shown to the user.
45
45
  logErrorServerDev(options.error, null, true);
46
- // We swallow Vite's message: we didn't see it add any value so far.
46
+ // We swallow Vite's message: it doesn't seem to add any value.
47
47
  // - It can even be confusing, such as the following:
48
48
  // ```
49
49
  // Error when evaluating SSR module virtual:vike:page-entry:server:/pages/abort: failed to import "/pages/abort/+Page.mdx"
@@ -51,7 +51,7 @@ function intercept(loggerType, config) {
51
51
  assert(!isDebugError());
52
52
  return;
53
53
  }
54
- const requestId = getHttpRequestId_withAsyncHook();
54
+ const requestId = getRequestId_withAsyncHook();
55
55
  // Vite's default logger preprends the "[vite]" tag if and only if options.timestamp is true
56
56
  const prependViteTag = options.timestamp || typeof requestId === 'number';
57
57
  // If it's an actual error => options.error is set => it's handled with logErrorServerDev() above
@@ -16,7 +16,7 @@ type PlusFileConfig = PlusFileCommons & {
16
16
  fileExportsByConfigName: Record<string, // configName
17
17
  unknown>;
18
18
  pointerImportsByConfigName: Record<string, // configName
19
- PointerImportLoaded>;
19
+ PointerImportLoaded[]>;
20
20
  isExtensionConfig: boolean;
21
21
  extendsFilePaths: string[];
22
22
  isNotLoaded?: undefined;
@@ -95,12 +95,14 @@ function getPlusFileFromConfigFile(configFile, isExtensionConfig, locationId, us
95
95
  const fileExport = getConfigFileExport(fileExports, filePath.filePathToShowToUser);
96
96
  Object.entries(fileExport).forEach(([configName, configValue]) => {
97
97
  fileExportsByConfigName[configName] = configValue;
98
- const pointerImport = resolvePointerImport(configValue, configFile.filePath, userRootDir, configName);
99
- if (pointerImport) {
100
- pointerImportsByConfigName[configName] = {
101
- ...pointerImport,
102
- fileExportValueLoaded: false,
103
- };
98
+ // Pointer imports
99
+ const values = Array.isArray(configValue) ? configValue : [configValue];
100
+ const pointerImports = values
101
+ .map((value) => resolvePointerImport(value, configFile.filePath, userRootDir, configName))
102
+ .filter((pointerImport) => pointerImport !== null)
103
+ .map((pointerImport) => ({ ...pointerImport, fileExportValueLoaded: false }));
104
+ if (pointerImports.length > 0) {
105
+ pointerImportsByConfigName[configName] = pointerImports;
104
106
  }
105
107
  });
106
108
  const plusFile = {
@@ -246,8 +246,8 @@ async function loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, user
246
246
  await loadValueFile(plusFile, configDefinitions, userRootDir, esbuildCache);
247
247
  }
248
248
  else {
249
- await Promise.all(Object.entries(plusFile.pointerImportsByConfigName).map(async ([configName, pointerImport]) => {
250
- await loadPointerImport(pointerImport, userRootDir, configName, configDefinitions, esbuildCache);
249
+ await Promise.all(Object.entries(plusFile.pointerImportsByConfigName).map(async ([configName, pointerImports]) => {
250
+ await Promise.all(pointerImports.map((pointerImport) => loadPointerImport(pointerImport, userRootDir, configName, configDefinitions, esbuildCache)));
251
251
  }));
252
252
  }
253
253
  }));
@@ -558,7 +558,7 @@ function sortPlusFilesSameLocationId(plusFile1, plusFile2, configName) {
558
558
  function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal, plusFilesAll) {
559
559
  let sources = plusFilesRelevant
560
560
  .filter((plusFile) => isDefiningConfig(plusFile, configName))
561
- .map((plusFile) => getConfigValueSource(configName, plusFile, configDef, userRootDir));
561
+ .flatMap((plusFile) => getConfigValueSources(configName, plusFile, configDef, userRootDir));
562
562
  // Filter hydrid global-local configs
563
563
  if (!isCallable(configDef.global)) {
564
564
  // Already filtered
@@ -579,7 +579,7 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
579
579
  function isDefiningConfig(plusFile, configName) {
580
580
  return getConfigNamesSetByPlusFile(plusFile).includes(configName);
581
581
  }
582
- function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
582
+ function getConfigValueSources(configName, plusFile, configDef, userRootDir) {
583
583
  const confVal = getConfVal(plusFile, configName);
584
584
  assert(confVal);
585
585
  const configValueSourceCommon = {
@@ -622,7 +622,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
622
622
  valueIsDefinedByPlusValueFile: false,
623
623
  definedAt: definedAtFilePath,
624
624
  };
625
- return configValueSource;
625
+ return [configValueSource];
626
626
  }
627
627
  // +config.js
628
628
  if (plusFile.isConfigFile) {
@@ -630,23 +630,25 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
630
630
  // Defined over pointer import
631
631
  const pointerImport = plusFile.pointerImportsByConfigName[configName];
632
632
  if (pointerImport) {
633
- const value = pointerImport.fileExportValueLoaded
634
- ? {
635
- valueIsLoaded: true,
636
- value: pointerImport.fileExportValue,
637
- }
638
- : {
639
- valueIsLoaded: false,
633
+ return pointerImport.map((pointerImport) => {
634
+ const value = pointerImport.fileExportValueLoaded
635
+ ? {
636
+ valueIsLoaded: true,
637
+ value: pointerImport.fileExportValue,
638
+ }
639
+ : {
640
+ valueIsLoaded: false,
641
+ };
642
+ const configValueSource = {
643
+ ...configValueSourceCommon,
644
+ ...value,
645
+ configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
646
+ valueIsLoadedWithImport: true,
647
+ valueIsDefinedByPlusValueFile: false,
648
+ definedAt: pointerImport.fileExportPath,
640
649
  };
641
- const configValueSource = {
642
- ...configValueSourceCommon,
643
- ...value,
644
- configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
645
- valueIsLoadedWithImport: true,
646
- valueIsDefinedByPlusValueFile: false,
647
- definedAt: pointerImport.fileExportPath,
648
- };
649
- return configValueSource;
650
+ return configValueSource;
651
+ });
650
652
  }
651
653
  // Defined inside +config.js
652
654
  const configValueSource = {
@@ -658,7 +660,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
658
660
  valueIsDefinedByPlusValueFile: false,
659
661
  definedAt: definedAtFilePath_,
660
662
  };
661
- return configValueSource;
663
+ return [configValueSource];
662
664
  }
663
665
  // Defined by value file, i.e. +{configName}.js
664
666
  if (!plusFile.isConfigFile) {
@@ -678,7 +680,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
678
680
  [configName],
679
681
  },
680
682
  };
681
- return configValueSource;
683
+ return [configValueSource];
682
684
  }
683
685
  assert(false);
684
686
  }
@@ -1,5 +1,5 @@
1
1
  export { getPageContext_withAsyncHook };
2
- export { getHttpRequestId_withAsyncHook };
2
+ export { getRequestId_withAsyncHook };
3
3
  export { getAsyncLocalStorage };
4
4
  export type { AsyncStore };
5
5
  import type { AsyncLocalStorage as AsyncLocalStorageType } from 'node:async_hooks';
@@ -8,5 +8,5 @@ type AsyncStore = null | {
8
8
  pageContext?: Record<string, unknown>;
9
9
  };
10
10
  declare function getAsyncLocalStorage(): Promise<AsyncLocalStorageType<AsyncStore> | null>;
11
- declare function getHttpRequestId_withAsyncHook(): number | null;
11
+ declare function getRequestId_withAsyncHook(): number | null;
12
12
  declare function getPageContext_withAsyncHook(): any;
@@ -1,5 +1,5 @@
1
1
  export { getPageContext_withAsyncHook };
2
- export { getHttpRequestId_withAsyncHook };
2
+ export { getRequestId_withAsyncHook };
3
3
  export { getAsyncLocalStorage };
4
4
  import { preparePageContextForPublicUsageServer } from './renderPageServer/preparePageContextForPublicUsageServer.js';
5
5
  import { assert, assertIsNotBrowser, getGlobalObject, isObject } from '../utils.js';
@@ -30,7 +30,7 @@ function getAsyncStore() {
30
30
  assert(asyncStore === undefined || isObject(asyncStore));
31
31
  return asyncStore ?? null;
32
32
  }
33
- function getHttpRequestId_withAsyncHook() {
33
+ function getRequestId_withAsyncHook() {
34
34
  const asyncStore = getAsyncStore();
35
35
  return asyncStore?.requestId ?? null;
36
36
  }
@@ -42,8 +42,8 @@ export * from '../utils/assertSetup.js';
42
42
  export * from '../utils/path.js';
43
43
  export * from '../utils/isHtml.js';
44
44
  export * from '../utils/virtualFileId.js';
45
- export * from '../utils/colors.js';
46
- export * from '../utils/colorVike.js';
45
+ export * from '../utils/colorsServer.js';
46
+ export * from '../utils/colorsClient.js';
47
47
  export * from '../utils/getTerminalWidth.js';
48
48
  export * from '../utils/truncateString.js';
49
49
  export * from '../utils/formatHintLog.js';
@@ -46,8 +46,8 @@ export * from '../utils/assertSetup.js';
46
46
  export * from '../utils/path.js';
47
47
  export * from '../utils/isHtml.js';
48
48
  export * from '../utils/virtualFileId.js';
49
- export * from '../utils/colors.js';
50
- export * from '../utils/colorVike.js';
49
+ export * from '../utils/colorsServer.js';
50
+ export * from '../utils/colorsClient.js';
51
51
  export * from '../utils/getTerminalWidth.js';
52
52
  export * from '../utils/truncateString.js';
53
53
  export * from '../utils/formatHintLog.js';
@@ -339,7 +339,7 @@ type ConfigBuiltIn = {
339
339
  *
340
340
  * https://vike.dev/extends
341
341
  */
342
- extends?: Config | ImportString | (Config | ImportString)[];
342
+ extends?: Config | Config[] | ImportString;
343
343
  /** Hook called before the page is rendered.
344
344
  *
345
345
  * https://vike.dev/onBeforeRender
@@ -596,4 +596,5 @@ type ConfigBuiltInResolved = {
596
596
  headersResponse?: Exclude<Config['headersResponse'], ImportString | undefined>[];
597
597
  };
598
598
  type ConfigMeta = Record<string, ConfigDefinition>;
599
- type ImportString = `import:${string}`;
599
+ type ImportString = ImportStringVal | ImportStringVal[];
600
+ type ImportStringVal = `import:${string}`;
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.247-commit-1250e38";
1
+ export declare const PROJECT_VERSION: "0.4.249-commit-775a43e";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.247-commit-1250e38';
2
+ export const PROJECT_VERSION = '0.4.249-commit-775a43e';
@@ -3,10 +3,12 @@ export { assertUsage };
3
3
  export { assertWarning };
4
4
  export { assertInfo };
5
5
  export { getProjectError };
6
- export { addOnBeforeAssertLog };
7
- export { addOnBeforeAssertErr };
8
6
  export { isVikeBug };
7
+ export { setAssertOnBeforeLog };
8
+ export { setAssertOnBeforeErr };
9
9
  export { setAlwaysShowStackTrace };
10
+ export { setAssertAddTagsDev };
11
+ import type { AddTagsDev } from '../node/vite/shared/loggerDev.js';
10
12
  declare function assert(condition: unknown, debugInfo?: unknown): asserts condition;
11
13
  declare function assertUsage(condition: unknown, errMsg: string, { showStackTrace, exitOnError }?: {
12
14
  showStackTrace?: true;
@@ -20,7 +22,8 @@ declare function assertWarning(condition: unknown, msg: string, { onlyOnce, show
20
22
  declare function assertInfo(condition: unknown, msg: string, { onlyOnce }: {
21
23
  onlyOnce: boolean;
22
24
  }): void;
23
- declare function addOnBeforeAssertLog(onBeforeAssertLog: () => void): void;
24
- declare function addOnBeforeAssertErr(onBeforeAssertErr: (err: unknown) => void): void;
25
+ declare function setAssertOnBeforeLog(onBeforeAssertLog: () => void): void;
26
+ declare function setAssertOnBeforeErr(onBeforeAssertErr: (err: unknown) => void): void;
27
+ declare function setAssertAddTagsDev(addTagsDev: AddTagsDev): void;
25
28
  declare function isVikeBug(err: unknown): boolean;
26
29
  declare function setAlwaysShowStackTrace(): void;
@@ -3,24 +3,24 @@ export { assertUsage };
3
3
  export { assertWarning };
4
4
  export { assertInfo };
5
5
  export { getProjectError };
6
- export { addOnBeforeAssertLog };
7
- export { addOnBeforeAssertErr };
8
6
  export { isVikeBug };
7
+ export { setAssertOnBeforeLog };
8
+ export { setAssertOnBeforeErr };
9
9
  export { setAlwaysShowStackTrace };
10
+ export { setAssertAddTagsDev };
10
11
  import { assertSingleInstance_onAssertModuleLoad } from './assertSingleInstance.js';
11
12
  import { createErrorWithCleanStackTrace } from './createErrorWithCleanStackTrace.js';
12
13
  import { getGlobalObject } from './getGlobalObject.js';
13
14
  import { PROJECT_VERSION } from './PROJECT_VERSION.js';
14
- import { colorVike } from './colorVike.js';
15
+ import { colorVike, colorWarning, colorError } from './colorsClient.js';
15
16
  import pc from '@brillout/picocolors';
16
17
  const globalObject = getGlobalObject('utils/assert.ts', {
17
18
  alreadyLogged: new Set(),
18
19
  });
19
20
  assertSingleInstance_onAssertModuleLoad();
20
- const projectTag = `[vike]`;
21
- const projectTagWithVersion = `[vike@${PROJECT_VERSION}]`;
22
- const bugTag = 'Bug';
23
- const numberOfStackTraceLinesToRemove = 2;
21
+ const tagVike = `[vike]`;
22
+ const tagVikeWithVersion = `[vike@${PROJECT_VERSION}]`;
23
+ const tagTypeBug = 'Bug';
24
24
  function assert(condition, debugInfo) {
25
25
  if (condition)
26
26
  return;
@@ -38,24 +38,20 @@ function assert(condition, debugInfo) {
38
38
  ]
39
39
  .filter(Boolean)
40
40
  .join(' ');
41
- errMsg = addWhitespace(errMsg);
42
- errMsg = addPrefixAssertType(errMsg, bugTag);
43
- errMsg = addPrefixProjectName(errMsg, true);
44
- const internalError = createErrorWithCleanStackTrace(errMsg, numberOfStackTraceLinesToRemove);
45
- globalObject.onBeforeAssertLog?.();
46
- globalObject.onBeforeAssertErr?.(internalError);
41
+ errMsg = addTags(errMsg, tagTypeBug, true);
42
+ const internalError = createError(errMsg);
43
+ globalObject.onBeforeLog?.();
44
+ globalObject.onBeforeErr?.(internalError);
47
45
  throw internalError;
48
46
  }
49
47
  function assertUsage(condition, errMsg, { showStackTrace, exitOnError } = {}) {
50
48
  if (condition)
51
49
  return;
52
50
  showStackTrace = showStackTrace || globalObject.alwaysShowStackTrace;
53
- errMsg = addWhitespace(errMsg);
54
- errMsg = addPrefixAssertType(errMsg, 'Wrong Usage');
55
- errMsg = addPrefixProjectName(errMsg);
56
- const usageError = createErrorWithCleanStackTrace(errMsg, numberOfStackTraceLinesToRemove);
57
- globalObject.onBeforeAssertLog?.();
58
- globalObject.onBeforeAssertErr?.(usageError);
51
+ errMsg = addTags(errMsg, 'Wrong Usage');
52
+ const usageError = createError(errMsg);
53
+ globalObject.onBeforeLog?.();
54
+ globalObject.onBeforeErr?.(usageError);
59
55
  if (!exitOnError) {
60
56
  throw usageError;
61
57
  }
@@ -65,19 +61,14 @@ function assertUsage(condition, errMsg, { showStackTrace, exitOnError } = {}) {
65
61
  }
66
62
  }
67
63
  function getProjectError(errMsg) {
68
- errMsg = addWhitespace(errMsg);
69
- errMsg = addPrefixAssertType(errMsg, 'Error');
70
- errMsg = addPrefixProjectName(errMsg);
71
- const projectError = createErrorWithCleanStackTrace(errMsg, numberOfStackTraceLinesToRemove);
64
+ errMsg = addTags(errMsg, 'Error');
65
+ const projectError = createError(errMsg);
72
66
  return projectError;
73
67
  }
74
68
  function assertWarning(condition, msg, { onlyOnce, showStackTrace }) {
75
69
  if (condition)
76
70
  return;
77
71
  showStackTrace = showStackTrace || globalObject.alwaysShowStackTrace;
78
- msg = addWhitespace(msg);
79
- msg = addPrefixAssertType(msg, 'Warning');
80
- msg = addPrefixProjectName(msg);
81
72
  if (onlyOnce) {
82
73
  const { alreadyLogged } = globalObject;
83
74
  const key = onlyOnce === true ? msg : onlyOnce;
@@ -85,22 +76,22 @@ function assertWarning(condition, msg, { onlyOnce, showStackTrace }) {
85
76
  return;
86
77
  alreadyLogged.add(key);
87
78
  }
88
- globalObject.onBeforeAssertLog?.();
79
+ const msgWithTags = addTags(msg, 'Warning');
80
+ globalObject.onBeforeLog?.();
89
81
  if (showStackTrace) {
90
- const err = createErrorWithCleanStackTrace(msg, numberOfStackTraceLinesToRemove);
91
- globalObject.onBeforeAssertErr?.(err);
82
+ const err = createError(msgWithTags);
83
+ globalObject.onBeforeErr?.(err);
92
84
  console.warn(err);
93
85
  }
94
86
  else {
95
- console.warn(msg);
87
+ console.warn(msgWithTags);
96
88
  }
97
89
  }
98
90
  function assertInfo(condition, msg, { onlyOnce }) {
99
91
  if (condition) {
100
92
  return;
101
93
  }
102
- msg = addWhitespace(msg);
103
- msg = addPrefixProjectName(msg);
94
+ msg = addTags(msg, null);
104
95
  if (onlyOnce) {
105
96
  const { alreadyLogged } = globalObject;
106
97
  const key = msg;
@@ -111,41 +102,65 @@ function assertInfo(condition, msg, { onlyOnce }) {
111
102
  alreadyLogged.add(key);
112
103
  }
113
104
  }
114
- globalObject.onBeforeAssertLog?.();
105
+ globalObject.onBeforeLog?.();
115
106
  console.log(msg);
116
107
  }
117
- function addOnBeforeAssertLog(onBeforeAssertLog) {
118
- globalObject.onBeforeAssertLog = onBeforeAssertLog;
108
+ function setAssertOnBeforeLog(onBeforeAssertLog) {
109
+ globalObject.onBeforeLog = onBeforeAssertLog;
119
110
  }
120
- function addOnBeforeAssertErr(onBeforeAssertErr) {
121
- globalObject.onBeforeAssertErr = onBeforeAssertErr;
111
+ function setAssertOnBeforeErr(onBeforeAssertErr) {
112
+ globalObject.onBeforeErr = onBeforeAssertErr;
122
113
  }
123
- function addPrefixAssertType(msg, tag) {
124
- let prefix = `[${tag}]`;
125
- if (tag === 'Warning') {
126
- prefix = pc.yellow(prefix);
114
+ function setAssertAddTagsDev(addTagsDev) {
115
+ globalObject.addTagsDev = addTagsDev;
116
+ }
117
+ function addTags(msg, tagType, showProjectVersion = false) {
118
+ const tagVike = getTagVike(showProjectVersion);
119
+ const tagTypeOuter = getTagType(tagType);
120
+ const whitespace = getTagWhitespace(msg);
121
+ if (globalObject.addTagsDev) {
122
+ const tagsDev = globalObject.addTagsDev(tagVike, tagTypeOuter);
123
+ return `${tagsDev}${whitespace}${msg}`;
127
124
  }
128
125
  else {
129
- prefix = pc.bold(pc.red(prefix));
126
+ const tags = `${tagVike}${tagTypeOuter}`;
127
+ return `${tags}${whitespace}${msg}`;
130
128
  }
131
- return `${prefix}${msg}`;
132
129
  }
133
- function addWhitespace(msg) {
130
+ function getTagWhitespace(msg) {
134
131
  if (msg.startsWith('[')) {
135
- return msg;
132
+ return '';
133
+ }
134
+ else {
135
+ return ' ';
136
+ }
137
+ }
138
+ function getTagType(tagType) {
139
+ if (!tagType)
140
+ return '';
141
+ let tag = `[${tagType}]`;
142
+ if (tagType === 'Warning') {
143
+ tag = colorWarning(tag);
136
144
  }
137
145
  else {
138
- return ` ${msg}`;
146
+ tag = colorError(tag);
139
147
  }
148
+ return tag;
140
149
  }
141
- function addPrefixProjectName(msg, showProjectVersion = false) {
142
- const prefix = showProjectVersion ? projectTagWithVersion : projectTag;
143
- return `${colorVike(prefix)}${msg}`;
150
+ function getTagVike(showProjectVersion = false) {
151
+ const tag = showProjectVersion ? tagVikeWithVersion : tagVike;
152
+ return colorVike(tag);
144
153
  }
145
154
  function isVikeBug(err) {
146
- return String(err).includes(`[${bugTag}]`);
155
+ return String(err).includes(`[${tagTypeBug}]`);
147
156
  }
148
157
  // Called upon `DEBUG=vike:error`
149
158
  function setAlwaysShowStackTrace() {
150
159
  globalObject.alwaysShowStackTrace = true;
151
160
  }
161
+ function createError(errMsg) {
162
+ const err = createErrorWithCleanStackTrace(errMsg, 3);
163
+ if (globalObject.addTagsDev)
164
+ err.stack = err.stack?.replace(/^Error:\s*/, '');
165
+ return err;
166
+ }
@@ -0,0 +1,6 @@
1
+ export { colorVike };
2
+ export { colorError };
3
+ export { colorWarning };
4
+ declare function colorVike<Str extends string>(str: Str): Str;
5
+ declare function colorError<Str extends string>(str: Str): Str;
6
+ declare function colorWarning<Str extends string>(str: Str): Str;
@@ -0,0 +1,16 @@
1
+ // ./colorsServer.js => server only
2
+ // ./colorsClient.js => server & client
3
+ // !!!WARNING!!! KEEP THIS FILE MINIMAL: to save KBs sent to the browser
4
+ export { colorVike };
5
+ export { colorError };
6
+ export { colorWarning };
7
+ import pc from '@brillout/picocolors';
8
+ function colorVike(str) {
9
+ return pc.bold(pc.yellow(str));
10
+ }
11
+ function colorError(str) {
12
+ return pc.bold(pc.red(str));
13
+ }
14
+ function colorWarning(str) {
15
+ return pc.yellow(str);
16
+ }
@@ -1,3 +1,5 @@
1
+ // ./colorsServer.js => server only
2
+ // ./colorsClient.js => server & client
1
3
  export { stripAnsi };
2
4
  export { hasRed };
3
5
  export { hasGreen };
@@ -1,6 +1,6 @@
1
1
  export { formatHintLog };
2
2
  import { assert } from './assert.js';
3
- import { stripAnsi } from './colors.js';
3
+ import { stripAnsi } from './colorsServer.js';
4
4
  function formatHintLog(msg) {
5
5
  assert(msg.length > 0);
6
6
  const msgLength = stripAnsi(msg).length;
@@ -6,20 +6,24 @@ export { getBetterError };
6
6
  import { isObject } from './isObject.js';
7
7
  import { assertIsNotBrowser } from './assertIsNotBrowser.js';
8
8
  import { objectAssign } from './objectAssign.js';
9
+ import { shallowClone } from './shallowClone.js';
9
10
  assertIsNotBrowser();
10
11
  function getBetterError(err, modifications) {
12
+ const errOriginal = shallowClone(err);
11
13
  let errBetter;
12
14
  // Normalize
13
15
  if (!isObject(err)) {
14
- warnMalformed(err);
16
+ warnMalformed(errOriginal);
15
17
  errBetter = new Error(String(err));
16
18
  }
17
19
  else {
18
- errBetter = structuredClone(err);
20
+ // We mutate instead of structuredClone(err) to avoid breaking Vite's ssrFixStacktrace() internal rewroteStacktraces.has(err) check
21
+ // https://github.com/vitejs/vite/blob/dafd726032daa98d0e614f97aebe9d4dbffe2ea7/packages/vite/src/node/ssr/ssrStacktrace.ts#L95
22
+ errBetter = err;
19
23
  }
20
24
  errBetter.message ?? (errBetter.message = '');
21
25
  if (!errBetter.stack) {
22
- warnMalformed(err);
26
+ warnMalformed(errOriginal);
23
27
  errBetter.stack = new Error(errBetter.message).stack;
24
28
  }
25
29
  // Modifications: err.hideStack and err.stack
@@ -40,7 +44,7 @@ function getBetterError(err, modifications) {
40
44
  errBetter.stack = messageNext + stack;
41
45
  }
42
46
  else {
43
- warnMalformed(err);
47
+ warnMalformed(errOriginal);
44
48
  }
45
49
  }
46
50
  else {
@@ -57,10 +61,10 @@ function getBetterError(err, modifications) {
57
61
  }
58
62
  }
59
63
  // Enable users to retrieve the original error
60
- objectAssign(errBetter, { getOriginalError: () => err?.getOriginalError?.() ?? err });
64
+ objectAssign(errBetter, { getOriginalError: () => errOriginal?.getOriginalError?.() ?? errOriginal });
61
65
  return errBetter;
62
66
  }
63
67
  // TO-DO/eventually: think about whether logging this warning is a good idea
64
- function warnMalformed(err) {
65
- console.warn('Malformed error: ', err);
68
+ function warnMalformed(errOriginal) {
69
+ console.warn('Malformed error: ', errOriginal);
66
70
  }
@@ -0,0 +1,2 @@
1
+ export { shallowClone };
2
+ declare function shallowClone<Obj>(obj: Obj): Obj;
@@ -0,0 +1,11 @@
1
+ export { shallowClone };
2
+ import { isObject } from './isObject.js';
3
+ // - AFAICT it's the most accurate.
4
+ // - The structuredClone() built-in isn't usable: https://www.typescriptlang.org/play/?ssl=7&ssc=1&pln=9&pc=1#code/G4QwTgBApmkLwQHZQO4QKKwPZgBQHIBhAVwGcAXLAW2mzHwEoIRTnEBPAKAh95jAB0AYywATKBAT50AfUIBVAMoAVAPIBZfN149+AiiHJlCYiQgCsABkucRiCrTCEANlmSjJECmGJCjYKFEXNyhcfgZOAHpIiAAZLABzVgADYkRxADMAS3dk2zdSLGcoAVcEgn5g92FTfAAaRyrAmvEIqJjlAAswLBRWEERHHE5vX39AptwAby9qKAAxNKFcJimAXzWGIA
5
+ function shallowClone(obj) {
6
+ if (!isObject(obj))
7
+ return obj;
8
+ const clone = Object.create(Object.getPrototypeOf(obj));
9
+ Object.defineProperties(clone, Object.getOwnPropertyDescriptors(obj));
10
+ return clone;
11
+ }
@@ -1,7 +1,7 @@
1
1
  export { trimWithAnsi };
2
2
  export { trimWithAnsiTrailOnly };
3
3
  import { assert } from './assert.js';
4
- import { stripAnsi } from './colors.js';
4
+ import { stripAnsi } from './colorsServer.js';
5
5
  const whitespaceRegex = /(\s+)/; // Capturing parathesis so that split preserves separator
6
6
  /* Same as trim() but works with ANSI escape codes */
7
7
  function trimWithAnsi(str) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.248",
3
+ "version": "0.4.249-commit-775a43e",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {
@@ -120,7 +120,7 @@
120
120
  "dependencies": {
121
121
  "@brillout/import": "^0.2.6",
122
122
  "@brillout/json-serializer": "^0.5.21",
123
- "@brillout/picocolors": "^1.0.29",
123
+ "@brillout/picocolors": "^1.0.30",
124
124
  "@brillout/require-shim": "^0.1.2",
125
125
  "@brillout/vite-plugin-server-entry": "^0.7.15",
126
126
  "acorn": "^8.0.0",
@@ -244,13 +244,13 @@
244
244
  "./universal-middleware.js"
245
245
  ],
246
246
  "devDependencies": {
247
- "@brillout/release-me": "^0.4.9",
247
+ "@brillout/release-me": "^0.4.12",
248
248
  "@types/estree": "^1.0.5",
249
249
  "@types/node": "^20.10.5",
250
250
  "@types/picomatch": "^3.0.2",
251
251
  "@types/semver": "^7.5.8",
252
252
  "@types/source-map-support": "^0.5.10",
253
- "react-streaming": "^0.4.14",
253
+ "react-streaming": "^0.4.15",
254
254
  "rimraf": "^5.0.5",
255
255
  "typescript": "^5.9.3",
256
256
  "vite": "^7.2.6"
@@ -1,2 +0,0 @@
1
- export { colorVike };
2
- declare function colorVike<Str extends string>(str: Str): Str;
@@ -1,5 +0,0 @@
1
- export { colorVike };
2
- import pc from '@brillout/picocolors';
3
- function colorVike(str) {
4
- return pc.bold(pc.yellow(str));
5
- }
File without changes