2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vite × React で Jestテストを選んだ結果、数時間溶かして地獄を見た話

2
Last updated at Posted at 2026-01-17

はじめに

どうも。
ビジネスサイド出身・非エンジニアPMのコーディです。

前回、AIを使わずに学習記録アプリを作ってみた話を書きましたが、今回はその続き。

「じゃあ次はテストとCI/CDもちゃんとやろう」

と軽い気持ちで始めたら、
Vite × React × Jest で想像以上にドロドロの沼にハマったので、その記録を書き残します。

何をやろうとしたのか

やりたかったことはシンプルでした。

  • Vite + React の個人開発アプリ
  • Jest + React Testing Library で下記のテストを書く
    • タイトルが表示されている
    • フォームに学習内容と時間を入力して登録ボタンを押すと新たに記録が追加されている
    • 数が1つ増えていることをテストする
    • 削除ボタンを押すと学習記録が削除され、数が1つ減っていることをテストする
    • 入力をしないで登録を押すとエラーが表示される
  • GitHub Actions で npm test → 通ったらデプロイ

「とりあえずJest使ってみよう」と、何も考えずに進めました。

最初は余裕だと思ってた

最初は本当に簡単でした。

  • Jest を入れる
  • React Testing Library を入れる
  • 「タイトルが表示されている」テストを書く

ここまでは問題なし。

「あ、テストって意外とすんなりイケそうじゃね?」

完全に油断してました。

沼の入口:import.meta.env

アプリでは Supabase を使っていて、
環境変数は Vite 標準のこれ。

import.meta.env.VITE_SUPABASE_URL

Jest を実行した瞬間、出てきたエラーがこれ。

最初はこう思いました。

  • if 分岐で避ければいい?
  • mock すればいい?
  • process.env に書き換えればいい?

全部良くない。沼った。

気づいた事実(ここが地獄の本体)

ここで理解したのがこれ。

Jest は
「そのコードが実行されるか」ではなく
「構文として理解できるか」で落ちる

つまり、

if (false) {
  import.meta.env
}

これでも 即アウト。

Vite 的には当たり前に使っていた構文が、
Jest 的には「見た瞬間に無理」な存在でした。

ここから沼が連鎖する

ここからが本番でした。
上手いやり方はあるのかもしれませんが。

jest.setup.js が壊れる

  • import と require を混ぜると死ぬ
  • ESM / CJS の違いで毎回詰まる

Babel 設定が分からなくなる
自分の今回の構成だと、

  • .babelrc では JSX が動かない
  • babel.config.js にすると "type": "module" で死ぬ
  • .cjs にしないとダメ

mockが突然キレる

The module factory of jest.mock() is not allowed to reference out-of-scope variables

→ 変数名を mockSelect みたいにしないと怒られる(Jestの仕様)

※厳密には“mock接頭辞必須”ではなく、ホイスト都合の out-of-scope 制限が原因。回避の1パターンとして mock〜 命名があるみたいな感じらしい。

clearAllMocks と resetAllMocks の罠

  • clearAllMocks:呼び出し履歴だけ消える
  • resetAllMocks:実装ごと消える

これを理解してないと、
前のテストの mock が次のテストに影響する

number input の 0 問題

if (!time) { ... }
  • 0 は falsy
  • 未入力と区別できない
  • テストだと特に顕在化する

正直、この辺から
「俺はいま何と戦ってるんだ?」状態でした。

一度は通した解:babel-preset-vite

調べまくって、最終的に辿り着いたのがこれ。

npm install --save-dev babel-preset-vite

Babel に「Vite の構文を理解させる」ことで、

  • import.meta.env が Jest でも通る
  • Vite 側のコードを変えずに済む

これは確かに動きました。

後で調べてみたところ、他の回避策として、Vite側で process.env 互換を用意する方法もあるみたい。(ただしアプリ側の書き方が変わりやすい)

正直しんどかった

ここまでやって思ったのが正直な感想。

  • Jest を Vite に無理やり合わせている感覚
  • 設定ファイルが増えすぎる
  • ESM / CJS / Babel / Jest の前提が全部違う

「テストを書く」より
「テストを動かす」方が難しくなっていました。

結論:Vite なら Vitest の方が自然

今回の結論はこれです。

「Vite プロジェクトなら、最初から Vitest を使った方が幸せそう」

理由はシンプル。

  • Vite と同じ実行環境
  • import.meta.env がそのまま使えそう
  • 設定量が圧倒的に少ない
  • mental model が一致する

Jest が悪いわけじゃなくて
Vite × Jest の相性が普通に悪かった感じですね、多分。

学び

僕がプログラミングの勉強を始めた理由にもつながりますが、改めて思い知らされました。

「ちゃんとした意思決定をする」

技術選定とか本当に適当こいちゃダメ。

おわりに

この記事は失敗談だけど、初心者が本気でテストを通しに行ったから書けたものかなと。
いい経験になりました。
同じところで詰まっている人の、時間を1時間でも減らせたらいいなあ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?