Skip to content

Configuring Vite ​

Lupa runs your tests inside a headless browser using Vite as its development server and build pipeline.

By default, Lupa will automatically discover and use your project's vite.config.ts (or vite.config.js) file, just like a standard Vite application. This means you can use the same Vite plugins, aliases, and loaders in your tests that you use in your application code.

Example: Supporting Standard ES Decorators ​

A common use case for customizing the Vite configuration in a testing environment is to support bleeding-edge syntax that isn't fully implemented in all browsers yet, such as Standard ES Decorators (Stage 3).

Vite 8 uses Oxc to transform TypeScript by default. While extremely fast, Oxc currently passes standard decorators directly through to the output, which causes a SyntaxError when the test runner loads the file in a browser like Chromium.

To fix this, you can configure Vite to pre-transform TypeScript files using esbuild (which natively transpiles standard decorators into JavaScript functions) before Vite's default pipeline processes them.

1. Update vite.config.ts ​

Create or update your vite.config.ts in the root of your project:

ts
import { defineConfig } from 'vite'
import esbuild from 'esbuild'

export default defineConfig({
  plugins: [
    {
      name: 'esbuild-decorators',
      enforce: 'pre',
      async transform(code, id) {
        // Only run on TypeScript files that actually contain decorators
        if (id.endsWith('.ts') && code.includes('@')) {
          const result = await esbuild.transform(code, {
            loader: 'ts',
            target: 'es2024',
            sourcemap: true,
            sourcefile: id,
          })

          return { code: result.code, map: result.map }
        }
      },
    },
  ],
})

NOTE

By omitting tsconfigRaw in the esbuild.transform() options, esbuild assumes standard decorators and natively transpiles them down to standard JavaScript, preventing browser SyntaxErrors.

WARNING

It is critical to include sourcemap: true and sourcefile: id in the esbuild.transform() options. Without these, Vite will not receive a source map for the type-stripping transformation, which will lead to highly inaccurate stack traces and line numbers when a test fails.

2. Run your tests ​

Lupa will automatically pick up your vite.config.ts without any extra configuration required in your lupa.config.ts file!

bash
npx lupa test

Inline configuration ​

If you do not want to use a vite.config.ts file, or if you need specific Vite settings that only apply during testing (and shouldn't affect your production build), you can pass Vite configuration directly to the configure() method in your lupa.config.ts runner:

ts
import { configure, run } from '@pawel-up/lupa/runner'
import esbuild from 'esbuild'

configure({
  suites: [
    {
      name: 'unit',
      files: ['tests/**/*.test.ts'],
    },
  ],
  vite: {
    plugins: [
      {
        name: 'esbuild-decorators',
        enforce: 'pre',
        async transform(code, id) {
          if (id.endsWith('.ts') && code.includes('@')) {
            const result = await esbuild.transform(code, { 
              loader: 'ts', 
              target: 'es2024',
              sourcemap: true,
              sourcefile: id
            })
            return { code: result.code, map: result.map }
          }
        },
      },
    ],
  }
})

run()

When you define vite properties inside the configure() block, Lupa will merge them with your vite.config.ts automatically.