8
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?

More than 1 year has passed since last update.

ZOZOAdvent Calendar 2023

Day 16

Vitestの内部で使われているvite-nodeを紐解く

Posted at

この記事はZOZO Advent Calendar 2023 シリーズ3 16日目の記事です。

vite-nodeとは

vite-nodeは、Vitestの内部で利用され、Vitestと共に開発されているライブラリでTypeScriptのトランスパイルなどをよしなにやってくれるランタイムのようなものです。
TypeScriptのトランスパイルをよしなにやってくれるランタイムのようなソリューションは思いつくだけでもいくつかあります。
BunDenots-nodetsxtsimpなど。

対してvite-nodeは、TypeScriptだけではなく、CSSや画像、Vite(Rollup)用プラグインによってVue.jsやSvelteのコンポーネントファイルなどもサポートできます。
Vitestでは、vite-nodeを内部的に利用することでJestでは設定が複雑になっていたUIコンポーネントのテストなどをより簡潔にできるようにしています。

vite-nodeの使い方

vite-nodeはts-nodeのようにコマンドラインから実行することができます。

vite-node src/index.ts

また、ここでは省略しますが、プログラムに組み込んで利用することもできます。

vite-nodeの仕組み

vite-nodeを紐解くには、Viteの仕組みを理解する必要があります。

Viteの仕組み

ここでは、Viteの開発サーバーの仕組みを簡単に紹介します。

StackBlitzでPlaygroundを用意しました。
Vite(Vue.js+TypeScript)のテンプレートのままです。

上記のPlaygroundにアクセスすると、Viteの開発サーバーが立ち上がります。
(PC)画面右では、プレビューが表示されます。

DevToolsのNetworkタブを開き、プレビューをリロードするとネットワークのログが閲覧できます。

image.png

一番上のログは / へのアクセスで /index.html 相当が返されていることが確認できます。
その中には、 <script type="module" src="/src/main.ts"></script> が含まれています。

image.png

ブラウザは、このスクリプトを読み込むため、 /src/main.ts にアクセスしてファイルを取得します。
ブラウザはTypeScriptを実行できないので、Viteの開発サーバーは /src/main.ts をトランスパイルして返します。

image.png

さらに、main.tsでは /src/App.vue をimportしているのでファイルを取得します。
(元のファイルでは ./App.vue をimportしていますが、絶対パス相当に変換されます)
当然、ブラウザは .vue ファイルを解釈できないので、Viteの開発サーバーは /src/App.vue をJavaScript相当に変換して返します。

image.png

このように、Viteではモジュール単位でサーバーに問い合わせてJust-in-timeにトランスパイル処理などをしています。
これにより、開発時はバンドル処理などを(ほぼ)省略でき、高速な開発ができるようになっています。

※ネットワークリクエストはモジュールの数だけ増えますが、基本的にはローカルでの利用が想定されているために大きな問題にはなりません。
※当たり前のように書いていますが、Vite以前はモジュールごとにリクエストせず、ほぼすべてのモジュールを1ファイルにバンドルするのが主流でした。

vite-nodeの仕組み

Viteは先に確認したように、サーバーとクライアントの仕組みで動作しています。

vite-nodeは、Viteのサーバーを動作させつつ、クライアント側もNode.js上で再現しています。
つまり、Viteの開発サーバーで動作を確認したようにモジュール毎にサーバー側へ問い合わせ、トランスパイルなどのステップが行われています。
トランスパイルされたコードは node:vm モジュールの script.runInThisContext で実行されます。

当然ですが、Vite(Rollup)で動作するプラグインによるモジュール解決が行われます。
Vue.jsやSvelteなどの開発者はVite向けのプラグインを作るだけでvite-node、Vitestの対応も完了します。

まとめ

vite-nodeはVitestの内部で使われているライブラリです。
Viteの仕組みを活用することで、通常そのまま実行できない言語やファイルを処理しNode.js上でそれらの実行を可能にします。

上では述べていませんが、Bunも本体側がPlugin(Loader)の機能を持つことで同等の処理を実現しています。
しかしながら、Vitest(vite-node)はViteをフロントエンドフレームワークのコアに持ち併用する場合には、追加の設定などは不要になり複雑怪奇な設定地獄から解放してくれることでしょう。

8
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
8
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?