Файл tsconfig.json управляет поведением компилятора
TypeScript и определяет, как проект анализируется, проверяется и
преобразуется. В экосистеме Vite этот файл играет особую роль, поскольку
Vite использует TypeScript иначе, чем классические сборщики.
Vite не выполняет полноценную компиляцию TypeScript через
tsc во время разработки. Вместо этого применяется быстрый
транспайлинг через esbuild, а типизация остаётся задачей
самого TypeScript. Из-за этого часть параметров
tsconfig.json влияет только на IDE и проверку типов, а
часть — непосредственно на работу Vite.
tsconfig.jsonМинимальный конфигурационный файл обычно выглядит следующим образом:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "react-jsx"
}
}
Каждая настройка оказывает влияние на совместимость проекта с Vite.
targetПараметр target определяет, в какую версию JavaScript
должен преобразовываться TypeScript-код.
Пример:
{
"compilerOptions": {
"target": "ES2017"
}
}
В проектах Vite чаще всего используется:
{
"compilerOptions": {
"target": "ESNext"
}
}
Причины:
esbuild эффективно работает с современным
синтаксисом;Если используется слишком старый target, могут
возникать:
moduleVite построен вокруг ES Modules, поэтому параметр module
практически всегда должен быть:
{
"compilerOptions": {
"module": "ESNext"
}
}
Некорректные значения:
{
"compilerOptions": {
"module": "CommonJS"
}
}
Использование CommonJS приводит к проблемам:
moduleResolution
и совместимость с ViteДолгое время использовалось:
{
"compilerOptions": {
"moduleResolution": "Node"
}
}
Этот режим имитирует поведение Node.js при поиске модулей.
BundlerНачиная с TypeScript 5 появился новый вариант:
{
"compilerOptions": {
"moduleResolution": "Bundler"
}
}
Для Vite это наиболее корректный вариант.
Преимущества:
exports и imports;Рекомендуемая современная конфигурация:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler"
}
}
useDefineForClassFieldsVite-шаблоны TypeScript обычно включают:
{
"compilerOptions": {
"useDefineForClassFields": true
}
}
Эта настройка переводит поля классов на современную спецификацию JavaScript.
Без неё возможны:
Практически все современные Vite-проекты используют:
{
"compilerOptions": {
"strict": true
}
}
Этот режим включает:
null;Дополнительные полезные настройки:
{
"compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
}
}
isolatedModulesДля Vite крайне важен параметр:
{
"compilerOptions": {
"isolatedModules": true
}
}
Причина заключается в том, что esbuild компилирует файлы
независимо друг от друга.
При включённом режиме TypeScript запрещает конструкции, требующие анализа нескольких файлов одновременно.
Без этой настройки код может:
esModuleInteropЧасто используется:
{
"compilerOptions": {
"esModuleInterop": true
}
}
Настройка улучшает совместимость между:
Особенно полезна при работе с устаревшими библиотеками.
allowSyntheticDefaultImportsОбычно включается вместе с esModuleInterop:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true
}
}
Позволяет писать:
import React from "react";
даже если библиотека не экспортирует default.
Для React используется:
{
"compilerOptions": {
"jsx": "react-jsx"
}
}
Это включает новый JSX runtime.
Старый вариант:
{
"compilerOptions": {
"jsx": "react"
}
}
требует обязательного импорта React в каждом файле.
В Vue-проектах JSX часто не нужен вообще:
{
"compilerOptions": {
"jsx": "preserve"
}
}
Для SolidJS используется:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js"
}
}
pathsОдна из самых популярных возможностей TypeScript — псевдонимы импортов.
Пример:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
После этого можно писать:
import Button from "@/components/Button";
вместо:
import Button from "../. ./. ./components/Button";
pathsTypeScript знает о paths, но сам Vite — нет.
Поэтому требуется дополнительная настройка:
import { defineConfig } from "vite";
import path from "path";
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
}
}
});
Без этого:
vite-tsconfig-pathsДля автоматической синхронизации путей применяется плагин:
npm install vite-tsconfig-paths
Подключение:
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [tsconfigPaths()]
});
Преимущества:
types и глобальные
типы ViteVite предоставляет собственные глобальные типы.
Обычно используется:
{
"compilerOptions": {
"types": ["vite/client"]
}
}
Это добавляет поддержку:
import.meta.env
Пример:
console.log(import.meta.env.VITE_API_URL);
Без подключения типов TypeScript выдаёт ошибку.
Для строгой типизации создаётся файл:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_APP_TITLE: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
Теперь TypeScript знает структуру .env.
include и
exclude{
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Неправильный include может:
В крупных проектах часто используется несколько файлов:
tsconfig.json
tsconfig.app.json
tsconfig.node.json
tsconfig.jsonЧасто содержит только общие настройки:
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true
},
"include": ["src"]
}
Для vite.config.ts могут потребоваться другие
настройки:
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node"
},
"include": ["vite.config.ts"]
}
TypeScript поддерживает ссылки между проектами:
{
"references": [
{ "path": "../shared" }
]
}
Это особенно полезно:
vite.config.tsКонфигурация Vite сама может быть написана на TypeScript:
import { defineConfig } from "vite";
export default defineConfig({
server: {
port: 3000
}
});
Для корректной типизации требуется:
{
"compilerOptions": {
"types": ["node"]
}
}
skipLibCheckОчень популярная оптимизация:
{
"compilerOptions": {
"skipLibCheck": true
}
}
Преимущества:
Недостаток:
.d.ts библиотеки.noEmitВ проектах Vite часто используется:
{
"compilerOptions": {
"noEmit": true
}
}
Причина:
Если оставить генерацию файлов включённой:
.js;Для импорта JSON-файлов:
{
"compilerOptions": {
"resolveJsonModule": true
}
}
После этого возможно:
import data from "./data.json";
В смешанных проектах:
{
"compilerOptions": {
"allowJs": true
}
}
Иногда дополнительно:
{
"compilerOptions": {
"checkJs": true
}
}
Это включает типизацию обычного JavaScript.
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"jsx": "react-jsx",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"noEmit": true,
"skipLibCheck": true,
"types": ["vite/client"]
},
"include": ["src"]
}
CommonJSОшибка:
{
"compilerOptions": {
"module": "CommonJS"
}
}
Последствия:
vite/clientОшибка:
import.meta.env
TypeScript сообщает:
Property 'env' does not exist
Решение:
{
"compilerOptions": {
"types": ["vite/client"]
}
}
TypeScript:
{
"paths": {
"@/*": ["src/*"]
}
}
Vite:
resolve: {
alias: {}
}
Результат:
Failed to resolve import.isolatedModulesВозможны проблемы:
Во время разработки Vite не запускает полноценный
tsc.
Для отдельной проверки обычно используется:
tsc --noEmit
или:
vue-tsc --noEmit
для Vue-проектов.
vite-plugin-checkerПлагин позволяет видеть ошибки типов прямо в браузере.
Установка:
npm install vite-plugin-checker -D
Подключение:
import checker from "vite-plugin-checker";
export default defineConfig({
plugins: [
checker({
typescript: true
})
]
});
Преимущества:
tsconfig.json
на IDEРедакторы вроде PhpStorm и Visual Studio Code используют
tsconfig.json для:
Ошибки конфигурации часто проявляются именно через IDE:
В монорепозиториях важно:
paths;node_modules;Часто применяется базовый файл:
{
"compilerOptions": {
"strict": true,
"module": "ESNext",
"moduleResolution": "Bundler"
}
}
который затем наследуется:
{
"extends": "../. ./tsconfig.base.json"
}
TypeScript поддерживает extends:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"strict": false
}
}
Это позволяет: