できない.dev

Vitest で「document is not defined」が解決できない(jsdom 環境未設定)

Vitest の既定環境は node なので、document や window を触ると document is not defined になる。
test.environment を jsdom か happy-dom にすれば DOM API が使えるようになる。

公開: 更新:

実行例あり(2026-09-04 に実環境で検証)

要約

document is not defined(window is not defined も同様)は、Vitest の既定テスト環境が Node.js で、ブラウザの DOM API を持たないために出る。

DOM を使うコンポーネントテストでは、jsdom か happy-dom のブラウザ風環境へ切り替える必要がある。

test.environment を jsdom にすれば document などが使えるようになる(公式: environment(新しいタブで開く))。

実行例

同じ npx vitest run を 3 回並べているが、1 回目は既定の node 環境で ReferenceError: document is not defined になり、2 回目は vitest.config.js で environment を jsdom にしたもの、3 回目は設定ファイルを消してテストファイル先頭の docblock で jsdom を指定したもので、どちらも同じテストが通る。
jsdom は最初から入れてあるので、失敗の原因が環境設定だけであることが分かる。

$ npx vitest run
RUN  v2.1.9 /tmp/tmp.PZktlxHvMu
 
 ❯ dom.test.js (1 test | 1 failed) 3ms
   × dom > creates an element 2ms
     → document is not defined
 
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
 
 FAIL  dom.test.js > dom > creates an element
ReferenceError: document is not defined
 ❯ dom.test.js:5:16
      3| describe('dom', () => {
      4|   it('creates an element', () => {
      5|     const el = document.createElement('div');
       |                ^
      6|     el.textContent = 'hello';
      7|     expect(el.textContent).toBe('hello');
 
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
 
 Test Files  1 failed (1)
      Tests  1 failed (1)
   Start at  01:22:28
   Duration  224ms (transform 22ms, setup 0ms, collect 9ms, tests 3ms, environment 0ms, prepare 52ms)
 
終了コード: 1
$ npx vitest run
The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
 
 RUN  v2.1.9 /tmp/tmp.PZktlxHvMu
 
 ✓ dom.test.js (1 test) 2ms
 
 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  01:22:29
   Duration  608ms (transform 18ms, setup 0ms, collect 11ms, tests 2ms, environment 386ms, prepare 48ms)
 
終了コード: 0
$ npx vitest run
RUN  v2.1.9 /tmp/tmp.PZktlxHvMu
 
 ✓ dom.test.js (1 test) 2ms
 
 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  01:22:30
   Duration  575ms (transform 16ms, setup 0ms, collect 11ms, tests 2ms, environment 356ms, prepare 44ms)
 
終了コード: 0

— 2026-09-04 時点の出力

検証環境

検証日
実行環境
node:20Debian GNU/Linux 12 (bookworm)
バージョン
  • Node.js 20.20.2
  • npm 10.8.2
  • Python 3.11.2
  • Git 2.39.5

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. 既定の environment が node で DOM が無い。
  2. React / Vue などのテストで document や window を参照している。
  3. jsdom(または happy-dom)が未インストール。

解決策

1. environment を jsdom にする

import { defineConfig } from 'vitest/config';
 
export default defineConfig({
  test: { environment: 'jsdom' },
});

2. ファイル単位で切り替える

// @vitest-environment jsdom

ファイル先頭の docblock やコメントで、その file だけ別環境を指定できる。

3. 依存を入れる

npm i -D jsdom

happy-dom を使う場合は同様に npm i -D happy-dom で追加する。

テスト対象が DOM を触らないユーティリティだけなら environment は node のままでよく、画面描画を伴うテストだけ jsdom にすると起動コストを抑えられる。

この記事は役立ちましたか?