Validate-env plugin for Vite
Tags: vite, javascript, webdev, beginners
Published: 2022-10-02 07:36:20

Have you ever restarted a CI several times in a row because you forgot to add some environment variables? 

Or spent an hour debugging an issue only to realize that it was just one of your environment variables that was undefined? Or maybe this variable was filled in but badly formatted? 

This is the problem that `vite-plugin-validate-env` tries to solve.

![example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu9stwcec6nf7s43q68s.png)

> https://github.com/Julien-R44/vite-plugin-validate-env

---

## Introduction

So, this plugin for Vite allows you to validate your environment variables at build time with 0 runtime overhead.

🪛 Totally type-safe. Types are inferred from your schema definition.
✅ Support multiple validation librairies ( `Zod`, and `@poppinss/validator-lite` )
👉 Parsing, validation, transformation
🎉 Custom rules and error messages

And it's as simple as that : 

```ts
// vite.config.ts
import { defineConfig } from "vite";
import { ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [
    ValidateEnv({
      VITE_MY_VAR: Schema.string()
    }),
  ],
})
```

Now, before launching your dev server with `pnpm dev`, or launching a build with `pnpm build`, the plugin will validate your environment variables. If something is wrong, the process will stop immediately and warn you. 
> See [fail-fast](https://en.wikipedia.org/wiki/Fail-fast)

Here is the output we will get directly in our terminal when we try to launch or build our application :

![terminal output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tvbb53pcdejl7kqgyup.png)

---

## Transforming variables

Also, let's imagine the following case: you want to expose a variable `VITE_AUTH_API_URL` in order to use it to call an API. However, you absolutely need a trailing slash at the end of this environment variable. Here's how it can be done :

```ts
import { defineConfig } from '@julr/vite-plugin-validate-env'
import { z } from 'zod'

export default defineConfig({
  validator: 'zod',
  schema: {
    VITE_AUTH_API_URL: z
      .string()
      .transform((value) => value.endsWith('/') ? value : `${value}/`),
  },
})
```

> Note two things here: 
- The schema is validated using Zod, which can be useful if you already use this library. But it would also be possible with the other validator.
- The schema is defined here in a dedicated file env.ts. Separating the schema from vite.config.ts is much cleaner.

And that's it. If one of your colleagues forgets the trailing slash at the end of this environment variable, it will be automatically added. 

---

## Type safe `import.meta.env`

If you are doing typescript, you may know that you can have intellisense on the `import.meta.env` object by manually adding your variables, as explained here in the documentation of vite : 

https://vitejs.dev/guide/env-and-mode.html#intellisense-for-typescript

With vite-plugin-validate-env, you kill two birds with one stone. Defining your schema will allow you to super easily augment your `import.meta.env` object like this : 

```ts
type ImportMetaEnvAugmented = import('@julr/vite-plugin-validate-env')
  .ImportMetaEnvAugmented<typeof import('../env').default>

interface ImportMetaEnv extends ImportMetaEnvAugmented {
  // Now import.meta.env is totally type-safe and based on your `env.ts` schema definition
}
```

Example : 

![example type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hk0j9lx71c4913qwf2s2.png)

---

I hope you will find this plugin useful, and if you have any feedback, please let me know ! I am also open to any PRs, if you want to contribute to the project.

You can find the project here on GitHub with much more information about the different features in the README : https://github.com/Julien-R44/vite-plugin-validate-env

Please show some 💖 and star the project if you like it, it will help me a lot to get more visibility on the project.