Closed MangelMaxime closed 1 year ago
Looking at the stats it seems that big.js > Decimal.js is being imported by Reflection while Long.js is being imported by Date.js and Feliz/Interop.js. There are a couple of methods in Date.js that use long (to create dates from ticks or milliseconds) but they don't seem to be used by Feliz/Interop.js.
IIRC a similar thing was observed in the past: when a file was included all dependencies of that file were included too even if they were not used. I think we fixed it for Webpack by adding "sideEffects": false
to package.json within fable-library (see this), but maybe this doesn't work the same for Vite/Rollup? It would be interesting to compare the results with Webpack.
The equality operator (or other comparison constructs) can trigger this sometimes as well, because the equals
function from Utils.ts
depends on a bunch of other things.
Does your bundler have something to view the dependency graph? Then we could track this down.
The bundler I am using is Vite which use rollup behind the hood.
I found this plugin https://www.npmjs.com/package/rollup-plugin-visualizer that I used to make the charts / stats from above.
Can you generate one of the other artifacts? The "Network" option looks like it's what's we're looking for.
@MangelMaxime It'd be nice if you could make a bundle with Webpack and see if the results are different. If Webpack manages to remove big.js
and long.js
dependencies maybe we can assume it's Rollup not understanding "sideEffects": false
. In that case, we can consider putting the methods that require Decimal and Long in different files so we're sure the dependencies aren't activated unless those specific methods are called.
Oops, I though I had provided a reproduction code for this issue but I think I made the Gitpod template and stopped here 🤣
I will, provide a reproduction code so we can apply any bundler to the project for reproduction purpose.
Here is a reproduction repository https://github.com/MangelMaxime/fable-2907-reproduction
Both Vite and Webpack are setup with a plugin visualize. You can run ./build.sh BuildVite
or ./build.sh BuildWebpack
depending on which one you want to observe.
Thanks a lot @MangelMaxime! I modified a bit your example to use webpack-bundle-analyzer which works a bit better and split the code from node_modules (basically react in this case) into a separate chunk. I also modified a bit the code to make sure the bundle contained code from Date module to see if this also brought Long.js in. Webpack generated an app.js bundle of 3.66KB (non-gzipped) which means tree shaking is working pretty well as it's removing all the stuff that's not necessary for that minimal app.
It looks like Webpack still has better bundle optimization capabilities than Vite/Rollup after all.
Description
The problem described in this issue occured for me when using React.useState from Feliz but I think this is related to Fable internals that's why I open the issue here. If needed, we can move it to Feliz.
I have a an empty React app consisting in:
When building it for production using Vite, I see that
big.js
andlong.js
are included in the bundle and impact it by "a lot".stats_with_long_big.zip
If I remove the line:
then
big.js
andlong.js
are not more included.stats_without_long_big.zip
Related information