Migrating from Create-React-App to Vite: Simple Tutorial

I am a Software Developer and Identity Consultant, specializing in securing applications and APIs using OpenID Connect and OAuth.
Search for a command to run...

I am a Software Developer and Identity Consultant, specializing in securing applications and APIs using OpenID Connect and OAuth.
No comments yet. Be the first to comment.
I recommend installing a new project with the Vite CLI and copying your code there. This way, you get the latest version of Vite configs, including tsconfig, etc.
REACT_APPindex.htmlnpm install -g create-vite
create-vite my-react-app --template react-ts
npm install
Copy files:
Copy the src and public directories from your CRA project to your new Vite project.
Install additional dependencies:
Update your package.json dependencies from your CRA project in the new project:
npm install
typescript to the latest version.npm install typescript@latest
react-scripts:npm uninstall react-scripts
In my case, I want to keep all environment variables with the prefix
REACT_APP. I configured it as follows:
Configure vite.config.ts:
In my case, I use the following additional configuration for:
npm i vite-plugin-sass-dtsnpm i sassnpm i vite-plugin-svgrREACT_APPnpm i vite-plugin-env-compatibleindex.htmlnpm i vite-plugin-htmlModify vite.config.ts to handle environment variables, SVG files, and Sass imports.
I created two files for env and plugins:
tsconfig.node.json:-"include": ["vite.config.ts"]
+"include": ["vite.config.ts", "vite.plugins.ts", "vite.env.ts"]
vite.env.ts:
import dotenv from "dotenv";
import dotenvExpand from "dotenv-expand";
// Load .env files
const env = dotenv.config();
dotenvExpand.expand(env);
export const REACT_APP_PREFIX = "REACT_APP_";
export const VITE_PREFIX = "VITE_";
export const getEnvVariables = () => {
const envVariables = Object.keys(process.env).reduce(
(prev: Record<string, any>, key) => {
if (key.startsWith(REACT_APP_PREFIX) || key.startsWith(VITE_PREFIX)) {
prev[key] = process.env[key];
}
return prev;
},
{}
);
return envVariables;
};
export const envVariables = getEnvVariables();
export const VITE_PUBLIC_URL = envVariables.VITE_PUBLIC_URL;
vite.plugins.ts:
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";
import { createHtmlPlugin } from "vite-plugin-html";
import viteSassDts from "vite-plugin-sass-dts";
import env from "vite-plugin-env-compatible";
import { envVariables, REACT_APP_PREFIX } from "./vite.env";
export const configurePlugins = () => {
return [
react(),
svgr({
svgrOptions: {
exportType: "named",
ref: true,
svgo: false,
titleProp: true,
},
include: "**/*.svg",
}),
viteSassDts(),
createHtmlPlugin({
inject: {
data: {
...envVariables,
},
},
}),
env({
prefix: REACT_APP_PREFIX,
}),
];
};
vite.config.ts:
import { defineConfig } from "vite";
import { VITE_PUBLIC_URL } from "./vite.env";
import { configurePlugins } from "./vite.plugins";
import path from "path";
export default defineConfig({
base: VITE_PUBLIC_URL,
plugins: configurePlugins(),
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
server: {
port: 3000,
},
build: {
outDir: "build",
emptyOutDir: true,
},
});
npm install @vitejs/plugin-react dotenv dotenv-expand vite-plugin-svgr vite-plugin-html vite-plugin-sass-dts vite-plugin-env-compatible
Optional: Migrate to VITE instead of REACT_APP variables:
File .env:
VITE_MY_VARIABLE=Test
File App.tsx:
- process.env.VITE_MY_VARIABLE
+ import.meta.env.VITE_MY_VARIABLE
import { ReactComponent as MyIcon } from "./images/MyIcon.svg";
index.htmlroot folder (previously in the public folder)<html lang="en">
<head>
<meta charset="utf-8" />
+<base href="<%= VITE_PUBLIC_URL %>" />
-<base href="%PUBLIC_URL%/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="App Name" />
<title>App Name</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
+<script type="module" src="/src/index.tsx"></script>
</body>
</html>
PUBLIC_URL VariablePUBLIC_URL was originally used in the router, so it is necessary to change it:-<BrowserRouter basename={process.env.PUBLIC_URL}>
+<BrowserRouter basename={import.meta.env.VITE_PUBLIC_URL}>
<App />
</BrowserRouter>
File .env.development:
VITE_PUBLIC_URL=/
File .env.production:
VITE_PUBLIC_URL=/my-app
package.json Scripts Section"scripts": {
-"start": "react-scripts start",
+"start": "vite",
-"build": "react-scripts build",
+"build": "vite build",
-"eject": "react-scripts eject",
+"preview": "vite preview"
}
npm run start
Feel free to share your feedback and suggestions for improvements!
Thanks for reading. 👋🏻