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

速さ優先 or 品質優先?Vue + Vite プロジェクトでの tsconfig 二刀流サンプル

Posted at

要点まとめ

  • Node側(設定/ビルド/スクリプト)とブラウザ側(アプリ本体)の型世界は分離するのが基本
  • まずは“緩め”で開発速度重視 → バグの芽が見えたら“固め”へ段階的に引き上げる
  • Vitest を使うなら typesvitest、Vite の環境変数補完に vite/client を入れる
  • CI では vue-tsc --noEmit を併用して SFC の型を厳格にチェックする

なぜ分ける?(Node / App)

  • Node側: vite.config.ts, vitest.config.ts, playwright.config.ts など。process, fs など Node固有の型を使う
  • App側: src/**/*.ts, src/**/*.vuewindow, document など DOMの型や .vue SFC を扱う

同じ設定で混在させると、Nodeの型とDOMの型が衝突しやすいため、プロジェクト参照で分離するのがベストプラクティスです。

ディレクトリ前提

.
├─ tsconfig.json
├─ tsconfig.node.json
├─ tsconfig.app.json
├─ env.d.ts
├─ vite.config.ts
├─ vitest.config.ts
└─ src/
   ├─ main.ts
   ├─ App.vue
   └─ ...

1) “緩め”の tsconfig(導入しやすい・スピード優先)

tsconfig.json(ルート:参照元)

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

tsconfig.node.json(Node / ツール)

{
  "extends": "@tsconfig/node22/tsconfig.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "cypress.config.*",
    "nightwatch.conf.*",
    "playwright.config.*",
    "eslint.config.*"
  ],
  "compilerOptions": {
    "noEmit": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"]
  }
}

tsconfig.app.json(App / ブラウザ)

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "skipLibCheck": true,
    "isolatedModules": true,
    "useDefineForClassFields": true,
    "paths": {
      "@/*": ["./src/*"]
    },
    "types": ["vite/client", "vitest"]
  }
}

env.d.ts(SFC & Vite補完)

/// <reference types="vite/client" />

ポイント(緩め)

  • skipLibCheck: true で依存型チェックをスキップし、開発とCIを高速化
  • isolatedModules: true は Vite/esbuild と相性が良い
  • typesvitest, vite/client を追加して補完を効かせる

2) “固め”の tsconfig(品質優先・堅牢)

tsconfig.json(ルート:参照元)

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

tsconfig.node.json(Node / ツール)

{
  "extends": "@tsconfig/node22/tsconfig.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "playwright.config.*",
    "eslint.config.*"
  ],
  "compilerOptions": {
    "noEmit": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"],
    "strict": true,
    "verbatimModuleSyntax": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitOverride": true
  }
}

tsconfig.app.json(App / ブラウザ)

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "useDefineForClassFields": true,
    "isolatedModules": true,
    "verbatimModuleSyntax": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitOverride": true,
    "paths": {
      "@/*": ["./src/*"]
    },
    "types": ["vite/client", "vitest"]
  }
}

env.d.ts

/// <reference types="vite/client" />
/// <reference types="vitest" />

ポイント(固め)

  • strict: true を基本とし、未定義アクセスやオプショナルを厳密に扱う
  • noUncheckedIndexedAccess, exactOptionalPropertyTypes でバグを型で検出
  • verbatimModuleSyntax, noImplicitOverride などでコードの明示性を強化

Vitest 連携の補足

  • typesvitest を入れると describe/it/expect が補完される
  • vitest.config.tsenvironment: 'jsdom' を指定すれば DOM API を使える
  • グローバルAPIを使うなら globals: true を有効化する
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'jsdom',
    globals: true,
    setupFiles: ['./src/test/setup.ts']
  }
})

実務Tips

  • Vue SFC の型チェックは vue-tsc を利用する
  • tsconfig.app.jsonpathsvite.config.tsresolve.alias は一致させる
  • “固め化”は段階的に進めると移行しやすい

おすすめの順番:

  1. strict: true
  2. isolatedModules: true, useDefineForClassFields: true
  3. verbatimModuleSyntax: true
  4. noUncheckedIndexedAccess: true
  5. exactOptionalPropertyTypes: true
  6. noImplicitOverride: true, noFallthroughCasesInSwitch: true

まとめ

  • Vue + Vite + Vitest では Node用とApp用の tsconfig を分けて管理するのが基本
  • 小規模・プロトタイプでは“緩め”でスピード重視
  • 中〜大規模・長期運用では“固め”へ段階的に移行するのがベスト
  • CIに vue-tsc を導入し、型で検知できるバグは早めに潰すのが実務的
1
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
1
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?