esbuild
esbuild copied to clipboard
[Bug]: tree shaking breaks with dynamic import() in some situation
System Info
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M1 Max
Memory: 2.34 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.4.1 - ~/.volta/tools/image/node/24.4.1/bin/node
pnpm: 10.13.1 - ~/.volta/tools/image/pnpm/10.13.1/bin/pnpm
Watchman: 2025.07.28.00 - /opt/homebrew/bin/watchman
npmPackages:
esbuild: ^0.25.8 => 0.25.8
Details
If you have a file foo.ts that contains 2 exports:
// foo.ts
export const bar = 'bar';
export const paz = 'paz';
Tree shaking will work (aka the unused variable will be stripped out during compilation) when writing:
// stripped.ts
import { bar } from './foo';
But if the file is lazy loaded using import(), paz is kept in the bundle:
// kept.ts
const { bar } = await import('./foo');
import('./foo').then(module => module.bar);
import('./foo').then(({ bar }) => bar);
The config I used is a simple one:
{
"bundle": true,
"treeShaking": true,
"splitting": true,
"format": "esm",
"outdir": ".",
"write": false
}
Reproduce link
https://github.com/Ayc0/code-splitting-issue
Reproduce Steps
You can clone https://github.com/Ayc0/code-splitting-issue and run node --test tests/esbuild.test.mjs (requires node 24.4.0+)
I have the same problem that doesn't allow me to switch from webpack + babel-loader to esbuild.