Webpack-2 recursive tree-shaking/dead code elimination.
See original GitHub issueHello, i’ve been trying out webpack@2.0.7-beta
and noticed that webpack doesn’t eliminate dead code recursively. Let me show you an example:
import { otherFunc1, otherFunc2 } from './otherModule';
function callOther() {
otherFunc1();
otherFunc2();
}
export default function () {
if (process.env.NODE_ENV !== 'production') {
callOther();
}
}
Let’s say process.env.NODE_ENV === 'production'
, so the condition is always false
.
- I would expect the whole
if
block in default function to be stripped out. - So
callOther
would get stripped out. - So
otherFunc1
andotherFunc2
would get stripped out(they aren’t used anywhere else).
Webpack does steps 1
and 2
, but skips step 3
, so otherFunc1
and otherFunc2
end up in the bundle anyway.
If i call otherFunc1
and otherFunc2
directly inside the if
block, they don’t end up in the bundle.
My webpack.config.js
:
'use strict';
var webpack = require('webpack');
var env = process.env.NODE_ENV;
var config = {
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
]
},
output: {
library: 'bundle',
libraryTarget: 'umd'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env)
})
]
};
module.exports = config;
My .babelrc
:
{
"plugins": [
["transform-es2015-template-literals", { "loose": true }],
"transform-es2015-arrow-functions",
"transform-es2015-shorthand-properties",
["transform-es2015-computed-properties", { "loose": true }],
"check-es2015-constants",
["transform-es2015-spread", { "loose": true }],
"transform-es2015-parameters",
["transform-es2015-destructuring", { "loose": true }],
"transform-es2015-block-scoping",
"transform-object-rest-spread",
]
}
And i call webpack
with:
cross-env NODE_ENV=production webpack -p src/index.js dist/bundle.min.js"
Thanks!
Issue Analytics
- State:
- Created 8 years ago
- Comments:11 (3 by maintainers)
Top Results From Across the Web
Tree Shaking - webpack
Tree Shaking. Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of...
Read more >How Tree-shaking in JavaScript Bundlers work
Tree shaking is a technique used in dead code elimination which aims to reduce bundle size by removing unused functions, imports and statements...
Read more >Tree shaking and code splitting in webpack - LogRocket Blog
Tree shaking, also known as dead code elimination, is the practice of removing unused code in your production build.
Read more >Does Webpack tree shaking with dead code elimination work ...
I was expecting that tree shaking alongside with dead code elimination of UglifyJS should work in a way that enables me to write...
Read more >How to make your library tree-shakable - Level Up Coding
Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. Although many bundlers nowadays support tree-shaking like Rollup ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@le0nik I think I know why this happens.
As I understand it, webpack does dead code elimination in two steps. First it figures out which exports are being referenced, and it writes the chunk’s code, only assigning exports to the
exports
object if they’re “used” somewhere. Then it passes that code to UglifyJS, which removes dead code.Numbers 1 and 2 are handled by UglifyJS. Number 3 is handled by webpack. However, since webpack is doing its part before UglifyJS, it doesn’t know it can remove those functions.
I think you’re just getting lucky here because webpack ignores code inside false conditionals. It doesn’t, however, remove that code; it waits for Uglify to take care of that.
It does. Webpack can mark unused imports/exports, (see usedExports property on HarmonyExportSpecifierDependency (I believe)), however it’s simply marking the statements and specifiers. Is it possible, maybe, but would be extremely complex and time consuming. We believe that a generic tool should be passed an AST program, to assist in analyzing and optimizing (and used/implemented in Webpack similar to UglifyJsPlugin) that any bundler etc can use. (Like babili, but more than just ES6 I think)
We’d love to have help from Flow, TS, babili, esprima, acorn, uglify, whatever, and framework teams to make one unifying tool to that can provide a High Level general purpose static program flow analysis optimizer/minifier. I know each library, parser has separate needs, but I think there could be a high-level approach at some of this, and benefits everyone.
/cc @hzoo @gaearon @danielrosenwasser @wycats @igorminar @Rich-Harris @aryia
My super super high level thoughts:
Tool takes ES6(or mixed commonjs, etc whatever is possible)AST/Program, tool does optimization, returns either optimized AST Program for respective parsers/compilers/etc to use.