tech4GT
tech4GT

Reputation: 139

Combining 2 or more dynamic imports into one chunk for webpack

I am code splitting a react-webpack application based on which route is loaded in the browserRouter. Now I want to package 2 or more dynamic imports into one chunk. For example I have a route /A which renders the A Dashboard and another /A/{id} which shows the details view for a single item. Since, when my users navigate to the dashboard, there is a high possibility that they would also open the details view for some item, I want to package both the dynamically imported components in the same chunk. Is this possible?

let aDetails: any;
let aDashboard: any;


const [isLoadedADashboard, setIsLoadedADashboard] = useState<boolean>(false);
const [isLoadedADetails, setIsLoadedADetails] = useState<boolean>(false);


return (
<BrowserRouter>
 <Route
    exact
    path="/A"
    render={(props) => {
        import('../A/Dashboard').then((mod) => {
            aDashboard = mod.default;
            setLoadedADashboard(true);
        });
        return loadedADashboard ? (
            <aDashboard />
        ) : <div />;
    }}
 />
 <Route
    exact
    path="/A/{id}"
    render={(props) => {
        import('../A/Details').then((mod) => {
            aDetails = mod.default;
            setLoadedADetails(true);
        });
        return loadedADetails ? (
            <aDetails />
        ) : <div />;
    }}
 />
</BrowserRouter>
);

Upvotes: 1

Views: 1614

Answers (2)

Indragith
Indragith

Reputation: 1310

You can try using webpack magic comments inside the dynamic imports. For both the dynamic imports use the same webpackChunkName to ensure that both the files are bundled under same chunk.

import(/* webpackChunkName: 'dashboard' */'../A/Dashboard').then((mod) => {
  aDashboard = mod.default;
  setLoadedADashboard(true);
});
import(/* webpackChunkName: 'dashboard' */'../A/Details').then((mod) => {
  aDetails = mod.default;
  setLoadedADetails(true);
});

Note: we are using the same chunk name for both the imports.

Upvotes: 3

Ken Bekov
Ken Bekov

Reputation: 14015

Create proxy-module which includes both modules you need to be in one chunk:

import Dashboard from 'Dashboard';
import Details from 'Details';

export {Dashboard, Details};

Now let say the name of the module above is 'Proxy' (just for example) and it's located in the same directory as your modules. You can load it dynamically:

 <Route
    exact
    path="/A"
    render={(props) => {
        import('../A/Proxy').then((mod) => {
            aDashboard = mod.Dashboard;
            setLoadedADashboard(true);
        });
        return loadedADashboard ? (
            <aDashboard />
        ) : <div />;
    }}
 />
 <Route
    exact
    path="/A/{id}"
    render={(props) => {
        import('../A/Proxy').then((mod) => {
            aDetails = mod.Details;
            setLoadedADetails(true);
        });
        return loadedADetails ? (
            <aDetails />
        ) : <div />;
    }}
 />

Upvotes: 0

Related Questions