-
Notifications
You must be signed in to change notification settings - Fork 662
Closed
Description
Is it possible anyhow to implement tree shaking during bundling.
Suppose I have a file say greetings.js
:
export const sayHi = (name) => {return `Jarvis says hi to ${name}`};
export const sayBye = (name) => {return `Jarvis says bye to ${name}`};
Now if in my project I am only using sayHi
then I want sayBye
to be removed from the final bundle which is currently not the case.
Is it possible anyhow to implement this (even if I had to do changes in the config file for the metro bundler).
ankit-w, maxkomarychev, phsantiago, LRNZ09, noomorph and 45 more
Activity
rafeca commentedon Aug 28, 2018
Metro currently does not support tree shaking based on module import/export. @mjesun is currently adding first-class support for Metro to understand them and this will eventually allow us to do tree shaking.
Stayed tuned! 😃
ghost commentedon Nov 14, 2018
any outcome on tree-shaking ? Looking forward to that.
karanjthakkar commentedon Nov 26, 2018
@rafeca Now that we have experimental support for import/export inside metro, is tree shaking now available out of the box or is there work going on to support it? Anything that we can help with to make this possible?
rafeca commentedon Nov 27, 2018
@karanjthakkar : we're planning to implement some sort of tree shaking (or better said, minification of code based on the es6 module information) during H1 2019.
Based on our internal tests, the most impactful minification in terms of bundle size that can be done is to minify the import/export names, so for example:
would get minified to:
Afterwards, we're going to be able to do dead code elimination based on the exported values that are not being used anywhere
camdagr8 commentedon Mar 22, 2019
Any movement or resolution on this?
aleclarson commentedon May 1, 2019
Is this still slated for H1 2019?
sunnylqm commentedon May 18, 2019
Jeevan-Kishore commentedon Aug 8, 2019
Is it supported yet?
12 remaining items
matthew-dean commentedon Nov 18, 2022
It's disappointing that Facebook's position is essentially, "bundling the entire import probably won't that much bloat, or add that much performance degradation to your app".
True (maybe), but why not just... not add things that aren't needed? Tree-shaking is an expected feature of any JS bundler, and not having tree shaking violates the Law of Least Surprise. If we use 1 function in, say, a giant hooks library with 1,000 hooks, we expect only that 1 function to show up in our app. If Metro can't provide this, then IMO Metro should not be in the business of bundling and should pair with Vite, Webpack, or other such bundlers to find a solution for React Native devs.
adnaan1703 commentedon Nov 19, 2022
Totally agree. The smaller bundle can still be valid even though we performed compression and backed it with Hermes. Currently, we are sending the bundle over HTTP with brotli compression and the underlying engine is Hermes for better performance but that doesn't rule out the use case for tree shaking. Also, I believe folks here undermine the improvement one can get with tree shaking.
When I raised this issue, Haul (predecessor of repack) solved this issue by using webpack. At that time we saw an improvement of around ~49.64% of bundle size.
Bundle size improvement: haul w/ tree shaking vs metro -> 49.64% gain.
*This was 2018.
We couldn't go to production with Haul because of a lack of community support and also the bundle it spits breaks our internal system. Our internal diffing logic would have needed overall changes. Also, using scripts to change haste-dependent libraries dynamically seems kind of a hack and is a bit dangerous to send in production.
But now I think we have multiple solutions out there:
Since these tools are now available, it is bound that users with advanced bundling needs will move away from Metro.
kelset commentedon Nov 21, 2022
btw for those of you using Metro and wanting tree shaking, over at MSFT we have developed a plugin for Metro to basically rely on esbuild for treeshaking: https://github.com/microsoft/rnx-kit/tree/main/packages/metro-serializer-esbuild (guide here: https://microsoft.github.io/rnx-kit/docs/guides/bundling#tree-shaking)
We already use it in prod on a couple projects and saw good bundle size improvements
mannoeu commentedon Jul 26, 2023
Too bad... Ignoring real cases where Tree Shaking is necessary
johnculviner commentedon Jun 19, 2024
Facebook went ahead and wrote their own JavaScript engine (hermes) to try to optimize startup behavior and in my own testing simply having less JavaScript goes a long way in improving startup performance... and dare I say is a lot simpler than writing your own JS engine from scratch 🤯
EvanBacon commentedon Aug 23, 2024
Went ahead and wrote a version of tree shaking in Expo CLI to get the ball rolling. It can be added to any React Native project by adopting
expo/metro-config
,babel-preset-expo
, and Expo CLI (requires E2E bundler integration).The implementation is landed on main and it'll ship experimentally in SDK 52 (October 2024). Here are the docs: Tree Shaking in Expo CLI
aleksamrakovic commentedon Oct 15, 2024
Any way to remove .git folder from bundle? Is there any reason why metro do that?
trip8971 commentedon May 12, 2025
Run a webpack bundle command before the metro bundler's work to achieve the tree-shaking effect. It's worthing noting that you should config webpack external properly.
You can have a try.
BoBoooooo commentedon Jun 20, 2025
It’s 2025 now. Unfortunately, there is still no metro treeShaking solution. ESBuild & Webpack support treeShaking, but the bundle split solution is different from metro. It’s a one-track mindset. My existing environment is strongly dependent on the Metro ecosystem, and migrating to other bundle solutions will have a high cost. So an official Metro(bundle split) + treeShaking ecosystem is very urgent needed !