Migrating a Flow typed React SPA project from create-react-app (and Webpack) to Vite
I had a project based on Create React App, using Flow types, which I wanted to migrate to Vite. These are roughly the steps I had to follow:
- Most of my JSX files had a
.js
file extension. I renamed them all to.jsx
– Vite is much happier that way - I installed Vite and a few plugins:
- @bunchtogether/vite-plugin-flow (to allow working with Flow types)
- @vitejs/plugin-react
- vite-jsconfig-paths
- @vitejs/plugin-react-refresh
- vite-plugin-svgr
yarn install -D vite vite-jsconfig-paths vite-plugin-svgr @vitejs/plugin-react @vitejs/plugin-react-refresh @bunchtogether/vite-plugin-flow
- Added a
vite.config.js
to the project root:
/* eslint-disable flowtype/require-valid-file-annotation */
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgrPlugin from "vite-plugin-svgr";
import { flowPlugin, esbuildFlowPlugin } from "@bunchtogether/vite-plugin-flow";
import jsconfigPaths from "vite-jsconfig-paths";
import * as path from "path";
// https://vitejs.dev/config/
/** @type {import('vite').UserConfig} */
export default defineConfig({
optimizeDeps: {
esbuildOptions: {
plugins: [esbuildFlowPlugin()],
},
},
plugins: [
flowPlugin(), react(), jsconfigPaths(), svgrPlugin()
],
resolve: {
alias: [
{ find: "styles", replacement: path.resolve(__dirname, "src/styles") },
],
},
});
- Added a new file at
/flow-typed/vite_import_meta.js
to handle Vite’s handling of environment variables:
// @flow
declare interface Import$Meta extends Import$Meta {
env: {
[key: string]: string,
};
}
- Update the paths in my .jsconfig file:
{
"compilerOptions": {
"baseUrl": "src",
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"paths": {
"flow-types": ["flow-types.js"],
"polyfills": ["polyfills.js"],
"apis/": ["apis/"],
"App/": ["App/"],
"assets/": ["assets/"],
"constants/": ["constants/"],
"errors/": ["errors/"],
"hoc/": ["hoc/"],
"hooks/": ["hooks/"],
"redux/": ["redux/"],
"styles/": ["styles/"],
"utils/": ["utils/"],
"validators/": ["validators/"]
}
},
"include": ["src"],
"exclude": [
"node_modules",
".storybook",
"Auth0",
"flow-typed",
"dist",
".idea"
]
}
- Change the prefix on all .env variables from
REACT_APP_
toVITE_
- [ ] Change all instances of
process.env["REACT_APP_WHATEVER"]
toimport.meta.env.VITE_WHATEVER
- Move index.html from public to the project root, and update any URLs to use
%VITE_WHATEVER%
- Add this to the ignore section of your
.flowconfig
:/vite.config.js
- I ran into issues with circular references. I was able to find them with:
npx madge src/index.jsx --circular
- Test like hell!
Thanks to Cathal Mac Donnacha, whose post about migrating a typescript project from CRA to Vite was hugely helpful.
Update: I’ve since migrated the project to use Flow’s Hermes parser.