.gitディレクトリの中でVitestを実行すると、エラーが発生する話
新しくWebアプリを作るためにまずはテストを実行できる環境を作ろうと、Vitestを使った環境構築をしていました。しかし、 Error: Cannot find module '/@vite/env'
というエラーが発生し、どうにもこうにも解消できません。AIに任せたところ、一生あれこれ試行錯誤していて解決しそうな雰囲気がまったくありませんでした。
Vitest
のバージョン3系を使うとこのエラーが発生するものの、2系を使えば問題ないことはわかりました。とはいえ気持ち悪いのでどうにかならないか調べ、原因がわかったので同様の問題に悩む方のために記事にします。
結論を言うと作業ディレクトリのパスに.git
が含まれている場合に問題が発生することがわかりました。最近使い始めたphantomのデフォルト設定で、ワークツリーの展開先が.git/phantom/worktrees
ディレクトリ以下のため、この問題に遭遇しました。
ディレクトリ構成としては、このような状態になります。
PROJECT_ROOT/
├── .git/
│ └── phantom/
│ └── worktrees/ ← ワークツリーの作業ディレクトリはここの下に展開
│ └── feature-branch1/ ← ここで Vitest を実行するとエラーが発生
│ └── feature-branch2/
└── (通常のプロジェクトファイル置き場)
具体的な問題の内容と原因について説明します。
調査のためのプロジェクト構成
今回、問題調査のために最小構成になるようなプロジェクトを作って試していました。Svelteのドキュメントを参考に作っています。
最終的に以下のような構成でテストをしました。
{
"name": "frontend",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"test": "vitest"
},
"devDependencies": {
"@sveltejs/kit": "^2.16.0",
"@testing-library/jest-dom": "^6.6.3",
"jsdom": "^26.1.0",
"svelte": "^5.0.0",
"typescript": "^5.0.0",
"vitest": "3.2.4"
}
}
export function multiplier(getCount: () => number, k: number) {
return {
get value() {
return getCount() * k;
},
};
}
import { flushSync } from "svelte";
import { expect, test } from "vitest";
import { multiplier } from "./multiplier.svelte.ts";
test("Multiplier", () => {
let count = 0;
let double = multiplier(() => count, 2);
expect(double.value).toEqual(0);
count = 5;
expect(double.value).toEqual(10);
});
/// <reference types="vitest" />
import { defineConfig } from "vitest/config";
import { sveltekit } from "@sveltejs/kit/vite";
export default defineConfig({
plugins: [sveltekit()],
test: {
environment: "jsdom",
globals: true,
},
});
テスト実行 - 正常系
npm install
してからテストを実行すると、期待通りテストはパスします。
$ npm run test
> frontend@0.0.1 test
> vitest
src/app.html does not exist
DEV v3.2.4 /Users/takayama/Document/vitest-sample
✓ multiplier.svelte.test.js (1 test) 1ms
✓ Multiplier 1ms
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 08:20:31
Duration 756ms (transform 185ms, setup 0ms, collect 282ms, tests 1ms, environment 288ms, prepare 40ms)
PASS Waiting for file changes...
press h to show help, press q to quit
テスト実行 - エラー
しかし構成をそのままに、.git
ディレクトリの中に入れてからテストをすると、以下のエラーが発生します。
$ npm run test
> frontend@0.0.1 test
> vitest
src/app.html does not exist
DEV v3.2.4 /Users/takayama/Document/check/.git/vitest-sample
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Error: Cannot find module '/@vite/env'
❯ VitestExecutor._fetchModule node_modules/vite-node/dist/client.mjs:247:19
❯ process.processTicksAndRejections node:internal/process/task_queues:105:5
❯ VitestExecutor.directRequest node_modules/vite-node/dist/client.mjs:268:44
❯ VitestExecutor.cachedRequest node_modules/vite-node/dist/client.mjs:189:11
❯ VitestExecutor.executeId node_modules/vite-node/dist/client.mjs:166:10
❯ createVitestExecutor node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js:469:2
❯ startVitestExecutor node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js:531:9
❯ startViteNode node_modules/vitest/dist/chunks/base.DfmxU-tU.js:10:14
❯ runBaseTests node_modules/vitest/dist/chunks/base.DfmxU-tU.js:24:30
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_MODULE_NOT_FOUND' }
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Test Files (1)
Tests no tests
Errors 1 error
Start at 08:19:14
Duration 143ms (transform 0ms, setup 0ms, collect 0ms, tests 0ms, environment 0ms, prepare 0ms)
FAIL Tests failed. Watching for file changes...
press h to show help, press q to quit
今回用意した最小構成とは別に、src/routes...
などのディレクトリ構成にしている場合に、/@vite/env
とは違う別のエラーが発生する場合があります。いずれも、必要なファイルが見つからないという、同じ原因によるエラーです。
FAIL src/routes/page.test.ts [ src/routes/page.test.ts ]
Error: Cannot find module '/Users/takayama/Document/check/.git/phantom/worktrees/feature-branch/frontend/src/routes/page.test.ts'
Caused by: Error: Failed to load url /Users/takayama/Document/check/.git/phantom/worktrees/feature-branch/frontend/src/routes/page.test.ts (resolved id: /Users/takayama/Document/check/.git/phantom/worktrees/feature-branch/frontend/src/routes/page.test.ts). Does the file exist?
❯ loadAndTransform ../node_modules/vite/dist/node/chunks/dep-DBxKXgDP.js:35725:17
エラーが発生する原因
セキュリティ上の理由から、**/.git/**
にマッチするファイルは読み込まれないというデフォルト設定がありました。
以下に引用します。
server.fs.deny
- Type: string[]
- Default: ['.env', '.env.*', '*.{crt,pem}', '**/.git/**']
Blocklist for sensitive files being restricted to be served by Vite dev server. This will have higher priority than server.fs.allow. picomatch patterns are supported.
コードだと以下の箇所です。
この設定の影響で、.git
ディレクトリの中にあるファイルが適切に読み込まれていないという状況が発生していたようです。
.git
ディレクトリの中で実行するとエラーになることは早い段階でわかったのですが、なぜそれが発生するのか理由を突き止めるのに手間取ってしまいました。具体的には、node_modules
ディレクトリの中を.git
という文字列で漁って編集しながらテストするというなんとも泥臭い方法を取りました。
解決方法
原因がわかったので、解決方法もわかります。.git
ディレクトリの中で作業をしない これに尽きます。phantomの場合は、phantom.config.json
でワークツリーのパスを変更できます。
もう一つは設定の上書きです。server.fs.deny
から、**/.git/**
を削除してしまえばエラーは発生しなくなります。が、本番環境で利用しない方がいいと思われるのであくまで一時的な対処として考えたほうが良さそうです。自己責任でお願いします。
/// <reference types="vitest" />
import { defineConfig } from "vitest/config";
import { sveltekit } from "@sveltejs/kit/vite";
export default defineConfig({
plugins: [sveltekit()],
test: {
environment: "jsdom",
globals: true,
},
server: {
fs: {
strict: true,
deny: [".env", ".env.*", "*.{crt,pem}"],
},
},
});
Discussion