Bundling a component library for tree-shaking
Optimizing a library so consumers ship less code.
ship ES modules, mark sideEffects false, preserve named exports, and externalize peers so consumers tree-shake and code-split.
WHAT THIS TESTS This probes whether you understand how a library author enables the consumer bundler to eliminate unused code and split it, because a poorly packaged library forces apps to ship the entire system even if they import one button.
A GOOD ANSWER COVERS Tree-shaking is dead-code elimination based on static analysis of ES module import and export statements. To enable it, the library must ship an ES module build, not only CommonJS, because CommonJS dynamic requires cannot be statically analyzed. Mark the package with sideEffects false in package.json, or list the few files that do have side effects such as global CSS imports, so the bundler may safely drop unused modules. Preserve named exports per component and avoid forcing everything through a single barrel file that imports the whole library, since that can defeat shaking. Externalize peer dependencies like React rather than bundling them. Code-splitting is the consumer-side complement: large or rarely used components can be lazily imported so they land in separate chunks loaded on demand. The library should not pre-bundle in a way that blocks this.
COMMON WRONG ANSWERS Shipping only a minified CommonJS bundle prevents tree-shaking entirely. Setting sideEffects false when CSS side-effect imports exist can strip needed styles. Bundling React into the library bloats output and risks duplicate copies. Assuming minification equals tree-shaking conflates two different steps.
LIKELY FOLLOW-UPS Why does CommonJS resist tree-shaking? What breaks if sideEffects is misconfigured with CSS? How do the exports map and module fields direct bundlers? When does a barrel file hurt? How do you measure what actually ships, for example with a bundle analyzer?
ONE CONCRETE EXAMPLE An app imports only DatePicker from acme-ui. Because the library ships ESM with sideEffects false and per-component exports, the consumer bundler drops the other fifty components, and a heavy RichTextEditor is additionally code-split behind a dynamic import so it only loads on the editor route, keeping the initial bundle small.
Read the original → webpack.js.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.