Diagnosing Rollup Build Failures and Bloated Bundles: A Systematic Checklist
A systematic diagnostic sequence for Rollup's three most common failures: unresolved modules, missing exports, and unexpected bundle bloat — with fixes tied to each finding.
27 Sept 2025, 13:39 UTC

Your Rollup build either fails with Could not resolve './utils', warns about missing exports, or produces a bundle that doubled in size after you added one dependency. These three symptoms share a root cause family: module resolution, tree-shaking, or plugin configuration. This guide walks through a diagnostic sequence that isolates which one you're hitting, then ties each fix to the finding that justifies it.
Recognizing the condition
Three patterns account for most Rollup support questions:
- Resolution failure: the build exits with
Error: Could not resolve '...' from src/.... The bundler cannot find the module on disk. - Missing export warning:
'foo' is not exported by node_modules/bar/index.js. Common with CommonJS packages that Rollup is reading as ESM. - Size anomaly: bundle grows far more than the dependency you added should cost, or tree-shaking appears to do nothing.
Cause map
| Condition | Likely causes |
|---|---|
| Could not resolve | Missing @rollup/plugin-node-resolve; plugin ordered after another plugin that transforms imports; path typo; importing a Node builtin in a browser build |
| Missing export | CommonJS dependency without @rollup/plugin-commonjs; circular dependency; output.exports mismatch |
| Oversized bundle | Dependency has side effects that defeat tree-shaking; treeshake: false somewhere; duplicate copies of a package; a plugin (JSON, replace) injecting code |
Ordered checks
Run these in order; each check is cheap and rules out a whole cause family.
1. Confirm entry, format, and plugin presence
Open rollup.config.js and verify the entry path actually exists and the output format matches your target (es for browsers/modern tooling, cjs for Node consumers). Then check that any bare import like import _ from 'lodash' is backed by both plugins, in this order:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: { file: 'dist/bundle.js', format: 'es' },
plugins: [resolve(), commonjs()]
};
Plugin order matters: node-resolve must locate the package before commonjs converts it. Swapping them is a frequent cause of resolution errors that look like missing files.
2. Read the warnings, not just the errors
Run the build from your project root (no special permissions needed):
npx rollup -c rollup.config.js
Rollup prints Unresolved dependency and Missing export as warnings before failing. If you see treating it as an external dependency, Rollup silently excluded a module — that is your resolution bug wearing a warning costume. Add the named package to the plugin path or fix the import.
3. Audit the external list
Anything in external: [...] is excluded from the bundle and expected to exist at runtime. Externalizing path or fs in a browser bundle produces a build that passes and a runtime that crashes. For browser output, only externalize things the page actually provides (e.g., a global library loaded via script tag, paired with output.globals).
4. Test tree-shaking behavior
If size is the problem, check whether the dependency ships ES modules with a module field and a sideEffects declaration in its package.json. Tree-shaking only works on ESM; a CommonJS-only package gets bundled whole. Also check your own config for treeshake: false or a plugin that injects code — @rollup/plugin-json and string-replacement plugins can mark modules as having side effects. You can force-check with:
// rollup.config.js
export default {
// ...
treeshake: { moduleSideEffects: false } // diagnostic only
};
If the bundle shrinks dramatically with moduleSideEffects: false, some module's side effects were keeping dead code alive. Do not ship this setting blindly — it can break CSS imports and polyfills that rely on being executed for effect.
5. Isolate with a minimal repro
Create a scratch directory with one entry file importing only the suspect package, and a bare config:
mkdir rollup-repro && cd rollup-repro
npm init -y
npm install rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs lodash-es
If the minimal build resolves and tree-shakes correctly, the problem is in your project config, not the dependency. Diff the two configs. If the minimal build fails identically, you've found a genuine compatibility issue.
Fixes tied to findings
- Resolution failure, plugin missing: install and add
@rollup/plugin-node-resolve(and@rollup/plugin-commonjsfor CJS deps), resolve first. - Missing export from a CJS package:
commonjs()usually fixes it; for stubborn packages, use named-export detection via the plugin'snamedExportsoption (older plugin versions) or import the default and destructure. - Circular dependency warnings: restructure the modules, or switch one side to a dynamic
import()so the cycle breaks at load time. - Bloat from a CJS-only library: replace it with an ESM alternative (e.g.,
lodash-esinstead oflodash) and import named bindings only. - Duplicate package copies: check
npm ls <package>; dedupe with lockfile cleanup orresolve()'sdedupeoption.
Version caveat
Tree-shaking defaults and plugin APIs changed between Rollup 2.x and 3.x, and again in 4.x (which moved to a new parser). Match plugin major versions to your Rollup major version — @rollup/plugin-node-resolve for Rollup 4 expects Rollup 4 as a peer. A version mismatch produces exactly the confusing resolution and export errors above.
Verifying the fix
After each change, rebuild and compare dist output size (ls -la dist/), confirm warnings are gone, and — critically — run the bundle. A tree-shaken build that drops code you actually need passes the build and fails in the browser. Load the page or run the Node entry and exercise the feature that uses the new dependency before calling it done.
When to escalate
Escalate to a bug report when: the minimal repro fails on the latest compatible Rollup/plugin versions; warnings contradict documented behavior; or a fix works on one major version but not another. Include the repro repo, your config, and exact versions — the Rollup issue tracker asks for all three, and reports without a repro rarely get traction.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.