Reputation: 655
We've recently been looking at implementing code splitting into our complex web application to reduce the main bundle size. The main part that we're focussing on is dynamic imports using webpack & react-loadable.
I've come across something I deem to be quite a big problem, take this example:
const FirstChild = Loadable({
loader: () => import('some/file/path/FirstChild.jsx')
});
const SecondChild = Loadable({
loader: () => import('some/file/path/SecondChild.jsx')
});
const ParentComponent = () => (
<div>
<FirstChild />
<SecondChild />
</div>
);
where FirstChild.jsx & SecondChild.jsx both import the same service:
import MyService from 'some/file/path/my.service.js';
When bundling this with webpack, we end up with 3 files:
MyService
)MyService
)At this point I see a problem - we have duplicates of MyService
between both files. For some small apps this might not be a problem (or if the service was specifically just helper methods) but if we're using our service to store some data across the lifetime of the app, we would end up with two object references of this service, therefore defeating it's point entirely.
I understand that the service here could be moved 'top-level' to the ParentComponent
and possibly passed as a prop to each component but it seems like it destroys the architecture that webpack has in place in the first place - to be able to import whatever we need wherever we need and it creating just one reference. It also could be problematic if you have lots of nested components which all need to import various services and other components.
Obviously this example is simple but implementing this into a massive app which has a very complex architecture could immediately run us into problems.
Any thoughts on this? Thanks!
Upvotes: 2
Views: 1368
Reputation: 655
Going to answer my own question on this one.
Discovered that:
MyService.js
ends up in the output of each chunk. Webpack is clever enough to only load the first instance of MyService
that it finds and uses just one reference for that. Meaning that if FirstChild
loads MyService
first, then SecondChild
will also use the same MyService
that was loaded by FirstChild
and it's copy of MyService
will just be ignored.MyService.js
in this case might end up in a chunk like services~FirstChild/SecondChild/SecondChild.js
- which doesn't make very nice for debugging but I assume it's the way Webpack references it's imports.
optimization: {
splitChunks: {
cacheGroups: {
services: {
test: /\.service.js$/,
enforce: true
}
}
}
},
Please let me know if any of that is wrong or you find other interesting points about code splitting + webpack.
Upvotes: 1