Can we split node modules library on route basis?

3.3k Views Asked by At

We have website on react and done code splitting using loadable, and all webpack optimizations. One thing is concerning we are using 70 npm library and It leads to make a big vendor chunks which we splitted using splitChunks webpack.

What If we have a page which is using only 10 libraries out of 70 but webpack loads all library at once in the form of vendor-react and vendor-all, etc on chunking basis.

Is there any way to split node modules on route basis, If a page using 10 library, we load only 10 library instead of whole node_modules at once.

For example we have three pages HOME Page, PRODUCT LISTING PAGE, PRODUCT DETAIL PAGE.

And in package json We have 10 libraies installed example

"react-collapsible"
"react-cookie"
"react-datepicker"
"react-day-picker"
"react-dropdown"
"react-google-maps"
"react-helmet"
"react-id-swiper"
"react-lazy-hydration"
"react-lazyload"
"react-lazyload-img"
 "redux-actions"
"redux-connect"
"redux-form"
"redux-thunk"
"serialize-javascript"
"snake-case"
"superagent"
"superagent-logger"
"swiper" 

HOME PAGE: 3 package are needed: "react-collapsible" "react-cookie" "react-datepicker" PRODUCT LISTING PAGE 4 package needed: "react-helmet" "react-id-swiper", "react-lazy-hydration" "react-lazyload"

PRODUCT DETAIL PAGE. 4 package needed "serialize-javascript" "snake-case" "superagent" "superagent-logger"

There must be common library as vendor will load for all pages.

Now If I open Home page, only home page 3 packages and common chunk will be loaded.

PRODUCT AND DETAIL packages should not be loaded. If I open Product listing page, only 4 packages and common chunk will be loaded. Home page package should not be loaded.

1

There are 1 best solutions below

4
gwl002 On

Yes. You can use splitChunks option. Read this blog and you will have a better understanding.Route-Based Code Splitting with Loadable Components and Webpack

In fact,webpack5 has a useful default config for splitChunks.

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

Try to change the splitChunks.chunks config.

This indicates which chunks will be selected for optimization. When a string is provided, valid values are all, async, and initial. Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

Let's see some examples for different settings.

  1. set chunks to initial. Packages in main are split into a vendor.Packages in screen1 are bundled into screen1 bundle,no vendor for screen1 is created. enter image description here enter image description here

  2. set chunks to async. Sync packages are bundled into the main bundle no vendor bundle.Async packages are bundled into vendor. enter image description here enter image description here

  3. set chunks to all. Both sync and async packages are bundled into separate bundles.

enter image description here

enter image description here

I just tried this in a SPA project. For ssr, maybe more settings are required.Here is the github link webpack-codesplit-test.Hope this will be helpful.