evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
38.25k stars 1.16k forks source link

treeshaking generate different result from webpack #2049

Open hardfist opened 2 years ago

hardfist commented 2 years ago

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

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.

mohsen1 commented 2 years ago

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

hardfist commented 2 years ago

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

emosheeep commented 1 year ago

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 commented 1 year ago

@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.

hardfist commented 1 year ago

@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

XiSenao commented 2 weeks ago

Regarding rollup, there may be some misunderstandings. I think that rollup itself does not seem to respect the sideEffects field in package.json, ref: https://github.com/rollup/rollup/issues/2593.

If sideEffects need to take effect, there are several solutions:

  1. Set treeshake.moduleSideEffects in the rollup.config.js.
  2. Use user plugins to return the moduleSideEffects field in the load and transform hooks to provide side effects for specific modules.
  3. The official @rollup/plugin-node-resolve plugin respects the sideEffects field in package.json.