Параметр isolatedModules в TypeScript предназначен для
проверки совместимости исходного кода с инструментами, выполняющими
независимую компиляцию каждого файла отдельно. Особенно важен этот режим
в экосистеме Vite, поскольку Vite использует сверхбыструю транспиляцию
через esbuild, а не полноценный компилятор TypeScript во
время разработки.
В tsconfig.json параметр выглядит так:
{
"compilerOptions": {
"isolatedModules": true
}
}
При включении режима TypeScript начинает запрещать конструкции, которые невозможно корректно обработать без анализа всей программы целиком.
isolatedModules важен для ViteVite ориентирован на скорость запуска и мгновенную горячую перезагрузку модулей. Для этого он:
esbuild для быстрой транспиляции;Это означает, что Vite не анализирует взаимосвязи между всеми
.ts-файлами проекта перед преобразованием кода.
Компилятор TypeScript умеет выполнять глобальный анализ программы:
esbuild работает иначе:
Именно поэтому isolatedModules становится механизмом
раннего обнаружения несовместимого кода.
Без isolatedModules TypeScript может использовать
глобальный контекст проекта.
Пример:
// types.ts
export interface User {
name: string
}
// app.ts
import { User } from './types'
const user: User = {
name: 'Alex'
}
Во время полноценной сборки TypeScript понимает:
User — это тип;Но изолированный транспилятор не способен надежно определить это во всех случаях.
Одна из наиболее распространённых проблем — повторный экспорт типов.
// types.ts
export interface User {
name: string
}
// index.ts
export { User } from './types'
При isolatedModules: true TypeScript выдаст ошибку.
Причина:
User существует только на уровне типов;export type { User } from './types'
Ключевое слово type явно сообщает:
В режиме isolatedModules особенно важна строгая граница
между:
import { User } from './types'
import type { User } from './types'
Такой синтаксис:
esbuild;import typeКонструкция:
import type { User } from './types'
полностью удаляется из итогового JavaScript.
Например:
import type { User } from './types'
const user: User = {
name: 'Alex'
}
const user = {
name: 'Alex'
}
Это особенно важно для:
isolatedModules ограничивает использование
namespace.
namespace Utils {
export const version = '1.0'
}
Причина ограничения:
Современный TypeScript в Vite-проектах ориентирован на ES-модули.
// utils.ts
export const version = '1.0'
const enum Status {
Active,
Disabled
}
const enum требует inline-подстановки значений:
Status.Active
превращается в:
0
Для этого нужен полноценный анализ TypeScript.
Изолированные транспиляторы не всегда способны корректно обработать такую оптимизацию.
Поэтому использование const enum в проектах Vite может
вызывать проблемы.
enum Status {
Active,
Disabled
}
или:
export const Status = {
Active: 0,
Disabled: 1
} as const
Старый синтаксис CommonJS:
export = something
плохо совместим с современной модульной системой ES Modules.
Vite ориентирован на:
Поэтому рекомендуется использовать:
export default something
или:
export const something = ...
isolatedModulesexport { User }
Исправление:
export type { User }
import { Config } from './config'
Исправление:
import type { Config } from './config'
namespace App {}
Исправление:
export const App = {}
const enum Role {
Admin
}
Исправление:
enum Role {
Admin
}
или:
const Role = {
Admin: 'admin'
} as const
esbuildesbuild — основной транспилятор Vite во время
разработки.
Он:
По сути esbuild:
Именно поэтому Vite рекомендует:
{
"compilerOptions": {
"isolatedModules": true
}
}
Этот параметр гарантирует, что код совместим с моделью работы
esbuild.
tsc --noEmitТипичная архитектура Vite-проектов:
tsc --noEmit
Выполняется самим Vite через esbuild.
Это разделение обязанностей:
| Инструмент | Назначение |
|---|---|
TypeScript (tsc) |
Проверка типов |
| esbuild | Быстрая компиляция |
| Vite | Dev server и HMR |
isolatedModules помогает гарантировать совместимость
между этими этапами.
Стандартные шаблоны Vite для TypeScript обычно содержат:
{
"compilerOptions": {
"isolatedModules": true
}
}
Это связано с несколькими причинами:
Код одинаково работает:
Подходит для:
Компилятору не приходится угадывать:
Современные проекты часто комбинируют:
{
"compilerOptions": {
"isolatedModules": true,
"verbatimModuleSyntax": true
}
}
Такой режим делает систему импортов максимально строгой и прозрачной.
TypeScript перестаёт автоматически модифицировать импорты.
Разработчик явно указывает:
import type { User } from './types'
или:
import { createApp } from './app'
Это уменьшает магию компилятора и повышает предсказуемость сборки.
isolatedModules фактически подталкивает проект к
современному стилю разработки:
import type { User } from './types'
export function init() {}
export const utils = {}
const enum;Код одинаково работает в:
Проект легче переносить между:
Явное разделение типов и значений помогает удалять неиспользуемый код.
Разработчик точно понимает:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"noEmit": true
}
}
Параметр критически важен при использовании:
Во всех этих случаях код часто обрабатывается без полноценной компиляции TypeScript.
Наиболее частые сценарии:
export { User } from './types'
import { User, createUser } from './user'
Старые проекты, написанные под tsc, часто несовместимы с
изолированной транспиляцией без рефакторинга.
import type { User } from './types'
export type { User }
export function createApp() {}
export const Role = {
Admin: 'admin',
User: 'user'
} as const
export const api = {}
Такой стиль максимально совместим с современной экосистемой JavaScript и архитектурой Vite.