Skip to content
tezvyn:

How would you structure TypeScript code and exports for effective tree-shaking?

Source: webpack.js.orgMediumHow cards are made

Tests ES module semantics and sideEffects for library authors. Great answers: emit ESM, set sideEffects:false, avoid stateful barrel files, and preserve import syntax. Red flag: saying ESM alone guarantees tree-shaking without mentioning side effects.

What's really being asked

This question tests whether you understand the difference between writing application code and authoring a distributable library. Interviewers want to know if you grasp that bundlers like webpack rely on static analysis to eliminate dead code, and that TypeScript compilation settings and package metadata directly determine whether that analysis succeeds or fails. It separates candidates who merely consume libraries from those who understand module graph semantics.

The full answer

A strong answer hits four things in order. First, configure TypeScript to emit ES modules by setting module to esnext or nodenext and moduleResolution to bundler or node, which preserves static import and export syntax instead of transforming them into CommonJS require and module.exports. Second, declare sideEffects accurately in package.json, typically sideEffects false for pure utility libraries or a precise array pointing to CSS files when styles are involved, because webpack uses this field to decide whether skipping an unused file is safe. Third, avoid stateful re-exports and barrel files that execute code during import, such as initializing a singleton or mutating a prototype, since those create side effects that force bundlers to retain the entire module. Fourth, point the package exports or module field to the ESM build and avoid shipping CommonJS as the only format, because CommonJS dynamic require calls cannot be statically analyzed for tree-shaking.

The mistakes people make

The biggest red flag is claiming that simply using export const makes a library tree-shakeable. Another mistake is setting sideEffects false when the library actually contains side effects like polyfills or global CSS imports, which breaks consumer builds. Recommending tsconfig module CommonJS is also wrong because it emits require syntax that bundlers cannot statically prune. Finally, ignoring nested dependencies is a pitfall; if your library depends on a non-tree-shakeable package, your consumers inherit that bloat.

What usually comes next

An interviewer might ask how you would handle CSS imports in a component library while keeping sideEffects accurate, or how you verify tree-shaking actually works before publishing. They may also probe the difference between webpack sideEffects flag and pure module annotations in minifiers like Terser, or ask how conditional exports in package.json can serve both ESM and CJS consumers without breaking tree-shaking.

A concrete example

Imagine a date-utils library with format, parse, and addDays functions. In tsconfig.json you set module to esnext and outDir to dist. In package.json you set type to module, main to dist/index.js, and sideEffects to false. Each function lives in its own file and is re-exported from index.ts using named exports. A consumer imports only format, so webpack sees the static import, checks sideEffects is false, and drops parse and addDays entirely. If you had instead compiled to CommonJS or forgotten sideEffects, the bundler would retain all three functions.

Interview question

You are building a tree-shakeable TypeScript component library that emits ES modules, but some entry files import global CSS. What is the safest way to configure sideEffects in package.json?

  • a.Set sideEffects to an array listing only the CSS file pathsCorrect
  • b.Set sideEffects to true because any CSS import makes the entire library stateful
  • c.Omit the sideEffects field so webpack analyzes every file individually
  • d.Set sideEffects to false to ensure maximum tree-shaking
Why?

Listing only the CSS paths keeps components tree-shakeable while preserving necessary style imports. Setting sideEffects to false is tempting but would cause webpack to drop the CSS imports and break styles.

Just read this? Test yourself on what you have been reading.

Read the original → webpack.js.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on typescript — each one lists the topics its interview covers.

See open roles