VitestのIn-Source Testing(import.meta.vitest)活用と本番削除設定

Vitest Vite Testing Performance
結論

In-Source テストを本物から消すには define'import.meta.vitest': 'undefined' を設定します。

// Vitest公式仕様:src/utils/math.ts での In-Source Testing 実装例
export function calculateTax(price: number): number {
  return Math.floor(price * 0.1);
}

// ⭕ 本番ビルド時にツリーシェイキングで削除されるブロック
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest;
  
  it('消費税計算が正しく四捨五入されること', () => {
    expect(calculateTax(100)).toBe(10);
    expect(calculateTax(105)).toBe(10);
  });
}
// vite.config.ts / vitest.config.ts の必須設定
import { defineConfig } from 'vite';

export default defineConfig({
  // ⭕ 本番ビルド時に import.meta.vitest を undefined へ置換してデッドコード削除
  define: {
    'import.meta.vitest': 'undefined',
  },
  test: {
    includeSource: ['src/**/*.{js,ts}'],
  },
});

Vitest公式仕様:In-Source Testing の特長

Vitest公式ドキュメント(vitest.dev/guide/in-source.html)の規定通り、In-Source Testing は Rust などの言語仕様を参考に作られたテスト手法です。

  • Private 関数や未 export 関数のテスト: モジュール外へ公開したくない内部関数をそのままテスト可能
  • プロトタイピングの高速化: .test.ts ファイルを別作成せず、関数直下にアサーションを即記述

実際に起こる障害:define 設定漏れによる本番JSバンドルへのテストコード流出

In-Source Testing を導入した際、vite.config.tsdefine 設定を書き忘れて本番ビルド(npm run build)を実行してしまう重大ミスが発生します。

ビルドツール(Vite / Rollup)が import.meta.vitest を静的条件(false / undefined)として認識できないため、本番用の JavaScript ファイルの中にテストのアサーションコードやテストデータ文字列がそのまま残存し、アプリのバンドルサイズが肥大化・内部コードが流出する障害 が発生します。


導入手順

  1. tsconfig.jsoncompilerOptions.types"vitest/importMeta" を追加して型補完を有効化する
  2. vite.config.tsdefine: { 'import.meta.vitest': 'undefined' } を記述し、ビルド時にデッドコード削除(Tree Shaking)が動作するように設定する
  3. ソースファイル末尾に if (import.meta.vitest) ブロックを書いてテストを記述する