Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter out Svelte's unknown class prop console warnings #7291

Merged
merged 9 commits into from
Aug 15, 2023
5 changes: 5 additions & 0 deletions .changeset/big-elephants-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/svelte': patch
---

Filter unknown `class` prop warnings
60 changes: 59 additions & 1 deletion packages/integrations/svelte/client.js
bluwy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
const noop = () => {};

let originalConsoleWarning;
let consoleFilterRefs = 0;

export default (target) => {
return (Component, props, slotted, { client }) => {
if (!target.hasAttribute('ssr')) return;
const slots = {};
for (const [key, value] of Object.entries(slotted)) {
slots[key] = createSlotDefinition(key, value);
}

try {
if (import.meta.env.DEV) useConsoleFilter();

new Component({
target,
props: {
Expand All @@ -18,7 +24,10 @@ export default (target) => {
hydrate: client !== 'only',
$$inline: true,
});
} catch (e) {}
} catch (e) {
} finally {
if (import.meta.env.DEV) finishUsingConsoleFilter();
}
};
};

Expand Down Expand Up @@ -51,3 +60,52 @@ function createSlotDefinition(key, children) {
noop,
];
}

/**
* Reduces console noise by filtering known non-problematic warnings.
*
* Performs reference counting to allow parallel usage from async code.
*
* To stop filtering, please ensure that there always is a matching call
* to `finishUsingConsoleFilter` afterwards.
*/
function useConsoleFilter() {
consoleFilterRefs++;

if (!originalConsoleWarning) {
originalConsoleWarning = console.warn;
try {
console.warn = filteredConsoleWarning;
} catch (error) {
// If we're unable to hook `console.warn`, just accept it
}
}
}

/**
* Indicates that the filter installed by `useConsoleFilter`
* is no longer needed by the calling code.
*/
function finishUsingConsoleFilter() {
consoleFilterRefs--;

// Note: Instead of reverting `console.warning` back to the original
// when the reference counter reaches 0, we leave our hook installed
// to prevent potential race conditions once `check` is made async
}

/**
* Hook/wrapper function for the global `console.warning` function.
*
* Ignores known non-problematic errors while any code is using the console filter.
* Otherwise, simply forwards all arguments to the original function.
*/
function filteredConsoleWarning(msg, ...rest) {
if (consoleFilterRefs > 0 && typeof msg === 'string') {
// Astro passes a `class` prop to the Svelte component, which
// outputs the following warning, which we can safely filter out.
const isKnownSvelteError = msg.endsWith("was created with unknown prop 'class'");
if (isKnownSvelteError) return;
}
originalConsoleWarning(msg, ...rest);
}