webpack
webpack copied to clipboard
Webpack doesn't split third party library code between bundles
Bug report
What is the current behavior? The code splitting, using Webpack with Loadable plugin, doesn’t split the code to the correct bundle. It happens when both bundles use the same third party library, but each one imports a different code from that library. The actual result is that the main bundle includes both of the imported codes from the third party library.
For example, using React:
This is the entry point of webpack: index.js
import { Component1 } from 'third-party-components-library';
import * as React from 'react';
import loadable from '@loadable/component';
export const MainComponent = () => {
const LoadableComponent = loadable(() => import('./LoadableComponent'));
return (
<Component1>
<LoadableComponent />
</Component1>
);
};
This is the loadable component: LoadableComponent.js
import { Component2 } from 'third-party-components-library';
import * as React from 'react';
const LoadableComponent = () => {
return (
<Component2/>
);
};
export default LoadableComponent;
Two separated bundles are created: First for index.js, which is the webpack entry point, and the second for LoadableComponent.js. The first one includes both codes for Component1 and Component2 from ‘third-party-components-library’. The second one doesn’t include any code from ‘third-party-components-library’.
If the current behavior is a bug, please provide the steps to reproduce. Use the loadable-components library via its webpack plugin: https://loadable-components.com/docs/getting-started/ https://loadable-components.com/docs/api-loadable-webpack-plugin/ The main bundle, which is the bundle that is created from the webpack entrypoint, should import a component from a third party library. The main bundle should include a loadable-component. The loadable-component should import a different component from the same third party library.
What is the expected behavior? The expected behavior is that webpack will split the code between the main bundle and the loadable bundle in a way that each bundle includes only the relevant code from the third party library. In the context of the previous example: The main bundle (for index.js entry point) should include only the code for Component1 from 'third-party-components-library' and the second bundle (for LoadableComponent.js) should include only the code for Component2 from 'third-party-components-library'.
Other relevant information: webpack version: 5.0.0 Node.js version: 12.18.0 Operating System: Additional tools:
Please open an issue in @loadable/webpack-plugin, if you need help please provide reproducible test repo
That's a webpack thing, but we don't support that (yet). And probably won't support it in near future.
It's only working if each piece is in an separate file and the main file reexports them and is flagged as side effect free.
if theres a static import, then webpack needs to provide it upfront as part of the main bundle since some pages might need it.
@sokra - I believe I'm having a similar issue (using regular dynamic import(), not loadable-components) after upgrading from 4.x to 5.x - it worked as expected in 4.x. As a result the main bundle size of our app will increase dramatically in 5.x.
It's only working if each piece is in an separate file and the main file reexports them and is flagged as side effect free.
The 3rd party package includes "sideEffects": "false" and the components are all in separate files. Maybe I'm misunderstanding your comment?
This issue had no activity for at least three months.
It's subject to automatic issue closing if there is no activity in the next 15 days.
@sokra Any idea what change from v4-v5 could cause this? This is blocking my team from upgrading to v5.
Update: I investigated some more and traced it to a 3rd party package re-exporting a different 3rd party package, i.e.
// third-party-package-a index.ts
export * from 'third-party-package-b';
which leads to this bailout:
ModuleConcatenation bailout: List of module exports is dynamic
After locally replacing the star export with the explicit named exports, the issue is resolved.
Can you show third-party-package-b export?
Bump - we still should address this it not already
Should work with webpack@5. Feel free to report new issue with reproducible repo.
take a look into runtime feature
Still valid
@alexander-akait I actually don't understand what is an issue? original issue fixed in webpack@5
@vankop Can you provide link on PR?
@alexander-akait did not find MR. here is demo https://github.com/vankop/webpack-runtime/tree/main/dist 2 separate chunks in output with different tree shaking
@vankop Try to use original code from the issue
Related https://github.com/webpack/webpack/issues/7782, small example https://github.com/webpack/webpack/issues/7782#issuecomment-407694117 and bundle, we can move this code to shared chunk, but keep them both in each chunk
from issue text:
What is the expected behavior?
The expected behavior is that webpack will split the code between the main bundle
and the loadable bundle in a way that each bundle includes only the relevant code from the third party library.
As I said this is possible within different runtimes
If you have one runtime, webpack can not do this, because one module can be executed once
I don't see how runtime fix this problem
Issue was closed because of inactivity.
If you think this is still a valid issue, please file a new issue with additional information.