Why we called tree shaking? -- you can imagine your application as a tree. The source code and libraries you actually use represent the green, living leaves of the tree. Dead code represents the brown, dead leaves of the tree that are consumed by autumn. In order to get rid of the dead leaves, you have to shake the tree, causing them to fall.
Tree shaking term was popularized by Rollup -- the concept of dead code elimination has existed for some time, then supported very early in Rollup module bundler and loved by community, Webpack has caught up since version 2.
Why tree shaking only works with es6 modules -- The dynamic nature of the CommonJS modules meant that tree shaking couldn’t be applied because it would be impossible to determine which modules will be needed before the code is actually run. The static syntax of ES6 modules, as any code that is used from an import can be determined without the code needing to be first run, makes possible for tree shaking.
Rollup has built-in support for tree shaking -- in addition to enabling the use of es6 modules, Rollup also statically analyzes the code you are importing, and will exclude anything that isn't actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project.
Webpack supported tree shaking since version 2 -- the webpack 2 release came with built-in support for es6 modules as well as unused module export detection. Webpack 4 release expands on this capability with a way to provide hints to the compiler via the "sideEffects" package.json property to denote which files in your project are "pure" and therefore safe to prune if unused.
What should I do to take advantage of tree shaking -- use es6 module syntax import/export, ensure no compilers transform your es6 module syntax into CommonJS modules, add a "sideEffects" property to your project's package.json file, use the production mode configuration option to enable various optimizations including minification and tree shaking.
Keeping Babel from transpiling ES6 modules to CommonJS modules -- we often use Babel to transpile our nice ES6 modules into more widely compatible CommonJS modules, this is great and all until we want to start tree shaking, webpack won't know what to prune from the bundle if you decide to use them.
Keeping side effects in mind -- one aspect to consider when shaking dependencies from your app is whether your project's modules have side effects, when a function modifies something outside of its own scope, you can tell webpack a package or files are free from side effects.
With tree shaking enabled, we expect what is imported and actually used will make it to the final bundle. However, tree shaking doesn’t eliminate all unused code and doesn’t solve the problem of unused code entirely.