Time to say goodbye to Webpack?
Tags: webdev, javascript, react, webpack
Published: 2022-01-13 09:50:25

Before we answer the big question, lets look at why we are even considering it.

If you look at bestofJS data for 2021, you would see that the rising star in the build tools category is `Vite`, leaving `Webpack` far behind in terms of popularity.
Check out more stats here:
[2021 JavaScript Rising Stars](https://risingstars.js.org/2021/en#section-build)

![Popular build tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/trt3d86jztveuw01blup.png)

## Lets have a closer look at `Vite` 

> Vite (French word for "quick", pronounced /vit/, like "veet") is a build tool that aims to provide a faster and leaner `development` experience for modern web projects.

Please note the emphasis on `development`. `Vite` does not promise a multifold optimization or better production experience. So don't expect your production build to be optimized or any drastic reduction in the bundle size you generate.

### So what does `Vite` do to make the development experience better?

It consists of two major parts:

- A dev server that provides rich feature enhancements over native ES modules, for example extremely fast Hot Module Replacement (HMR).

- A build command that bundles your code with Rollup, pre-configured to output highly optimized static assets for production.

`Vite` is opinionated and comes with sensible defaults out of the box, but is also highly extensible via its Plugin API and JavaScript API with full typing support.

<hr>

It has been long since we have been writing JS code in a modular fashion specially since ES6 modules. Since not a lot of browsers were handling loading ES6 modules natively, we have the concept of bundling our code, using tools that crawl, process and concatenate our source modules into files that can run in the browser.

Tools like Webpack, parcel & rollup do the same job.
When you start a project, the size & number of JS modules may look like a smaller problem but as you write more code, the project grows & you see that starting a dev server takes a long time.
Since it has to transpile the code & concatenate the code in a way that can be loaded in browsers.
The slow feedback loop can greatly affect developers' productivity and happiness.

_Vite aims to address these issues by leveraging new advancements in the ecosystem: the availability of native ES modules in the browser, and the rise of JavaScript tools written in compile-to-native languages._

`Vite` splits the bundles into two parts:
1. External dependencies (Vendor code): Dependencies are mostly plain JavaScript that do not change often during development. 
**Vite pre-bundles dependencies using esbuild.** Esbuild pre-bundles dependencies 10-100x faster than JavaScript-based bundlers.

2. Your code (ES modules): **Vite serves source code over native ESM.** This is essentially letting the browser take over part of the job of a bundler. `Vite` only needs to transform and serve source code on demand, as the browser requests it.

Here, `Vite` assumes that while you are developing in your local machine you would have latest of browsers that support loading ES6 modules natively.

## That essentially means no time spent on bundling your code before the server can start.
![Bundling before server start](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/656g1l249uei8twera71.png)

![No Bundling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y8bsd1kkkxj7c69jg4s.png)
 
## Awesome, so why bundle for production?

- Though most of the browsers now support loading ES modules natively, if not all of your target audience is on latest browsers, you still need bundling.
- If you don't bundle, you are going to make a lot of round trips on the network to fetch modules. To get the optimal loading performance in production, it is still better to bundle your code with tree-shaking, lazy-loading and common chunk splitting (for better caching).

## Getting started with `Vite`

With minimal dev dependencies, you can be off to a flying start

```
"devDependencies": {
  "@vitejs/plugin-react": "^1.1.4",
  "vite": "^2.7.10"
}
```
A very basic `vite.config.js`

```
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()]
});
```
Two simple commands to start a dev server & make a production build:
`vite` & `vite build` respectively.

`Vite` looks for an index html entry in the root directory from where you need to load the root/index module of your code.

![Server startup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rik9cy9ifbbfq8xqo86y.png)
 
`index.html`
```
<!DOCTYPE html>
<html>
<head></head>
<body>
  <div id="root"></div>
  <script type="module" src="./index.jsx"></script>
</body>
</html>
```

`index.jsx`
```
import React from 'react';
import ReactDOM from 'react-dom'
import App from './src/app';

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.querySelector('#root')
);

```
`src/app.jsx`

```
import React from 'react';

const App = () => {
  return <>
    <div>Hello There</div>
    <div>Time right now: {new Date().toTimeString()}</div>
  </>
}

export default App;

```

Without bundling the code, server starts in a fraction of a second
![Server startup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c26w1mjhy4v0cf1wazbo.png)

If you look at how the ES modules are loaded in the browser, note that app.jsx loaded as a native ES module
![Resources](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ddunvl623gn0i0dm68r.png)

## Hot replacement of modules (HMR)
Developers need to get immediate feedback of changes made in the code. You can't wait for full bundling to happen again & reloading the page which breaks the current state & flow.
This is why some bundlers support Hot Module Replacement (HMR), allowing a module to "hot replace" itself without affecting the rest of the page. Again as the project grows, HMR also takes a long time which can be a productivity killer.

`Vite` takes an edge over other bundling tools by performing HMR over native ESM. When a file is edited, `Vite` only needs to precisely invalidate the chain between the edited module and its closest HMR boundary (most of the time only the module itself), making HMR updates consistently fast regardless of the size of your application.

`Vite` also takes advantage of HTTP headers to speed up full page reloads. Source code module requests are made conditional via 304 Not Modified, and dependency module requests are strongly cached via Cache-Control: max-age=31536000,immutable so they don't hit the server again once cached.

## Recap
- `Vite` starts your dev server fast by skipping the bundling.
- `Vite` make use of HTTP status codes for a faster reload & caching.
- `Vite` uses native ESM for hot module replacement. Thus your changes reflect in your app faster.
- Since `Vite` is a bit opinionated about the config, with a minimal config you are good to go.
![Wow](https://i.pinimg.com/originals/0f/67/90/0f67908cde5b012edffeb5ff5e96bcd4.gif)
 
## Server side rendering
`Vite` is also pre-configured to handle your build as a universal app. `Vite` can pre-render the HTML pages, so robot crawlers can fetch your page content without executing js.
Read more [https://vitejs.dev/guide/ssr.html](https://vitejs.dev/guide/ssr.html)

## So should we just move to `Vite` & stop using tools like Webpack?
Coming back to the question that we started with. With all the benefits listed above, it seems promising to move to `Vite`.

> What gives you a lot of simpler APIs with a lot of abstraction and an opinion is often hard to configure.

Based on this principle if you use some very specific long tail configurations of Webpack, it won't be a good idea to jump to Vite rightaway. If you use Webpack with basic configurations, you should move to `Vite` for a better developer experience.

If I am starting a new project, it will be using `Vite` for sure.

Thank you for reading. If you have moved a large scale project from Webpack to `Vite`, do share your experience. It will be great to learn from your experience.