Migrating to Vite,Vitest?
Let's go through the steps to migrate your frontend repo to Vite
We recently migrated our project from Parcel to Vite and the reasons for doing so are in this article. Even though migrating from Parcel to Vite may not be as difficult as migrating from Webpack to Vite, this article can help you identify the essential elements that need to be set up on the Vite side.
Install Vite packages
The first step is to ensure that all the necessary Vite-specific dependencies are correctly installed.
npm i -D vite @vitejs/plugin-react vite-plugin-checker
@vitejs/plugin-react enables React support in a Vite project.
vite-plugin-checker helps in identifying typescript errors while developing.
Add Vite Config file
Add a config file in the root directory. checkout the following config -
vite.config.ts
/// <reference types="vite/client" />
// Add the above line if you are using typescript.
import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import react from '@vitejs/plugin-react';
export default () => {
return defineConfig({
plugins: [
react(),
checker({
typescript: true,
}),
],
build: {
outDir: '../dist',
},
server: {
port: 8080,
},
root: './src'
});
};
Add scripts in package.json
Include the start and build scripts in the package.json file.
package.json
"scripts": {
"build": "vite build --base=/base-path-if-any/ --config vite.config.ts",
"start": "vite --config vite.config.ts"
}
If you are deploying your project under a nested public path ( otherwise ignore this step), simply specify the base config option and all asset paths will be rewritten accordingly. This option can also be specified as a command line flag, e.g. vite build --base=/my/public/path/
.
Update Environment variables
Vite exposes all the environment variables on import.meta.env
so you can access your environment variables like import.meta.env.VITE_MY_ENV_VARIABLE
It is important to prefix all the environment variables with VITE_ since it prevents the accidental leaking of environment variable data to the client.
Add Vitest
Add vite packages
npm i -D vitest @vitest/coverage-c8 @vitest/ui
Add test scripts
Update the package.json with the following test-specific scripts -
package.json
"scripts" : {
// ... other build scripts
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage",
"test:watch": "vitest --watch",
}
Update vite config
Update the test setup in vite config.
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['../setupTests.ts']
}
update setupFiles if there are any test setup files which you want to run before running the actual unit tests.
here we are using jsdom as our test environment. so we will have to install jsdom.
npm i -D jsdom
Now the config file should look like -
vite.config.ts
// include this to add types support
/// <reference types="vitest" />
/// <reference types="vite/client" />
import { defineConfig } from 'vite';
import checker from 'vite-plugin-checker';
import path from 'path';
import react from '@vitejs/plugin-react';
export default () => {
return defineConfig({
plugins: [
react(),
checker({
typescript: true,
}),
],
build: {
outDir: '../dist',
},
server: {
port: 8080,
},
root: './src',
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['../setupTests.ts'],
}
});
};
migration from jest to vitest is pretty easy but in our scenario, the number of tests was pretty high and the performance improvement which vitest was claiming was not much evident. because of this, we thought of sticking to jest for some more time.
checkout the migration guide if you want to move from jest to vitest.
How to make it work with Jest?
The only challenge when using Jest with Vite is the way we import environment variables, i.e. import.meta.env
. To make it work with Jest, we need to revert to the process.env
implementation. Remember, we changed this in the "Update Environment" section above.
We can use the define
attribute in Vite to import environment variables more efficiently. Instead of using process.env
, we can add the environment variables directly to the define
attribute when creating the Vite instance. For example:
defineConfig({
define: {
MY_ENVIRONMENT_VARIABLE: process.env.MY_ENVIRONMENT_VARIABLE
}
});
Now the config file would look like this -
vite.config.ts
/// <reference types="vitest" />
/// <reference types="vite/client" />
import { defineConfig, loadEnv } from 'vite';
import checker from 'vite-plugin-checker';
import react from '@vitejs/plugin-react';
interface ViteConfigProps {
mode: string;
}
export default ({ mode }: ViteConfigProps) => {
const env = loadEnv(mode, process.cwd());
// expose .env as process.env instead of import.meta since jest does not not support import meta yet
const processEnvValues = {
'process.env': Object.entries(env).reduce((prev, [key, val]) => {
return {
...prev,
[key]: val,
};
}, {}),
};
return defineConfig({
plugins: [
react(),
checker({
typescript: true,
}),
],
build: {
outDir: '../dist',
},
server: {
port: 8080,
},
root: './src',
define: processEnvValues,
});
};
This will get you started with the project migration.
I will be updating this article with the following topics very soon -
Adding Aliases
Code Splitting
Thanks for reading !