Speed Up Development by Replacing Webpack with Vite

Are you missing out on blazing-fast development server start-up and hot module replacement (HMR)? Maybe you should consider Vite.

Recently, I participated in a Hackathon with a handful of my fellow Atoms. I worked for three days on a project that tied together a myriad of different technologies the group shared an interest in learning more about. The project called for a frontend, and for this, we chose Svelte, an increasingly popular JS library that aims to compete with React, Vue, etc.

While I worked on the project and became more familiar with Svelte (technically SvelteKit), I was blown away by how quickly my changes were displayed on the page. It felt nearly instantaneous. After looking through the Svelte docs, I discovered that Svelte accomplishes this with Vite, its frontend build tool.

How Vite Achieves Its Impressive Performance

Vite dramatically cuts down on start and rebuild times by leaning on modern web browsers with support for native ESM modules. In development, Vite essentially acts as a web server, serving up files as needed by the browser. These files may include both source code modules as well as precompiled dependencies compiled with esBuild during the initial run. This process of forgoing bundling is a deviation from web development’s recent past. That recent past has relied heavily on bundling up dependencies for good reason!

There’s a great deal more to say on this topic, much more than I can fit into this post. If you’re curious about how Vite achieves its impressive performance, I’d encourage you to read more about it on Vite’s site. They do an excellent job of explaining the various features of the tool and how it’s been optimized.

Alleviating Project Pain

After doing some research and witnessing Vite’s performance throughout the Hackathon, I was curious whether my current project could benefit from its use. The project’s React Typescript frontend relied on webpack for its dev tooling, which is standard for most React projects. It also sported a substantial webpack config. Our development workflow was reasonable, but we felt pains at times during reloading. With all of this in mind, I decided to pull Vite into the project with hopes that it could alleviate that pain.

I was pleasantly surprised by how well it went! The dev server’s performance has been as impressive as advertised, and the process of migrating to Vite wasn’t overly difficult. Vite offers templates for many different frontend libraries and supports Typescript out of the box, so I was not concerned on that front.

I had some reservations regarding its ability to replace the functionality provided by our webpack config. Turns out, Vite’s default configurations covered much of what we needed! This is one area, though, that I’d still urge caution for those considering Vite. If you have a very complex webpack config, you will likely find that Vite doesn’t offer that same level of configuration.

Leveraging Vite for Development

While Vite also includes rollup to facilitate builds, we’re currently only leveraging it for development. Here’s how you can do the same in your project:

Install dependencies

You’ll need Vite and the plugin that helps React work seamlessly with Vite.


yarn add -D vite @vitejs/plugin-react

Vite Configuration

This will be heavily influenced by your own project. See the Vite documentation for details. I recommend referring to your existing webpack configuration where appropriate. You should notice that your Vite config winds up being much smaller.


// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";

const SERVER = "http://localhost:8080"

export default defineConfig({
  plugins: [react()],
  define: {
    __TEST__: JSON.stringify(false),
    __DEV__: JSON.stringify(false),
  },
  server: {
    proxy: {
      "/api": `http://${SERVER}`,
    },
  },
  resolve: {
    alias: 
      src: path.resolve(__dirname, "/src"),
    },
  },
});

Entry point

Vite’s dev server requires you use index.html as an entry point. Something like this will suffice:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
    />
  </head>

  <body style="margin: 0px; position: fixed; height: 100%; overflow-y: auto">
    <div id="app"></div>
  </body>
  <script type="module" src="./app.tsx"></script>
</html>

Typescript Configuration and Shims

Update tsconfig.json to use "isolatedModules": true

Add client type shims to support asset imports and Vite injected environment variables.

/// <reference types="vite/client" />

Vite Typescript Documentation

Type Imports

You will need to modify type imports to specifically utilize the import type {foo} from "bar" syntax. This means you may have two distinct import lines when importing from a module: one for types, one for values.

Project-Specific Tweaks

I can’t offer much help here. You may find perusing Awesome Vite for plugins helpful.

Configure npm Scripts

Last but not least, make sure to update your dev script to use yarn vite


And that should do it! With Vite pulled in, you should have blazing fast server start and HMR, without any complex configuration!

Conversation
  • Aissa BOUGUERN says:

    Thank you for this well done article!
    Is not there a workaround for importing types issue ? I have an existing big project I want to migrate to Vite :s

    Thanks in advance

    • Jake Silas Jake Silas says:

      Thanks for question, Aissa. My point about the fixing type imports is a bit over-blown and probably deserves an edit.
      Generally, there is no issue as

      types are treated as comments and are ignored by esbuild.

      You can read more about that in the esbuild documentation.

      You may run into an issue if you’re importing and exporting a type within the same file. In that case, I recommend the following:

      export type { AppState } from "./core";
      
      
      		
  • Comments are closed.