Open matt-kinton opened 2 years ago
Hi @Mattinton, this is really interesting, thanks for the repros.
My first thought was that maybe we were accidentally only exporting the .cjs build of ReactFire, but we do have the module
field in our package.json, so I don't think that's it. Will keep investigating.
I wonder if it's because our package.json is missing the exports
field. react-scripts, which is bundling your examples, uses webpack, and it looks like webpack expects the exports
field. I'm not sure if it looks at the module
field. The webpack docs say:
exports
field is preferred over other package entry fields likemain
,module
,browser
or custom ones.
Related TSDX issue (ReactFire uses TSDX for the build): https://github.com/jaredpalmer/tsdx/issues/298#issuecomment-786771416
update: I pulled https://codesandbox.io/s/elegant-roentgen-2iyt8?file=/src/App.tsx down locally, npm installed, then modified ReactFire's package.json in the node_modules folder to have an exports
field. Then built and checked the bundle. Doesn't seem to have made a difference.
It seems that just using FirebaseAppProvider
(without any call at all to import or lazy import Firestore) is enough to pull Firestore and Storage into the bundle 😬 🤯
I'm not sure why, because FirebaseAppProvider doesn't import either of those. It only imports the following:
When I try to just import getApps, initializeApp, registerVersion
directly in an app (without importing FirebaseAppProvider
), Firestore and Storage are NOT included in the build, so it doesn't appear to be a bug in the Firebase JS SDK itself.
I think it has something to do with our build.
UPDATE: After investigating more, I didn't have tree shaking properly enabled in my tests for my comment above. Once I got tree shaking set up, the extra stuff was dropped from my bundle
I did fork the repo and play around with it myself and also had no luck. I did notice that importing performance lazily didn't add to the overall package size and worked as expected. What are the differences between performance and firestore/storage?
Hey @jhuleatt did you ever make any progress on this? Cheers
Hey there, got the same issue, I just pulled all my hairs out my head to know what libraries was causing this.
finally I just did a little hack with the webpack config by using https://webpack.js.org/configuration/externals/
config.externals = { 'firebase/database': 'root Math', };
this hack force remove the firebase/database dependency out of the bundle. why putting Math ? because webpack will add a small line in the bundle : "e.exports=math", so I used a builtin package to export to not crash the whole app
When using Next.js, every module in Firebase appears to be bundled: https://github.com/FirebaseExtended/reactfire/issues/489#issuecomment-1249173518
When using ReactFire I want to lazy load Firestore to reduce build initial build size and improve load times. When using ReactFire lazy loading firestore does not happen even while using
import('firebase/firestore')
.I have included a version that does not use ReactFire with working lazy loading as shown by the initialisation time. I have also included a version that does use ReactFire where I am trying to use lazy loading but I believe it is not working.
I noticed this in a Nextjs project with the bundle analyzer but haven't included Nextjs in the examples for simplicity.
Version info
React: 17.02
Firebase: 9.4.1
ReactFire: 4.2.1
Test case
Test case without using ReactFire and lazy loading working: https://codesandbox.io/s/blissful-scott-05qj6?file=/src/App.tsx https://csb-9c5hc.netlify.app/
Test case with using ReactFire and lazy loading not working: https://codesandbox.io/s/elegant-roentgen-2iyt8?file=/src/App.tsx https://csb-2iyt8.netlify.app/
You can use the network tab to see that 6 networks requests are made without ReactFire but only 5 are made with using it, you can also see the breakdown of chunks in the lighthouse analysis.
Lighthouse Treemap without ReactFire Lighthouse Treemap with ReactFire
This is quite a big blocker for me so any help would be appreciated.
Steps to reproduce
Open the two codesandbox's/netlify deployments above.
Expected behavior
Firestore is loaded in a separate chunk.
Actual behavior
Firestore is loaded in the initial chunk.