Migrating from CRA to Vite: Problems you might face
Tags: react, cra, vite, tutorial
Published: 2024-03-24 06:19:29

## Why Consider Migrating from CRA to Vite?

Migrating from Create React App (CRA) to Vite can offer several benefits:

1. **Improved Development Experience:** Vite provides faster cold start times and hot module replacement (HMR), resulting in a smoother development experience compared to CRA.

2. **Performance:** Vite leverages ES modules and native ESM browser support, resulting in faster bundling and serving of assets, which can lead to improved application performance.

3. **Simplified Configuration:** Vite requires minimal configuration, reducing boilerplate code and making it easier to set up and customize your project compared to Webpack-based setups like CRA.

4. **Support for Modern JavaScript Features:** Vite supports modern JavaScript features out of the box, allowing developers to leverage features like ES modules, TypeScript, and JSX without additional configuration.

5. **Optimized Build Output:** Vite generates optimized build outputs, including tree-shaking and code-splitting, resulting in smaller bundle sizes and faster load times for end-users.

Overall, migrating from CRA to Vite can help improve the developer experience, application performance, and build optimization, making it a compelling choice for React developers looking to modernize their projects.

In this quick demo, I'll be migrating a simple React 17 to-do list app I created using CRA to Vite. Even though this is a small app, the process is going to be similar for a bigger project. If you want to play along, feel free to download the to-do list source from the following [link](https://github.com/justnixx/react-todo-app-example/archive/refs/heads/main.zip).

After you have downloaded the project, navigate to the project folder and run `npm install`. You may notice that we have a lot of vulnerability warnings; let's ignore that for now and try to run the app to see if it works. To run the app, type the command `npm start`. If everything is good up until this point, your app will be built and opened in your web browser. However, in my case, I ran into an error.

This error is related to the Webpack build process. Specifically, it seems to be encountering an issue with creating a hash, which is used for cache-busting and ensuring that assets are only updated when their content changes.

This suggests that there might be an incompatibility or unsupported feature in the OpenSSL library being used by Node.js. My first attempt to resolve the issue was to use an earlier version of Node.js. I have NVM already installed on my computer, so this would be easy. Therefore, I ran the command `nvm use 16` and `node -v` to confirm. Now let's try running the app again with `npm start`. Voila! Our app compiles successfully and opens on http://localhost:3000.

Now that our app is working, let's begin the migration process. There are a couple of ways we could go about this, but first, let's create a new branch for our migration using `git checkout --orphan vite-migration`.

I'm going to create a fresh Vite app in this branch in a folder I'll name `vite-app`, but this is just temporary. I could also simply modify the `package.json` file and delete the `node_modules` directory, but I would go with the former approach. To create the Vite app, run `npm create vite@latest`, type the name `vite-app` or anything you like, choose React on the next screen using the arrow down key, and then choose JavaScript. A folder will be created for you; in my case, the folder is named 'vite-app'. I could navigate to that folder and run `yarn` or `npm install`, but not yet, as I want to make some changes to the `package.json` file. I want to change the React version from 18 to our CRA React version, which is 17. Our goal right now is to migrate and test to ensure our app works; we'll upgrade later. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82udjtg6l90g16c0w27q.png)

So now, let's run `yarn` to install our dependencies. Dependencies successfully installed, now let's delete the `src` folder from the `vite-app` and move our `src` folder from the CRA version into it. Let's also delete the `public` folder from the `vite-app` directory and move the `public` folder from the CRA into it. Now, notice we have an `index.html` file in the root directory and also in the `public` folder we just moved. Let's replace the `index.html` file in the root with `public/index.html`. Now let's delete everything in the root directory, keeping only the `vite-app` directory and `README.md` file. Let's delete the `README.md` in the `vite-app` directory and move everything to the root directory. Your `vite-app` directory should be empty right now; let's delete it.

In the `src` folder, let's rename `index.js` to `main.jsx`, open the `index.html` and add 
```HTML
<script type="module" src="/src/main.jsx"></script>
``` 
right before the closing `</body>` tag, save the file, and let's try to run the app with `yarn dev` or `npm run dev`. You'll get an "Internal server error: URI malformed" error. Notice the `%PUBLIC_URL%` in the tags inside the `<head>` element; that is the issue. Let's remove those. I also removed all the comments in the HTML file.

Now let's try to run the app again. This time we get a different error: "Internal server error: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension." This is because our `src/App.js` file contains JSX code; we need to rename it to `src/App.jsx`. Although you can configure Vite to parse the file correctly, the recommended approach is simply to rename files with JSX code to `.jsx` extension. So let's rename and try again.

Now our app is working with no problem. Mine is running on http://localhost:5173. I want to change the port to 3000. There are two ways you can do this: modify the `vite.config.js` or the `package.json` scripts, but I'll use the former. Open the `vite.config.js` file and add 

```JavaScript
server: { port: 3000 }
```
That's all!

If you are migrating a large project, you may face some other challenges. I'll be willing to assist you if you drop a comment. Thanks for reading. 💕🙏 

[Code available here](https://github.com/justnixx/react-todo-app-example)