Viteは「ヴィート」と読む、フランス語で「速い」を意味するフロントエンドビルドツールです。Vueの作者であるEvan Youが開発し、今やReact・Vue・Svelteを問わず広く使われています。
TypeScriptと組み合わせるとき、「vite.config.tsの書き方がわからない」「パスエイリアスの設定でハマった」「環境変数の型がstringしか付かない」といった疑問が出てきます。本記事ではVite + TypeScript環境を一から構築し、実務で必要な設定を体系的に解説します。
- Viteが速い理由とTypeScriptとの相性
npm create vite@latestでプロジェクトを作成する手順vite.config.tsの型定義とdefineConfig()の使い方- パスエイリアス(
@/)の設定方法(tsconfig連携含む) import.meta.envの型定義と環境変数の管理- 型チェックとビルドを分離する理由と設定方法
- Vitestとの統合設定
Viteを初めて使う方から、すでに使っているが設定に自信がない方まで、この記事で実務レベルの環境が整います。
なお、TypeScriptのtsconfig.json全般についてはTypeScript tsconfig.json 完全ガイドもあわせてご覧ください。
ViteとTypeScriptの相性が良い理由
Viteには「開発サーバーが速い」以外にも、TypeScriptと相性が良い特徴があります。
| 特徴 | 内容 |
|---|---|
| TypeScript標準サポート | 追加プラグイン不要でTSファイルをそのまま扱える。.tsファイルをesbuildでトランスパイル |
| vite.config.tsが書ける | 設定ファイル自体をTypeScriptで書けるため、型補完・型検証が効く |
| ESモジュールネイティブ | TypeScriptのESM設定(moduleResolution: "bundler")との相性が良い |
| 環境変数の型定義 | import.meta.envを拡張する仕組みがあり、型安全に環境変数を扱える |
| Vitest | Viteと共通設定で動くテストランナー。Jestより型まわりの設定が少ない |
Viteの開発サーバーはesbuildでTSをトランスパイルするだけで型チェックを行いません。型エラーがあっても開発中は気付きにくいため、CIやエディタで
tsc --noEmitを別途実行する必要があります。これはViteの重要な特性なので、後述の「型チェックとビルドの分離」で詳しく解説します。プロジェクトの作成
Viteはプロジェクト作成用のCLIを提供しています。対話形式でフレームワークと言語を選べます。
# npm npm create vite@latest my-app # yarn yarn create vite my-app # pnpm pnpm create vite my-app
コマンドを実行すると対話形式でフレームワークを選択できます。
? Select a framework: › - Use arrow-keys.
Vanilla
Vue
❯ React
Preact
Lit
Svelte
Solid
Qwik
Angular
Others
? Select a variant: › - Use arrow-keys.
TypeScript
❯ TypeScript + SWC
JavaScript
JavaScript + SWC
- TypeScript: esbuildでトランスパイル(デフォルト)
- TypeScript + SWC: Rustで書かれたSWCでトランスパイル。Reactのfastリフレッシュが高速になる
新規プロジェクトではSWCを選ぶとHMR(Hot Module Replacement)がさらに速くなるためおすすめです。
cd my-app npm install npm run dev
デフォルトではhttp://localhost:5173で開発サーバーが起動します。
生成されるファイル構成
Reactテンプレートで生成されるファイル構成は以下の通りです。
my-app/ ├── public/ # 静的ファイル(ビルド時にそのままコピー) ├── src/ │ ├── assets/ │ ├── App.tsx │ ├── main.tsx # エントリーポイント │ └── vite-env.d.ts # Vite環境変数の型定義 ├── index.html # エントリーHTML(publicではなくルートに置く) ├── package.json ├── tsconfig.json # ルートのtsconfig(参照設定) ├── tsconfig.app.json # アプリコードのtsconfig ├── tsconfig.node.json # vite.config.ts用のtsconfig └── vite.config.ts
Vite v5以降のテンプレートでは
tsconfig.jsonが3つに分割されています。tsconfig.jsonはルートのみでreferencesとしてtsconfig.app.jsonとtsconfig.node.jsonを参照します。tsconfig.app.jsonがブラウザ向けコード、tsconfig.node.jsonがVite設定ファイル向けです。これはTypeScriptのProject Referencesという機能を活用したものです。生成されるtsconfig.jsonの解説
Vite + React + TypeScriptテンプレートで生成されるtsconfig.app.jsonを確認します。
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* バンドラーモード */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* リント */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
| 設定 | 意味 |
|---|---|
moduleResolution: "bundler" |
Vite(バンドラー)向けの解決方法。拡張子省略・index.ts省略が使える |
allowImportingTsExtensions |
import "./foo.ts"のように拡張子付きでインポートできる |
isolatedModules: true |
esbuildでの単一ファイルトランスパイルに対応。const enumなどの非対応構文を禁止 |
noEmit: true |
型チェックのみ実行(JSファイルの生成はViteに任せる) |
noUnusedLocals/Parameters |
未使用の変数・引数をエラーにする |
vite.config.tsの書き方
vite.config.tsはViteの設定ファイルです。defineConfig()でラップすることで型補完が効きます。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
});
defineConfig()にはコールバック関数を渡すこともできます。これによりmode(development/production)やcommand(serve/build)を参照できます。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig(({ command, mode }) => {
console.log("command:", command); // "serve" または "build"
console.log("mode:", mode); // "development" または "production"
return {
plugins: [react()],
build: {
sourcemap: mode === "development",
},
};
});
よく使う設定オプション
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
// 開発サーバーの設定
server: {
port: 3000, // ポート番号
open: true, // 起動時にブラウザを開く
cors: true, // CORSを有効化
proxy: {
// /api/* へのリクエストをバックエンドにプロキシ
"/api": {
target: "http://localhost:8080",
changeOrigin: true,
},
},
},
// ビルドの設定
build: {
outDir: "dist", // 出力ディレクトリ
sourcemap: true, // ソースマップ生成
target: "es2020", // ターゲット環境
rollupOptions: {
output: {
// チャンクの分割設定
manualChunks: {
vendor: ["react", "react-dom"],
},
},
},
},
// 依存関係の最適化
optimizeDeps: {
include: ["react", "react-dom"],
},
});
パスエイリアスの設定
プロジェクトが大きくなると../../components/Buttonのような相対パスが煩雑になります。@/などのエイリアスを使うと@/components/Buttonとシンプルに書けます。
設定は2箇所に必要です。①Viteのモジュール解決と②TypeScriptの型解決を両方設定しないと、実行時エラーまたは型エラーが発生します。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
"@components": path.resolve(__dirname, "./src/components"),
"@hooks": path.resolve(__dirname, "./src/hooks"),
"@utils": path.resolve(__dirname, "./src/utils"),
"@types": path.resolve(__dirname, "./src/types"),
},
},
});
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@hooks/*": ["./src/hooks/*"],
"@utils/*": ["./src/utils/*"],
"@types/*": ["./src/types/*"]
}
}
}
pathの型定義が必要import path from "path"をvite.config.ts内で使うには@types/nodeが必要です。npm install --save-dev @types/nodeでインストールしてください。またtsconfig.node.jsonのtypesに"node"を追加してください。vite-tsconfig-pathsプラグインを使う方法
vite.config.tsのresolve.aliasとtsconfig.jsonのpathsを二重管理するのが手間な場合、vite-tsconfig-pathsプラグインを使うとtsconfig.jsonの設定を自動でViteに適用できます。
npm install --save-dev vite-tsconfig-paths
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
react(),
tsconfigPaths(), // tsconfig.json の paths を自動でViteに適用
],
});
このプラグインを使うとtsconfig.app.jsonのpathsを設定するだけで済み、resolve.aliasが不要になります。
// Before: 相対パス(深いネストで読みにくい)
import { Button } from "../../components/ui/Button";
import { useAuth } from "../../../hooks/useAuth";
// After: パスエイリアス(すっきり読める)
import { Button } from "@/components/ui/Button";
import { useAuth } from "@/hooks/useAuth";
環境変数の型定義
Viteではimport.meta.envを通じて環境変数にアクセスします。デフォルトではstring型のみで型補完が利きません。型定義ファイルを作成することで型安全に使えます。
基本の仕組み
Viteは.envファイルの変数を読み込みますが、VITE_プレフィックスが付いた変数のみクライアントコードに公開されます。
# VITE_ プレフィックスつき → クライアントコードに公開される VITE_API_BASE_URL=https://api.example.com VITE_APP_TITLE=MyApp VITE_FEATURE_FLAG_NEW_UI=true # VITE_ なし → サーバーサイド専用(クライアントからアクセス不可) DATABASE_URL=postgresql://... SECRET_KEY=super-secret
VITE_API_BASE_URL=http://localhost:8080 VITE_ENABLE_DEVTOOLS=true
VITE_API_BASE_URL=https://api.example.com VITE_ENABLE_DEVTOOLS=false
型定義ファイルの作成
src/vite-env.d.ts(またはsrc/env.d.ts)にImportMetaEnvを拡張します。
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string;
readonly VITE_APP_TITLE: string;
readonly VITE_FEATURE_FLAG_NEW_UI: string; // "true" | "false" の文字列
readonly VITE_ENABLE_DEVTOOLS: string;
// 他の環境変数を追加していく...
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
この定義があることでimport.meta.env.VITE_API_BASE_URLがstring型として補完されます。
// 型補完が効く
const apiUrl = import.meta.env.VITE_API_BASE_URL; // string 型
const appTitle = import.meta.env.VITE_APP_TITLE; // string 型
// 存在しない変数はエラーになる
const unknown = import.meta.env.VITE_UNKNOWN; // TypeScriptエラー(定義されていない)
// boolean に変換して使う
const isNewUiEnabled = import.meta.env.VITE_FEATURE_FLAG_NEW_UI === "true";
// Viteビルトインの環境変数
if (import.meta.env.DEV) {
console.log("開発モードです");
}
if (import.meta.env.PROD) {
console.log("本番モードです");
}
| Viteビルトイン変数 | 型 | 内容 |
|---|---|---|
import.meta.env.MODE |
string |
現在のモード(”development”, “production” など) |
import.meta.env.BASE_URL |
string |
デプロイのベースURL(vite.configのbaseオプションの値) |
import.meta.env.PROD |
boolean |
本番ビルドかどうか |
import.meta.env.DEV |
boolean |
開発モードかどうか |
import.meta.env.SSR |
boolean |
SSRビルドかどうか |
型チェックとビルドを分離する
前述の通り、Viteは型チェックをしません。型エラーを見落とさないためにCIパイプラインやpackage.jsonのスクリプトに型チェックを組み込みます。
{
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"type-check": "tsc --noEmit",
"lint": "eslint . --ext ts,tsx",
"preview": "vite preview"
}
}
tsc -bはProject References(tsconfig.jsonのreferences設定)に対応したビルドコマンドです。tsc --noEmitは型チェックのみ実行しJSファイルを生成しません。
vite-plugin-checkerを使うと開発サーバー実行中にもTypeScriptの型エラーをブラウザのオーバーレイや端末に表示できます。npm install --save-dev vite-plugin-checker
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import checker from "vite-plugin-checker";
export default defineConfig({
plugins: [
react(),
checker({
typescript: true, // TypeScript型チェックを有効化
}),
],
});
Vitestとの統合設定
VitestはViteと共通の設定ファイルで動作するテストランナーです。vite.config.tsにtestセクションを追加するだけで設定できます。
npm install --save-dev vitest @vitest/ui jsdom @testing-library/react @testing-library/jest-dom
/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
test: {
globals: true, // describe, it, expect をインポート不要にする
environment: "jsdom", // ブラウザ環境をシミュレート
setupFiles: "./src/test/setup.ts",
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
},
},
});
import "@testing-library/jest-dom";
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}
Vitestでのテストの書き方全般についてはTypeScript Jest・Vitest テスト完全ガイドを参照してください。
実務的なvite.config.tsのサンプル
ここまでの設定をまとめた、実務で使えるフル設定サンプルです。
/// <reference types="vitest" />
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react-swc";
import tsconfigPaths from "vite-tsconfig-paths";
import checker from "vite-plugin-checker";
import path from "path";
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
return {
plugins: [
react(),
tsconfigPaths(),
checker({ typescript: true }),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
server: {
port: 3000,
proxy: {
"/api": {
target: env.API_TARGET_URL || "http://localhost:8080",
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, ""),
},
},
},
build: {
outDir: "dist",
sourcemap: mode !== "production",
rollupOptions: {
output: {
manualChunks: {
vendor: ["react", "react-dom"],
},
},
},
},
test: {
globals: true,
environment: "jsdom",
setupFiles: "./src/test/setup.ts",
},
};
});
よくあるエラーと解決策
エラー①:Cannot find module ‘path’
Cannot find module 'path' or its corresponding type declarations.
# @types/node をインストール npm install --save-dev @types/node
{
"compilerOptions": {
"types": ["node"]
}
}
エラー②:パスエイリアスが実行時に解決されない
// TypeScriptのコンパイルは通るが、Viteの開発サーバーで
// "Failed to resolve import @/components/Button" エラーが発生する
import { Button } from "@/components/Button";
// 原因: tsconfig.json の paths を設定しただけで
// vite.config.ts の resolve.alias が設定されていない
// 解決策①: vite.config.ts に resolve.alias を追加する
resolve: {
alias: { "@": path.resolve(__dirname, "./src") },
},
// 解決策②: vite-tsconfig-paths プラグインを使う
// tsconfig.json の paths が自動でViteに適用される
plugins: [react(), tsconfigPaths()],
エラー③:import.meta.envの型が効かない
// import.meta.env.VITE_API_URL が any または string になる const url = import.meta.env.VITE_API_URL; // ^^^^^^^^^^^^^^ 型補完が効かない
// src/vite-env.d.ts に ImportMetaEnv の拡張を追加する
interface ImportMetaEnv {
readonly VITE_API_URL: string;
}
// tsconfig.app.json の include に src が含まれていることも確認する
// "include": ["src"]
エラー④:const enumがエラーになる
Cannot access ambient const enums when 'isolatedModules' is enabled.
// NG: const enum は isolatedModules: true と非互換
const enum Direction {
Up, Down, Left, Right
}
// OK①: 通常の enum に変更する
enum Direction {
Up, Down, Left, Right
}
// OK②: union型やオブジェクトで代替する
const Direction = { Up: "up", Down: "down", Left: "left", Right: "right" } as const;
type Direction = typeof Direction[keyof typeof Direction];
const enumとその代替についてはTypeScript enum 完全ガイドを参照してください。
エラー⑤:defineConfigの型エラー
Type '{ test: { globals: boolean; ... } }' is not assignable to type 'UserConfigExport'.
// 解決策: vite.config.ts の先頭に vitest の型参照を追加する
/// <reference types="vitest" />
import { defineConfig } from "vite";
// これがないと test: {} プロパティが UserConfig の型に存在せずエラーになる
まとめ
ViteとTypeScriptの設定における重要ポイントをまとめます。
| 項目 | ポイント |
|---|---|
| 型チェック | Viteは型チェックしない。tsc --noEmitをCIやビルドスクリプトに組み込む |
| tsconfig | Vite v5以降はtsconfig.app.jsonとtsconfig.node.jsonを分離。moduleResolution: "bundler"が推奨 |
| パスエイリアス | tsconfig のpathsとvite.configのresolve.aliasの両方が必要。vite-tsconfig-pathsで一元管理可能 |
| 環境変数 | VITE_プレフィックスでクライアントに公開。ImportMetaEnvを拡張して型補完を有効化 |
| Vitest | vite.config.tsのtestセクションで設定。/// <reference types="vitest" />が必要 |
| const enum | isolatedModules: trueと非互換。通常のenumかunion型で代替 |
ViteはTypeScriptプロジェクトのビルドツールとして現在最もおすすめできる選択肢の一つです。設定ファイル自体が型安全に書けるのは大きなメリットで、チーム開発でも設定ミスを防ぎやすくなります。
ESLintやPrettierとの組み合わせについてはTypeScript ESLint + Prettier 完全セットアップガイドを、モジュールシステムの詳細についてはTypeScript モジュールとimport/export完全ガイドもあわせてご覧ください。

