esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

treeshaking generate different result from webpack

Open hardfist opened this issue 3 years ago • 2 comments
trafficstars

webpack has a nice feature,when set sideEffects to false, if a import x from b, and x comes from b's reexport from c, then bundler could shake whole side effect in b

  • index.js
import { internal } from './lib'
console.log('outer',internal);
  • lib.js
export const answer = 42;
export const secret = 10;
console.log('lib'); // because internal comes from reexport other than lib.js, so this side effect could be shaked
export { internal } from './reexport';
  • reexport.js
console.log('internal');
export const internal = 100;

different bundler result are shown, and you can see webpack tree shake the lib.js side effect, but esbuild and rollup does not, https://github.com/hardfist/treeshaking-demo

  • rollup image

  • esbuild image

  • webpack image

This feature is documented here https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects image

and vue change sideEffects to true to avoid shaking sideEffects https://github.com/vuejs/core/issues/1263, so I'm wondering whether esbuild could align with webpack or webpack's behavior is not right.

hardfist avatar Feb 24 '22 03:02 hardfist

To me, what Webpack does is strange. The lib.js side effect seems desired from the source code.

mohsen1 avatar Apr 05 '22 17:04 mohsen1

since no spec about tree shaking, I don't know which is right

hardfist avatar Jun 05 '22 13:06 hardfist

Same problem here

Component library directory structure

// package.json
{
  "sideEffects": [
    "**/*.css"
  ]
}
// index.js
import Drawer from './components/drawer/index.js';
......
export { Drawer, .... }

// components/drawer/inde.js
import './style.css'; // This file would be shaked wrongly!
export * from './drawer.js';
export { default } from './drawer.js';

Usage in my project

I used vite(based on rollup or esbuild) to build my project with the following entry:

// src/main.js
import { Drawer } from 'my-lib'
...

And I found that tree-shaking eliminated my css files that I had listed in sideEffects field, which confused me. But when I tried to change the following line

export { default } from './drawer.js';

into the below:

import drawer from './drawer.js';
export default drawer;

Everything works well, I guess that may be a BUG with rollup or esbuild.

emosheeep avatar Dec 21 '22 13:12 emosheeep

@hardfist But when at development with vite, I didn't get this problem, it only occurred at build time, so I preferred to think of this as rollup's BUG not esbuild.

emosheeep avatar Dec 21 '22 14:12 emosheeep

@hardfist But when at development with vite, I didn't get this problem, it only occurred at build time, so I preferred to think of this as rollup's BUG not esbuild.

you need to provide minimal demo using esbuild | rollup directly

hardfist avatar Dec 22 '22 05:12 hardfist