Skip to content

Commit b523d75

Browse files
authored
feat: add option to send warnings to dev client via websocket (#372)
* feat: add option to send warnings to dev client via websocket * fix: optional experimental * fix: add data to websocket message that client needs to work with repeated message for the same file * chore: add type for message and improve docs
1 parent 696e2e1 commit b523d75

File tree

6 files changed

+88
-8
lines changed

6 files changed

+88
-8
lines changed

.changeset/rich-pianos-fly.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/vite-plugin-svelte': minor
3+
---
4+
5+
New experimental option sendWarningsToBrowser

docs/config.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,33 @@ export default defineConfig({
332332
]
333333
});
334334
```
335+
336+
### sendWarningsToBrowser
337+
338+
- **Type:** `boolean`
339+
- **Default:** `false`
340+
341+
Sends a websocket message `svelte:warnings` with the warnings that are passed to `onwarn`. This is only useful if you build a custom browser based integration where you want to display these.
342+
343+
**Example**
344+
345+
```js
346+
import.meta.hot.on('svelte:warnings', (message) => {
347+
// handle warnings message, eg log to console
348+
console.warn(`Warnings for ${message.filename}`, message.warnings);
349+
});
350+
```
351+
352+
**Message format**
353+
354+
```ts
355+
type SvelteWarningsMessage = {
356+
id: string;
357+
filename: string;
358+
normalizedFilename: string;
359+
timestamp: number;
360+
warnings: Warning[]; // allWarnings filtered by warnings where onwarn did not call the default handler
361+
allWarnings: Warning[]; // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
362+
rawWarnings: Warning[]; // raw compiler output
363+
};
364+
```

packages/vite-plugin-svelte/src/handle-hot-update.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export async function handleHotUpdate(
5353

5454
if (!jsUpdated) {
5555
// transform won't be called, log warnings here
56-
logCompilerWarnings(compileData.compiled.warnings, options);
56+
logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
5757
}
5858

5959
const result = [...affectedModules].filter(Boolean) as ModuleNode[];

packages/vite-plugin-svelte/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin[] {
186186
cache.setError(svelteRequest, e);
187187
throw toRollupError(e, options);
188188
}
189-
logCompilerWarnings(compileData.compiled.warnings, options);
189+
logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
190190
cache.update(compileData);
191191
if (compileData.dependencies?.length && options.server) {
192192
compileData.dependencies.forEach((d) => {
@@ -237,3 +237,5 @@ export {
237237
Processed,
238238
Warning
239239
} from './utils/options';
240+
241+
export { SvelteWarningsMessage } from './utils/log';

packages/vite-plugin-svelte/src/utils/log.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { cyan, yellow, red } from 'kleur/colors';
33
import debug from 'debug';
44
import { ResolvedOptions, Warning } from './options';
5+
import { SvelteRequest } from './id';
56

67
const levels: string[] = ['debug', 'info', 'warn', 'error', 'silent'];
78
const prefix = 'vite-plugin-svelte';
@@ -99,18 +100,54 @@ export const log = {
99100
setLevel
100101
};
101102

102-
export function logCompilerWarnings(warnings: Warning[], options: ResolvedOptions) {
103+
export type SvelteWarningsMessage = {
104+
id: string;
105+
filename: string;
106+
normalizedFilename: string;
107+
timestamp: number;
108+
warnings: Warning[]; // allWarnings filtered by warnings where onwarn did not call the default handler
109+
allWarnings: Warning[]; // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
110+
rawWarnings: Warning[]; // raw compiler output
111+
};
112+
113+
export function logCompilerWarnings(
114+
svelteRequest: SvelteRequest,
115+
warnings: Warning[],
116+
options: ResolvedOptions
117+
) {
103118
const { emitCss, onwarn, isBuild } = options;
104-
const warn = isBuild ? warnBuild : warnDev;
105-
const notIgnoredWarnings = warnings?.filter((w) => !ignoreCompilerWarning(w, isBuild, emitCss));
106-
const extraWarnings = buildExtraWarnings(warnings, isBuild);
107-
[...notIgnoredWarnings, ...extraWarnings].forEach((warning) => {
119+
const sendViaWS = !isBuild && options.experimental?.sendWarningsToBrowser;
120+
let warn = isBuild ? warnBuild : warnDev;
121+
const handledByDefaultWarn: Warning[] = [];
122+
const notIgnored = warnings?.filter((w) => !ignoreCompilerWarning(w, isBuild, emitCss));
123+
const extra = buildExtraWarnings(warnings, isBuild);
124+
const allWarnings = [...notIgnored, ...extra];
125+
if (sendViaWS) {
126+
warn = (w: Warning) => {
127+
handledByDefaultWarn.push(w);
128+
warn(w);
129+
};
130+
}
131+
allWarnings.forEach((warning) => {
108132
if (onwarn) {
109133
onwarn(warning, warn);
110134
} else {
111135
warn(warning);
112136
}
113137
});
138+
if (sendViaWS) {
139+
const message: SvelteWarningsMessage = {
140+
id: svelteRequest.id,
141+
filename: svelteRequest.filename,
142+
normalizedFilename: svelteRequest.normalizedFilename,
143+
timestamp: svelteRequest.timestamp,
144+
warnings: handledByDefaultWarn, // allWarnings filtered by warnings where onwarn did not call the default handler
145+
allWarnings, // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
146+
rawWarnings: warnings // raw compiler output
147+
};
148+
log.debug(`sending svelte:warnings message for ${svelteRequest.normalizedFilename}`);
149+
options.server?.ws?.send('svelte:warnings', message);
150+
}
114151
}
115152

116153
function ignoreCompilerWarning(

packages/vite-plugin-svelte/src/utils/options.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,12 @@ export interface ExperimentalOptions {
560560
* enable svelte inspector
561561
*/
562562
inspector?: InspectorOptions | boolean;
563+
564+
/**
565+
* send a websocket message with svelte compiler warnings during dev
566+
*
567+
*/
568+
sendWarningsToBrowser?: boolean;
563569
}
564570

565571
export interface InspectorOptions {
@@ -609,7 +615,7 @@ export interface InspectorOptions {
609615
export interface PreResolvedOptions extends Options {
610616
// these options are non-nullable after resolve
611617
compilerOptions: CompileOptions;
612-
experimental: ExperimentalOptions;
618+
experimental?: ExperimentalOptions;
613619
// extra options
614620
root: string;
615621
isBuild: boolean;

0 commit comments

Comments
 (0)