Define Plugin
a high level of define plugin, treeshake + minification happens in the following
for any module,
- webpack reads the source code
- apply all the loaders
- apply define plugin
- for the final code after loaders + define plugin,
- for code at
if (truthy)ortruthy && ...ortruthy ? ... : ..., webpack will try to collapse that conditional, meaning based on truthy / falsy value, remove unwanted code logic paths
- for code at
- find all the
importsorrequirein the code - traverse them and apply the same step for each module
after creating the module map
- create chunks based on dynamic import()
- apply graph based optimisation - such as mark unused exports and treeshake them away
- granular split chuks optimisation
- lastly, for each chunk
- run terser to minify the code, will remove any unused variables / functions within each chunk
which means, there's a difference between the following contrived code:
const a = __FLAG__;
if (a) {
require('foo');
} else {
require(bar');
}and
if (__FLAG__) {
require('foo');
} else {
require(bar');
}after applying new DefinePlugin({ __FLAG__: true }), you get:
const a = true;
if (a) {
require('foo');
} else {
require(bar');
}and
if (true) {
require('foo');
} else {
require(bar');
}webpack's parser is able to collapse the conditional of the latter, but not the former.
the collapse of conditional expression happens here
if (true) {
require('foo');
} else { }so, the former case, will have both foo and bar in the bundled code ,but the latter will only have foo.
What about terser?
terser runs on chunk level after all the bundling and chunking logic, so even though terser is smart enough to collapse
const a = true;
if (a) {
require('foo');
} else {
require(bar');
}into
require('foo');the bundled code still have foo and bar's code.