bundle size worse than preset-env with esmodules:true ?
frehner opened this issue · comments
I was looking into migrating a project that I maintain to preset-modules. However, I've noticed that the resulting bundle size is actually bigger than when I use preset-env with esmodules:true.
I'm not entirely sure that this is the fault of preset-modules, but I can't seem to figure out why it's behaving the way that it is.
To reproduce:
If you clone single-spa, checkout the 5.0 branch, yarn
install, and then run yarn build:analyze
, here’s the output (which is using preset-env with targets:{esmodules:true}
- focusing only on the esm
bundle:
./src/single-spa.js → ./lib/esm/single-spa.dev.js...
-----------------------------
Rollup File Analysis
-----------------------------
bundle size: 42.974 KB
original size: 53.199 KB
code reduction: 19.22 %
module count: 23
Then, if you yarn add -D @babel/preset-modules
, change the .babelrc
file to use @babel/preset-modules
(for the "esm" environment), and then run yarn build:analyze
again, here’s the result:
./src/single-spa.js → ./lib/esm/single-spa.dev.js...
-----------------------------
Rollup File Analysis
-----------------------------
bundle size: 45.098 KB
original size: 96.12 KB
code reduction: 53.08 %
module count: 24
If I do a comparison between the two compiled files, it appears that the size difference comes down to two things: 1)there’s an additional function added:
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
and 2) all the arrow functions were compiled back to normal function
s.
I'm not sure why either of these things are happening, especially the transpilation of arrow functions to normal functions.
this sounds like a similar problem to #3. Did you try adding the { loose: true }
flag in your config? #3 (comment)
I also don't see any reference to @babel/preset-modules
in your package.json.
this sounds like a similar problem to #3. Did you try adding the { loose: true } flag in your config? #3 (comment)
Added it: no change to file size. :(
I also don't see any reference to @babel/preset-modules in your package.json.
From my original post:
Then, if you yarn add -D @babel/preset-modules, change the .babelrc file to use @babel/preset-modules (for the "esm" environment), and then run yarn build:analyze again, here’s the result:
I finally got a minute to look at this more closely, and I realized what the problem is: you're using both @babel/preset-env
and @babel/preset-modules
. Babel overrides, such as the "esm"
one you're using, do not replace plugins
and presets
wholesale - they get merged. Since @babel/preset-env
and @babel/preset-modules
are different preset names, they are both included in the resolved configuration.
This will sort itself out once babel/babel#11083 is merged - you'll be able to simply have your "esm"
override set { "target": { "esmodules": true }, "bugfixes": true }
and it'll apply preset-modules optimizations.
I finally got a minute to look at this more closely, and I realized what the problem is: you're using both
@babel/preset-env
and@babel/preset-modules
. Babel overrides, such as the"esm"
one you're using, do not replaceplugins
andpresets
wholesale - they get merged. Since@babel/preset-env
and@babel/preset-modules
are different preset names, they are both included in the resolved configuration.This will sort itself out once babel/babel#11083 is merged - you'll be able to simply have your
"esm"
override set{ "target": { "esmodules": true }, "bugfixes": true }
and it'll apply preset-modules optimizations.
Ah, thanks, I wasn't aware that babel behaved that way.
Thank you for looking into this.
confirmed to work while using latest babel and "bugfixes": true