Cloudflare Workers, vitestのsetupFilesの設定がわからなかった話
Cloudflare Workersのvitestの設定の仕方
背景
最近 Cloudflare Workersのプロジェクトを始めた。
Googleのjulesで段階的に進めていたが、特にテストの進め方の面でCloudflareの現在のバージョンのやり方をjulesにインプットできないとスムーズに進まないことが分かった。
やりたかったこと / できなかったこと
D1のテストで使用するテーブルやデータはテストのたびに用意する必要がある
vitestを動かすときに、D1のテーブル作成とか登録とかをしたい。
「vitest.config.tsのsetupFilesでテスト前に呼びたいコードのパスを置けばできる」
と各種AIが教えてくれたのでコードサンプルも書かせて実行してみた。
だがログを見る限りどうもsetup.tsは動いていない。(テストは実行されている)
分かった設定/Setting
分かれば単純。
poolOptionsの中でなく、test: 中でsetupFilesの設定を行えばよい。
*LLMに書かせるとpoolOptions: の中にsetupFilesを記述していた。
// vitest.config.ts
import { defineWorkersConfig,readD1Migrations } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersConfig({
test: {
setupFiles: ['./setup.ts'], // <- here
poolOptions: {
workers: {
wrangler: {
configPath: './wrangler.jsonc',
},
miniflare: {
d1Persist: './.wrangler/state',
},
},
},
},
})
やったことの経緯
- パスのチェック
- 問題なし
- LLM(chatGPT,Cloude,Gemini)への問い合わせ
- 正解を出したのはなかった(なので時間がかかった)
- Cloudflare Docのチェック
- setupFilesで引っ掛かるのは以下のリンクのみ
- WEBでの検索
- 少し前の開発環境の話が多く、直接的なコードが見つからない。
- 結果が分かってからみればあーと思うところはあるが。
- 少し前の開発環境の話が多く、直接的なコードが見つからない。
- setpu.ts に console.log("ログ文字列") をいれて実行をチェック
- 表示されない
- node_moduleの中身をたどってデバッグ。
- node_moduleも中身全部書いてあるんだしたどればわかるだろうと調べてみた。
import { defineWorkersConfig,readD1Migrations } from '@cloudflare/vitest-pool-workers/config';
export default defineWorkersConfig({
test: {
poolOptions: {
setupFiles: './setup.ts',
workers: {
wrangler: {
configPath: './wrangler.jsonc',
},
miniflare: {
d1Persist: './.wrangler/state',
},
},
},
},
})
node_moduleの検索
node_moduleのコードを'setupFiles'で検索
最初は@vitest-pool-worker内を調べていたが、ためにはなったが原因までは遠そうだった。
視点を変えて、ファイルに'setupFiles'と中に書いてあるファイルを探し、そこを起点に原因を探ろうと思った。
こういうコードはLLMに依頼するのがよいのでGeiminiにサクッと作って貰う。
Get-ChildItem -File -Recurse |
Select-String -Pattern "setupFiles" -SimpleMatch |
Select-Object -ExpandProperty Path -Unique |
ForEach-Object {
# フルパスから $base を取り除く
$_ -replace [regex]::Escape($base), ''
}
結果は以下。cloudflare特融の@vitest\runner\distの中に手がかりがありそう。
@vitest\runner\dist\index.d.ts
@vitest\runner\dist\index.js
@vitest\runner\dist\tasks.d-hsdzc98-.d.ts
@vitest\runner\dist\types.d.ts
vitest\dist\index.d.ts
vitest\dist\node.d.ts
vitest\dist\chunks\cac.KrMo52r1.js
vitest\dist\chunks\cli-api.BzebkJv7.js
vitest\dist\chunks\config.d.UqE-KR0o.d.ts
vitest\dist\chunks\coverage.D6LCUsnS.js
vitest\dist\chunks\reporters.d.C-cu31ET.d.ts
vitest\dist\chunks\utils.CgTj3MsC.js
調べた結果、セットアップファイルがあったらcollectTestsがrunSetupFilesを呼ぶ構造になっている。そこでconsoleで関数が呼ばれたら
async function runSetupFiles(config, files, runner){
console.debug(`runSetupFiles`, files, config);
// ファイルパスのスクリプトを実行する
}
async function collectTests(specs, runner) {
console.log("collectTests");
// この中でrunSetupFilesが呼ばれている
}
上のようにデバッグ用のログを仕込んで vitest run
したところ、
collectTestsは実行されるけど、runSetupFilesは実行されないことがわかった。
試しに以下のようにオブジェクトから取得するのではなく、パス直書きにしてみたらsetupが実行された。
//const setupFiles = toArray(config.setupFiles);
const setupFiles = toArray("./setup.ts")
多分パスが伝わってないなと思い、configを出力
async function collectTests(specs, runner) {
console.log("collectTests");
const files = [];
const config = runner.config;
// config全体を出力
console.log(`[DEBUG @vitest/runner] , JSON.stringify(config, null, 2));
"setupFiles": [],
やはり空。
ただ、ログをGeminiに入れて解析してたら興味深い解析をした。
[DEBUG @vitest/runner] runner.config object: {
// ... (多くの設定) ...
"setupFiles": [], // ← ここが空の配列!
// ...
"poolOptions": {
"threads": {
"isolate": false
},
"workers": { // ← ここに setupFiles がない!
"main": "C:\\Users\\tomiy\\Documents\\GitHub\\EdgeAuth\\experiments\\12-D1Migration\\d1-test\\src\\index.ts",
"durableObjectBindingDesignators": {},
"isolatedStorage": true
}
},
// ...
"sequence": {
"hooks": "stack",
"setupFiles": undefined // ← runner.config.sequence.setupFiles も undefined
},
// ...
}
「ここが空の配列!」と言っている場所が、vitest.config.tsの内容と違う!!!
*Gemiinのこの時点ではここが原因とは気づいていない。
ということで、コードの中身を追っていくことで解決できた。
学び
設定わからない場合は、設定名でnode_moduleを検索してLLMに解析させるのは意外と近道かも。
Discussion