How to replace webpack & babel with Vite on a legacy React Typescript project
Tags: javascript, webdev, vite, react
Published: 2022-03-25 14:37:28


It's insane how fast the world of JavaScript moves. 

As far as build tools go I remember how popular [Grunt](https://gruntjs.com/) was when it was first released, then it was [Gulp](https://gulpjs.com/), and [Babel](https://babeljs.io/) came along to help you add new us features and get them working on older browsers. 

Then there was [Webpack](https://webpack.js.org/) which seemed like it would be around for a while. Even after things like [Parcel](https://parceljs.org/) and [Snowpack](https://www.snowpack.dev/) came on the scene people still recommended Webpack. I mean, it's still the backbone of create-react-app. An then, [Vite](https://vitejs.dev/) was released. 

Vite is fast, really fast. It requires very little config and is easy to setup. It sits on top of [esbuild](https://esbuild.github.io/).

I have no doubt there will be something in the future that will replace Vite, but for the simple fact that the config file for Vite can be around 10 lines whereas for Webpack it would have been around 100, I think it's a good choice to stick with for the next few years and something to upgrade your old Webpack project to. 

Plus you don't need Babel if you're using Vite so you can get rid of a tonne of dependencies and security vulnerability messages.

## Main steps

1 - First thing's first, let's create a new branch for our old project just in case we need to go back to it for any reason. We can delete the branch after a few months if we've never needed to refer to it.

```sh
# oh-my-zsh git aliases
gcb old-webpack-babel
gpsup
```
Note: The above commands are aliased github commands that come by default with [oh-my-zsh](https://ohmyz.sh/). You can view the [full list](https://kapeli.com/cheat_sheets/Oh-My-Zsh_Git.docset/Contents/Resources/Documents/index) here.

2 - now let's go back to our main branch and remove all of our babel and webpack packages, brace yourself for one large command:
```sh
npm uninstall webpack webpack-merge webpack-dev-server
 webpack-cli ... you get the idea
```

3 - Delete all webpack and babel related files, webpack.common.js, webpack.dev.js etc...

4 - Install Vite and the Vite React plugin
```sh
npm i vite @vitejs/plugin-react
# then
npm i @types/node -D
```

5 - Create a **vite.config.ts** file in the root of your project with the following code:
```js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()]
});
```

6 - Update your package.json file with the following code
```
"dev": "vite",
"build": "vite build",
```

And now run `npm run dev`, and if all goes well your project should be fine. 

## Optional steps

Depending on your project, the steps below might not be necessary.

### Aliases
If like me you have some random Webpack aliases in your code like this:
```js
import "@/assets/styles/global";
```

You can add that to your Vite config file like so:
```js
// At top of file
import path from "node:path";

// ...
  resolve:{
      alias:{
        '@' : path.resolve(__dirname,)
      },
    },
  plugins: [react()]
```

### CSS Modules
If you're using css modules, then I feel sorry for you. You need to change the extension of all your files to .module.css instead of just .css

Then change the name of any compose properties you have in your css file as well:

```css
/* from this */
composes: c-white from "../helpers.css";
/* to this */
composes: c-white from "../helpers.module.css";
```

And also any JS/TS file that you are importing the css file in.

```js
// from this
import buttonCss from '@assets/styles/Buttons.css';
// to this
import buttonCss from '@assets/styles/Buttons.module.css';
```

This is really painful I know, but it does kind of make more sense. And also, find and replace all is your friend 💪

### Vite environment variables
You may want to set up environment variables to keep secrets or to insert bits of information based

1 - Create a `.env` file.
2 - Put a **VITE_** prefix in front of variables like this:
```
VITE_TEST_VAR = "something secret"
```
3 - Load them up in your code like this:
```js
const secretVar = import.meta.env.VITE_TEST_VAR;
```
4 - If you're using Typescript you will need to create an `env.d.ts` file in the root of your project 
```ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  // more env variables...
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}
```

### Install npm-check-updates
Since you're upgrading one part of a legacy project, why not update all the other dependencies. The best way to do that is with the [npm-check-updates](https://github.com/raineorshine/npm-check-updates) package.

I'd recommend installing updates in by [semver](https://semver.org/) levels, so patch updates first, then minor updates, then major. Testing the project still works in-between updates

This can be done easily by running a command like this:
```sh
ncu -t patch -u
```
to update just the patch versions in the package.json file, then run
```
npm i
```
to actually install the updates.

---
And that's pretty much it.

I'm not expert on Vite but if you have any questions, feel free to write them down in the section below and I'll do my best to answer them.