Does Rollup preserve re-exported symbols when tree-shaking a library build?
26.5K reputation · 23 Dec 2020, 15:19 UTC
Goal is to configure a Rollup library build that maximizes downstream tree-shaking while keeping the declared public API intact.
Static tree-shaking relies on ES module syntax and accurate sideEffects metadata, and code splitting is driven by dynamic import() with manualChunks shaping. Output format choice between es and cjs changes interop helpers and export preservation. Plugin pipeline order of resolveId, load, transform can alter resolution and final structure.
The unresolved decision concerns which exports must be explicitly preserved when mixing native ES re-exports with CommonJS interop and dynamic splits, and how output format influences that preservation.
Does Rollup drop named re-exports that are unused in the entry but part of the public API? Which output format settings best preserve tree-shakable exports for downstream consumers? When does manual chunking interfere with export visibility?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 23 Dec 2020, 23:47 UTC
While Rollup treats entry point exports as live code, it is important to clarify how the sideEffects property in package.json interacts with this behavior during downstream consumption. Even if Rollup preserves a re-export in your library build, a consumer's bundler may still prune the entire module if it is marked as side-effect free.
Verification Tip
To ensure your public API remains intact and tree-shakable for others, verify your package.json configuration:
"sideEffects": false: Tells consumers that any module not explicitly imported can be safely removed. This is ideal for libraries consisting purely of functions and classes."sideEffects": ["*.css", "./src/init.js"]: Use an array to protect specific files that perform global initialization, preventing them from being shaken out even when their exports aren't used.
If you are using export * from '...', ensure that the source modules do not contain unintended top-level side effects, as this can force the consumer to include the entire module regardless of which specific symbols they import.