Vite: How to bundle / group chunks together
Tags: vite, rollup, javascript, config
Published: 2024-06-14 08:28:51

If you use a library like Svelte or Vue you might have noticed that Vite and Rollupjs create tons of tiny js files - in my case causing the browser to have to download 72 js files for one web page - some files being less then 1kb.

There is a way to group chunks in your vite.config, its manual but it can help you.

**First a screenshot of the problem:**
_Every function or component in my codebase ends up being its own chunk, even commonly use ones_
![vite rollup tiny chunks bloat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ijun1telmbzqcnc30oi.png)

I want to group some of my imports or modules in my codebase into one chunk to reduce the amount of files / script tags vite and rollup create. Here is an example of the vite config on how to achieve this:
```typescript
// vite.config.ts

// modules I want to group (by file path)
const group_chunks = [
  "src/constants.ts",
  
  "src/lib/utils/util_fetch.ts",
  "src/lib/utils/util_date_get_time.ts",
  "src/lib/utils/util_price_to_rands.ts",
  "src/lib/utils/util_date_to_friendly_date.ts",
  
  "flowbite-svelte/dist/typography/A.svelte",
  "flowbite-svelte/dist/typography/Button.svelte",
  "flowbite-svelte/dist/toast/Toast.svelte",
  
  "svelte-hero-icons/dist/Icon.svelte",
  
  "src/lib/components/logo.svelte",
  "src/lib/components/form/input.svelte",
  "src/lib/components/form/field.svelte",
  "src/lib/components/clickToCopy.svelte",
  "src/lib/components/header/header.svelte",
  "src/lib/components/general/loader.svelte",
]


export default defineConfig({
  // ...other config stuff

  // how to group chunks
  build: {
    rollupOptions: {
      output: {
        manualChunks: (id) => {
          const is_group_chunk = group_chunks.some(partialPath => id.includes(partialPath));
          
          if (is_group_chunk) {
            return "general" // this will create a chunk called general
          }
        },
      },
    },
  },
});
```

This reduces all those chunks into one chunk called general:
![vite grouped chunk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfaptnlkmkxbnfkm3pjq.png)

## Result
In this case i have reduced 15 trips to the server down to 1. This is especially helpful on mobile when my burger menu was taking a long time to become functional because its script was loading last because rollup didnt know its importance - now that its in the general chunk, it loads in faster.

## Lighthouse Score
In terms of lighthouse the performance is around the same although i am now getting a warning about unused javascript in my general file I am happy to suffer that warning considering the users experience has improved.

## Automate
You could put all common assets in a common folder and update the vite config to see if the file is in that folder and automatically add it to a grouped chunk. Minor tweak to the code.

If you are really smart you could make a plugin that allows you to add comments to your imports that tells vite what chunk to group that import into - this is how webpack used to work.

Example of how webpack allowed chunk naming in code:
```js
const Login = import( /* webpackChunkName: "login" */ '../views/LoginView.vue'),
```

Thats it,
I hope this helped and good luck