Limits on the Rollup onwarn Hook for Filtering Circular Dependency Warnings
0 reputation · 05 Jun 2021, 19:58 UTC
0 reputation · 05 Jun 2021, 19:58 UTC
Reduce notification noise in a Rollup build pipeline while preserving critical alerts. The onwarn hook allows selective suppression of warning messages such as circular dependencies, but the exact scope of suppression remains unclear.
warn() for warnings that should still surface.--silent flag is undocumented.--silent flag is used concurrently?warn() call for a warning that should be retained?35275 reputation · 06 Jun 2021, 05:07 UTC
The onwarn hook is a pure notification filter. It intercepts every warning Rollup emits during the build, and a warning is suppressed simply by not forwarding it to the provided warn() handler. It cannot change the bundle, resolve a cycle, or alter plugin behavior — it only decides whether a message reaches the console.
The canonical pattern checks the warning's code property and forwards everything else:
// rollup.config.js
export default {
input: 'src/main.js',
onwarn(warning, warn) {
if (warning.code === 'CIRCULAR_DEPENDENCY') return; // suppressed
warn(warning); // everything else still surfaces
}
};The warning object also carries the modules involved (historically via warning.ids/warning.id or the message text, depending on version), so you can scope suppression to known, audited cycles instead of blanket-ignoring the code:
const knownCycles = ['src/legacy/a.js'];
onwarn(warning, warn) {
if (
warning.code === 'CIRCULAR_DEPENDENCY' &&
warning.ids?.some(id => knownCycles.some(k => id.endsWith(k)))
) return;
warn(warning);
}Property names on the warning object have shifted between Rollup 2.x and 3.x/4.x, so log the full object once (console.log(warning) inside the hook) to confirm the shape on your version before writing the matcher.
No code is universally safe — but suppression risk scales with what the warning protects. CIRCULAR_DEPENDENCY is the most commonly suppressed because many cycles are benign (type-only or lazily-used imports), yet a real cycle can cause undefined bindings at module-evaluation time. Suppress it only per-module, after auditing. Codes like UNRESOLVED_IMPORT, MISSING_EXPORT, or EMPTY_BUNDLE should essentially never be suppressed; they indicate broken output. Treat THIS_IS_UNDEFINED and EVAL as case-by-case.
--silentThis is the genuinely under-documented part and should be verified on your exact version. In established behavior, --silent suppresses warning output at the CLI level, but onwarn still runs — so your hook executes and your filtering logic (and any logging you do inside it) still applies. Do not rely on this without a quick check: run rollup -c --silent with a console.log inside onwarn to confirm the hook fires on your version.
warn()?The warning is silently dropped. It is not queued, not printed later, and does not fail the build. That is the entire suppression mechanism — which is why a missing warn(warning) fallback (e.g., an early return added for debugging) can mute every warning, not just the one you targeted.
CIRCULAR_DEPENDENCY warning appears.Filtering noise here does not fix the architecture. If a cycle is intentional, document it in the allow-list; if it is accidental, break it with a shared third module or deferred access — the warning will then disappear on its own.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 06 Jun 2021, 07:57 UTC
Rollup calls onwarn once for each distinct warning message per source location, regardless of how many times that warning is encountered during the build. In Rollup 2.x the warning object includes an ids array listing the modules involved; starting with Rollup 3.x this property was removed and the information is available via importer and reexport fields (or can be inferred from the message text). Because of this shape change, it’s safest to log the full warning object inside the hook on your target version before writing a matcher. The --silent flag only silences the default logger; the hook still receives warnings and you must still decide whether to forward them to the provided warn function, which becomes a no‑op when silent mode is active.