963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
5.1 KiB
5.1 KiB
Tree Shaking
Remove unused code from bundles.
Overview
Tree shaking eliminates dead code (unused exports) from your final bundle, reducing size and improving performance.
Default: Enabled
Basic Usage
CLI
# Tree shaking enabled (default)
tsdown
# Disable tree shaking
tsdown --no-treeshake
Config File
export default defineConfig({
entry: ['src/index.ts'],
treeshake: true, // Default
});
How It Works
With Tree Shaking
Source:
// src/util.ts
export function unused() {
console.log("I'm unused");
}
export function hello(x: number) {
console.log('Hello World', x);
}
// src/index.ts
import { hello } from './util';
hello(1);
Output:
// dist/index.mjs
function hello(x) {
console.log('Hello World', x);
}
hello(1);
unused() function is removed because it's never imported.
Without Tree Shaking
Output:
// dist/index.mjs
function unused() {
console.log("I'm unused");
}
function hello(x) {
console.log('Hello World', x);
}
hello(1);
All code is included, even if unused.
Advanced Configuration
Enable (Default)
export default defineConfig({
treeshake: true,
});
Uses Rolldown's default tree shaking.
Custom Options
export default defineConfig({
treeshake: {
moduleSideEffects: false,
propertyReadSideEffects: false,
unknownGlobalSideEffects: false,
},
});
See Rolldown docs for all options.
Disable
export default defineConfig({
treeshake: false,
});
Side Effects
Package.json sideEffects
Declare side effects in your package:
{
"sideEffects": false
}
Or specify files with side effects:
{
"sideEffects": ["*.css", "src/polyfills.ts"]
}
Module Side Effects
export default defineConfig({
treeshake: {
moduleSideEffects: (id) => {
// Preserve side effects for polyfills
return id.includes('polyfill');
},
},
});
Common Patterns
Production Build
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
treeshake: true,
minify: true,
});
Development Build
export default defineConfig((options) => ({
entry: ['src/index.ts'],
treeshake: !options.watch, // Disable in dev
}));
Library with Side Effects
export default defineConfig({
entry: ['src/index.ts'],
treeshake: {
moduleSideEffects: (id) => {
return id.includes('.css') || id.includes('polyfill') || id.includes('side-effect');
},
},
});
Utilities Library
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
treeshake: true,
dts: true,
});
Users can import only what they need:
import { onlyWhatINeed } from 'my-utils';
Benefits
Smaller Bundles
- Only includes imported code
- Removes unused functions, classes, variables
- Reduces download size
Better Performance
- Less code to parse
- Faster execution
- Improved loading times
Cleaner Output
- No dead code in production
- Easier to debug
- Better maintainability
When to Disable
Debugging
During development to see all code:
export default defineConfig((options) => ({
treeshake: !options.watch,
}));
Side Effect Code
Code with global side effects:
// This has side effects
window.myGlobal = {};
export function setup() {
// ...
}
Disable tree shaking or mark side effects:
{
"sideEffects": true
}
Testing
Include all code for coverage:
export default defineConfig({
treeshake: false,
});
Tips
- Leave enabled for production builds
- Mark side effects in package.json
- Use with minification for best results
- Test tree shaking - verify unused code is removed
- Disable for debugging if needed
- Pure functions are easier to tree shake
Troubleshooting
Code Still Included
- Check for side effects
- Verify imports are ES modules
- Ensure code is actually unused
- Check
sideEffectsin package.json
Missing Code at Runtime
- Code has side effects but marked as none
- Set
sideEffects: trueor list specific files
Unexpected Behavior
- Module has side effects not declared
- Try disabling tree shaking to isolate issue
Examples
Pure Utility Functions
// utils.ts - perfect for tree shaking
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
// Only 'add' imported = only 'add' bundled
import { add } from './utils';
With Side Effects
// polyfill.ts - has side effects
if (!Array.prototype.at) {
Array.prototype.at = function (index) {
// polyfill implementation
};
}
export {}; // Need to export something
{
"sideEffects": ["src/polyfill.ts"]
}
Related Options
- Minification - Code compression
- Target - Syntax transformations
- Dependencies - External packages
- Output Format - Module formats