Migrating to Vite,Vitest?

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.

read more

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 -

  1. Adding Aliases

  2. Code Splitting

Thanks for reading !

Did you find this article valuable?

Support Anoop Jadhav by becoming a sponsor. Any amount is appreciated!