Is It Time To Say Goodbye To Webpack?
Before we answer the big question, let's 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
Let's 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.
It has been long since we have been writing JS code in a modular fashion especially 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:
- 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. - 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 the latest of browsers that support loading ES6 modules natively.
That essentially means no time spent on bundling your code before the server can start.
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 the 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.
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, the server starts in a fraction of a second
If you look at how the ES modules are loaded in the browser, note that app.jsx loaded as a native ES module
Hot replacement of modules (HMR)
Developers need to get immediate feedback on changes made in the code. You can’t wait for full bundling to happen again & reload 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.
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
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 right away. 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.
More content at plainenglish.io. Sign up for our free weekly newsletter. Get exclusive access to writing opportunities and advice in our community Discord.