20251016

Vite

shadcn/uiを試そうと思った際に生じた疑問の調査。

https://ui.shadcn.com/docs/installation/vite


なぜ tsconfig.jsontsconfig.app.json に同じような記述を追加するのか。
そもそも tsconfig.json とはなにか。

npm create vite@latest で TypeScriptのプロジェクトを作成するとTypeScriptの設定ファイルが3つ現れる。

  • tsconfig.json
  • tsconfig.app.json
  • tsconfig.node.json

なぜこんなにあるのか。

そもそも tsconfig.json とは

https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

tsconfig.json があるディレクトリは TypeScript プロジェクトとみなされる。

そして tsconfig.json の中身でそのプロジェクトのコンパイラオプション、およびコンパイル対象のソースファイルを指定する。

TypeScriptのコンパイラである tsc は、入力ファイルを指定しない場合まず tsconfig.json を探す。そして見つかった tsconfig.json の内容を元にプロジェクトをコンパイルする。

つまり1つの tsconfig.json = 1つのコンパイラ設定と言える。

Viteにはコンパイラ設定が最低限2つ必要

Viteで扱うTypeScriptファイルは主に2種類ある。

  • ブラウザ上で動作するプログラム
    • CSRで動作するプログラム
    • その他諸々。とにかくそのプロジェクトのユーザーによってブラウザ上で実行されるもの。
  • Node.js上で動作するプログラム
    • Viteの設定ファイル(vite.config.ts)
    • Vite用のプラグイン
    • SSRで動作するプログラム
    • その他諸々。とにかくNode.js上で実行されるもの。

これらはそれぞれコンパイル結果やコンパイル方法が異なる。(実行できるJavaScriptのバージョンが異なる、必要な型定義が異なる、など)

そのため、ブラウザ上で実行されるプログラム用の tsconfig.app.json と、Node.js上で実行されるプログラム用の tsconfig.node.json を用意し、それぞれのコンパイラ設定を記述する。

テスト用のコンパイラ設定や、SSRが動作するサーバー用のコンパイラ設定も必要に応じて用意しないといけないかもしれない。

※厳密にはViteのビルド処理自体はesbuildを使うため、 tsconfig.node.json を参照するわけではないらしい。ただしエディタの型解析などでは tsconfig.node.json の設定が参照される。

※※よくみたら tsconfig.node.jsoninclude には vite.config.ts しかないのでこれだけのために存在する説アリ。ゴリゴリにViteを使う場合は include に独自に追加したりすることもあるのかな?

tsconfig.json の意義

では tsconfig.json の存在意義はなにか。

1つはプロジェクト全体のルートを示すため。
tsctsconfig.json を探してプロジェクトのルートを割り出す。

もう1つは tsc -b でビルドを実行したときに各コンパイラ設定をもとにそれぞれをコンパイルするため。

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

references でそれぞれの設定ファイルを指定することで、これらが順にコンパイルされる。

エディタも tsconfig.json を参照する

コンパイラ設定はコンパイル時だけでなくファイルの静的解析にも使用される。

エディタは現在開いているTypeScriptファイルがどのコンパイル設定を使用するかを判別し、そのコンパイラ設定に基づいて静的解析を行い、エラーがあればそれを表示する。

tsconfig.app.jsontsconfig.node.json には「どのファイルを対象とするか」という設定も含まれるため、エディタは特定のファイルに対してどのコンパイラ設定に基づくかを判別できる。

なぜ shadcn/ui では tsconfig.js にも “compilerOptions” を追加するのか

わからない。

が、shadcn/ui の仕様という線が濃厚かも。
npx shadcn@latest init を実行する際に tsconfig.json にインポートエイリアスの指定がないとエラーが出るとのこと。
https://github.com/shadcn-ui/ui/discussions/4702

(コンポーネントを生成するときにエイリアスでのインポートを行いたい?)

では tsconfig.json にだけ記述すればいいかというとそうではなく、エディタが参照するのは tsconfig.app.json なのでそちらにも記述が必要。