Зміст
Коротко
Монорепо ламається на ланцюжках ../../../packages/types. Автор CitizenApp описує налаштування TypeScript path aliases для Astro, React 19 і спільного пакета @shared/types — читабельні імпорти та безпечний рефакторинг.
Що сталося
Три підходи до спільних типів: відносні шляхи (крихко), публікація в npm (надмірно для внутрішнього коду), path aliases (золота середина). Структура: packages/types/, застосунки в apps/web (Astro), apps/dashboard (React), кореневий tsconfig.json.
Пакет типів компілюється окремо з declaration: true, moduleResolution: bundler. У package.json поле exports вказує на ./dist/index.d.ts — без двозначності для споживачів.
Кореневий конфіг задає baseUrl: "." і paths: { "@shared/*": ["packages/*/src"] }. Project references пов'язують workspaces як окремі одиниці компіляції — швидші інкрементальні збірки, менше циклічних залежностей. Кожен застосунок extends корінь і додає references на packages/types.
Імпорт стає import { User } from '@shared/types' — IDE автодоповнює, перенос файлу оновлює посилання. FastAPI aliases не розуміє; типи генерують у Python через datamodel-code-generator, джерело правди залишається в TS.
Чому це важливо
Без workspace:* у залежностях застосунків збірка падає з «cannot find module» — іноді тихо на CI. Порядок збірки: спочатку packages/types, потім apps — у pnpm / Turborepo це явно.
Ще грабля: різний moduleResolution локально (nodeNext) і на Vercel (bundler) — paths резолвляться по-різному. Для сучасних монорепо автор рекомендує bundler.
На практиці
- Винесіть спільні типи в
packages/typesзexportsі.d.ts. - У кореневому
tsconfig.jsonналаштуйтеbaseUrl,pathsіreferences. - Кожен app:
extends+referencesна types-пакет. - У
package.jsonapps:"@shared/types": "workspace:*". - Збирайте types-пакет першим у pipeline.
- Уніфікуйте
moduleResolution: bundlerскрізь.
Підсумок
30 хвилин на правильний tsconfig економлять години на імпортах і рефакторингу. @shared/types одразу читається як «спільний код». Покрокові конфіги — в оригіналі на Dev.to.