
SvelteKitのvite.config.tsとtsconfig.jsonの役割を整理する
SvelteKitで迷いやすいvite.config.tsとtsconfig.jsonの役割を整理。include/exclude、SSR external/noExternal、ビルドに含める・含めない設定、よくあるハマりポイントを初心者向けに解説します。
この記事で整理すること
01 設定ファイルごとの役割
02 tsconfig.json の include / exclude
03 vite.config.ts の external / noExternal
04 ビルド時によくあるハマりポイント
05 実践用の設定例
SvelteKit を使っていると、あるタイミングで必ず設定ファイルまわりに迷います。
vite.config.ts 、svelte.config.js 、tsconfig.json 、そして自動生成される.svelte-kit/tsconfig.json 。それぞれ名前は見たことがあっても、 どの設定をどこに書くべきか は意外とわかりにくいです。
特にハマりやすいのが、「このファイルをビルドに含めたくない」「この依存パッケージはバンドルしたくない」「exclude に書いたのにビルドエラーが消えない」といった場面です。
🎯 この記事の結論
tsconfig.json は TypeScript の型チェックやエディタ補完のための設定です。SvelteKit のビルド対象を直接コントロールする設定ではありません。
ビルド・バンドル・SSR の依存関係を調整する場合は、主にvite.config.ts を見ます。
SvelteKit に登場する設定ファイルの全体像
まずは、それぞれのファイルの役割をざっくり整理します。ここが曖昧なままだと、tsconfig.json に書くべきではない設定を追加してしまったり、逆にvite.config.ts で制御すべき内容を見落としたりします。
svelte.config.js
SvelteKit 本体の設定
adapter、alias、kit 設定などを書きます。SvelteKit としての振る舞いを決める中心的な設定ファイルです。
vite.config.ts
Vite の設定
plugins、dev server、build、SSR 外部化、Vitest 設定などを書きます。ビルド挙動に大きく関わります。
tsconfig.json
TypeScript の設定
型チェック、パス解決、include / exclude、strict などを設定します。ビルド除外の設定ファイルではありません。
.svelte-kit/tsconfig.json
SvelteKit が自動生成する設定
SvelteKit が必要とする TypeScript 設定が入ります。基本的に直接編集しません。
| やりたいこと | 主に見るファイル | 理由 |
|---|---|---|
| adapter を変更したい | svelte.config.js | SvelteKit 本体の設定だから |
| 開発サーバーのポートを変えたい | vite.config.ts | Vite dev server の設定だから |
| 型チェック対象を調整したい | tsconfig.json | TypeScript の対象ファイルを調整するため |
| SSR ビルドで特定パッケージを外部化したい | vite.config.ts | Vite の SSR / Rollup 設定で制御するため |
| 本番で開発用ページを見せたくない | hooks.server.ts など | 型設定ではなくルーティング制御が必要だから |
💡 SvelteKit は Vite プロジェクトでもある
SvelteKit プロジェクトは、@sveltejs/kit/vite プラグインを使った Vite プロジェクトです。そのため、開発サーバーやビルドの細かい挙動はvite.config.ts 側で調整することが多くなります。
tsconfig.json の役割:型チェックとエディタ補完
tsconfig.json は、TypeScript がプロジェクトをどのように解釈するかを決める設定ファイルです。SvelteKit では、基本的に.svelte-kit/tsconfig.json を継承して使います。
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
} 重要なのはextends です。SvelteKit は.svelte-kit/tsconfig.json を自動生成し、その中に$lib や$types など、SvelteKit プロジェクトに必要な設定を含めます。
⚠️ 直接編集しない
.svelte-kit/tsconfig.json は生成物です。.svelte-kit を削除したり、svelte-kit sync が走ったりすると再生成されます。自分の設定はプロジェクトルートのtsconfig.json に書きます。
include / exclude は何をする設定か
include とexclude は、TypeScript がどのファイルを型チェック対象として扱うかを調整するための設定です。
{
"extends": "./.svelte-kit/tsconfig.json",
"exclude": [
"node_modules",
"build",
".svelte-kit",
"dist",
"coverage",
"playwright-report",
"test-results"
]
} ここで一番大事なのは、exclude は「ビルドに含めない設定」ではない という点です。
✨ よくある誤解
exclude に書いたファイルでも、アプリ側からimport していれば依存関係として読み込まれます。つまり、exclude は「絶対に使わせない設定」ではありません。
exclude に書いたのに読み込まれる例
たとえばscripts フォルダを除外したとします。
{
"exclude": ["scripts/**"]
}しかし、アプリ側で次のように import していたら、TypeScript やビルドツールはそのファイルを依存関係として扱います。
import { runTask } from '../../scripts/run-task';
export const load = async () => {
await runTask();
}; この場合、exclude に書いたからといって安全ではありません。使いたくないファイルは、そもそもアプリ側から import しない設計にする必要があります。
vite.config.ts の役割:開発サーバー・ビルド・SSR の設定
vite.config.ts は、SvelteKit アプリを Vite がどのように扱うかを決める設定ファイルです。
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()]
}); Tailwind CSS v4 を使っている場合は、次のように@tailwindcss/vite を追加する構成もよく使います。
import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
server: {
port: 5160,
strictPort: true
}
});| 設定 | 役割 | 例 |
|---|---|---|
plugins | Vite プラグインを読み込む | sveltekit() 、tailwindcss() |
server | 開発サーバーの設定 | ポート番号、host、strictPort |
build | ビルド時の Rollup 設定 | rollupOptions.external |
ssr | SSR ビルド時の依存関係制御 | external 、noExternal |
test | Vitest の設定 | テスト対象、browser test 設定など |
ビルドに含めたくないものはどこで制御するのか
ここが一番ハマりやすいポイントです。「含めたくない」と言っても、実は何を外したいのかによって書く場所が変わります。
| やりたいこと | 書く場所 | 考え方 |
|---|---|---|
| 型チェック対象から外したい | tsconfig.json | exclude を使う |
| SSR ビルドでバンドルしたくない | vite.config.ts | ssr.external を使う |
| Rollup のバンドル対象から外したい | vite.config.ts | build.rollupOptions.external を使う |
| ルーティング対象にしたくない | ファイル配置 | src/routes の外へ出す |
| 本番でアクセスさせたくない | hooks.server.ts など | production 時に 404 などで制御する |
Node.js 専用ライブラリをバンドルしたくない例
たとえばplaywright 、playwright-core 、chromium-bidi のようなパッケージは、通常の画面表示では使わず、OG画像生成や開発用処理でだけ使うことがあります。 このような依存関係を SSR ビルドにそのまま巻き込むと、ビルド後のサーバーチャンクに不要な参照が残ったり、実行環境でCannot find module 系のエラーが出たりすることがあります。
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
const isExternal = (id: string) => {
return (
id === 'playwright' ||
id === 'playwright-core' ||
id === 'chromium-bidi' ||
id.startsWith('playwright/') ||
id.startsWith('playwright-core/') ||
id.startsWith('chromium-bidi/')
);
};
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
ssr: {
external: ['playwright', 'playwright-core', 'chromium-bidi']
},
build: {
rollupOptions: {
external: isExternal
}
}
});⚠️ external は削除ではない
external は「不要だから消す」設定ではありません。ビルド成果物にバンドルせず、実行時にnode_modules から読み込むようにする設定です。 つまり、本番環境でそのコードが実行されるなら、該当パッケージは本番環境にもインストールされている必要があります。
コード側では dynamic import も検討する
そもそも通常のリクエスト処理で使わない重いライブラリは、静的 import ではなく dynamic import にする方が安全です。
// static import ではなく、必要なタイミングで読み込む
const { chromium } = await import('playwright');
const browser = await chromium.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});この形にしておくと、通常のアプリ起動時に Playwright を読み込まず、OG 画像生成など必要な処理のタイミングだけ読み込めます。
ビルドに含めたいものはどこで制御するのか
逆に、SSR ビルド時に外部化せず、Vite の変換を通したい依存関係もあります。その場合はssr.noExternal を使います。
export default defineConfig({
plugins: [sveltekit()],
ssr: {
noExternal: ['some-package']
}
});noExternal は、指定した依存関係を SSR ビルド時に外部化せず、バンドル側に含めたいときに使います。
| 設定 | 意味 | 使う場面 |
|---|---|---|
ssr.external | SSR ビルドで外部化する | Node.js 側でそのまま読み込ませたい依存関係 |
ssr.noExternal | SSR ビルドで外部化しない | Vite の変換を通したい依存関係 |
rollupOptions.external | Rollup のバンドルから外す | 深い import まで外部化したい場合など |
✨ 最小限にする
external やnoExternal は、何でも追加すればよい設定ではありません。対象を広げすぎると、ビルドが重くなったり、別の依存関係トラブルを招いたりします。必要なパッケージだけを最小限に指定するのが基本です。
src/routes に置いたものはルーティング対象になる
SvelteKit では、src/routes 配下のファイル構成がそのままルーティングに関わります。 そのため、開発用のページや実験用のページをsrc/routes に置いたままにしていると、本番でもルートとして存在することになります。
src/routes/
├ devonly/
│ └ og/
│ └ +page.svelte
├ sample/
│ └ +page.svelte
└ posts/
└ [category]/
└ [slug]/
└ +page.sveltetsconfig.json のexclude にsrc/routes/devonly/** と書いても、SvelteKit のルーティング対象から外れるわけではありません。
⚠️ ルーティング除外は exclude ではない
ルーティングさせたくないファイルは、src/routes の外に置くか、本番環境でアクセスできないようにサーバー側で制御します。
本番で開発用ルートを見せない例
開発用ルートを残したい場合は、production では 404 にする方法があります。
import { dev } from '$app/environment';
import { error } from '@sveltejs/kit';
import type { Handle } from '@sveltejs/kit';
const mode = process.env.VITE_NODE_ENV;
export const handle: Handle = async ({ event, resolve }) => {
const devOnlyRoutes = ['/devonly'];
const isProd = !dev && mode === 'production';
if (isProd && devOnlyRoutes.some((path) => event.url.pathname.startsWith(path))) {
throw error(404, 'Not Found');
}
return resolve(event);
};ただし、もっと安全にするなら、開発専用ページ自体を本番ビルド対象のルートに置かない設計も検討してください。
よくあるハマりポイント
ここからは、SvelteKit の設定まわりで実際によく起きる問題を整理します。
❓ exclude に書いたのにビルドエラーが消えない
exclude は TypeScript の型チェック対象を調整する設定です。アプリ側から import されているファイルや、Vite / SvelteKit が処理する依存関係を強制的に消すものではありません。ビルドや SSR の依存関係はvite.config.ts 側を確認します。
❓ .svelte-kit/tsconfig.json がないと警告が出る
.svelte-kit は生成ディレクトリです。削除直後や、まだ SvelteKit の sync が走っていない状態では警告が出ることがあります。bunx svelte-kit sync 、またはbun run dev で再生成します。
$ bunx svelte-kit sync
# または開発サーバーを起動する
$ bun run dev❓ test 設定を vite.config.ts に残してよいかわからない
Vitest を使っているならtest 設定自体は問題ありません。ただし、browser test 用に Playwright などの重い依存を常に読み込む構成だと、本番ビルド側の依存関係が複雑になることがあります。
import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
});❓ src/lib/server に置けばクライアントに絶対入らないと思っている
src/lib/server はサーバー専用コードを置く場所として便利です。ただし、クライアント側の.svelte コンポーネントや通常の+page.ts から import しないことが前提です。サーバー専用処理は+page.server.ts 、+layout.server.ts 、+server.ts などから使うように整理します。
❓ external にしたのに本番で Cannot find module が出る
external はバンドルしない設定なので、実行時にはnode_modules から対象パッケージを読み込みます。Docker の runner ステージに依存パッケージが存在しない場合、本番実行時にCannot find module が出ることがあります。
設定に迷ったときの判断フロー
何をどこに書けばよいかわからなくなったら、次の順番で考えると整理しやすいです。
1
型チェックやエディタ補完の話か?
はい →tsconfig.json を確認します。include /exclude /compilerOptions の領域です。
2
ビルドや SSR の依存関係の話か?
はい →vite.config.ts を確認します。ssr.external /ssr.noExternal /rollupOptions.external の領域です。
3
SvelteKit の adapter や alias の話か?
はい →svelte.config.js を確認します。SvelteKit 本体の設定はここです。
4
本番でルートを見せたくない話か?
はい →exclude ではなく、ファイル配置、ルーティング、hooks.server.ts で制御します。
実践用の vite.config.ts / tsconfig.json 例
最後に、実運用で使いやすい形のサンプルをまとめます。必要に応じて、自分のプロジェクトに合わせて削ってください。
tsconfig.json
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
},
"exclude": [
"node_modules",
"build",
".svelte-kit",
"dist",
"coverage",
"playwright-report",
"test-results"
]
} vite.config.ts
import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
const isExternal = (id: string) => {
return (
id === 'playwright' ||
id === 'playwright-core' ||
id === 'chromium-bidi' ||
id.startsWith('playwright/') ||
id.startsWith('playwright-core/') ||
id.startsWith('chromium-bidi/')
);
};
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
server: {
port: 5160,
strictPort: true
},
ssr: {
external: ['playwright', 'playwright-core', 'chromium-bidi']
},
build: {
rollupOptions: {
external: isExternal
}
},
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
});💡 この設定例の考え方
tsconfig.json では型チェック対象を整理し、vite.config.ts では Vite の開発・ビルド・SSR の挙動を制御しています。
特にplaywright 関連は、通常の画面表示では使わず、OG 画像生成などサーバー側の特定処理でだけ使う場合を想定しています。
まとめ
今回学んだこと
tsconfig.jsonは TypeScript の型チェックやエディタ補完のための設定excludeはビルド除外ではなく、型チェック対象の調整vite.config.tsは Vite の開発サーバー・ビルド・SSR 設定を扱う- SSR ビルドでバンドルしたくない依存は
ssr.externalやrollupOptions.externalを検討する externalは削除ではなく、実行時にnode_modulesから読む設定src/routesに置いたものはルーティング対象になるため、excludeでは制御できない- 本番で見せたくないルートは、ファイル配置や
hooks.server.tsで制御する
📌 設定ファイルを分けて考える
SvelteKit の設定で迷ったら、「型チェックの話なのか」「ビルドの話なのか」「ルーティングの話なのか」を最初に分けると整理しやすくなります。
tsconfig.json でビルドを制御しようとしない。vite.config.ts で型チェックを制御しようとしない。この線引きを覚えておくだけで、設定まわりのトラブルはかなり解決しやすくなります。