TS начинается с файла tsconfig.json, где хранится конфигурация компилятора и проекта. Но ему часто не уделяют должного внимания. Чаще всего он кочует из проекта в проект с минимальными изменениями. Просто потому что "работает". И я делал так же
Но в одном проекте пришлось заняться сборкой более плотно. Возникала потребность разобраться в многочисленных опциях. Вкладка документации по TS была открыта 24/7... И так, первый лайфхак: существует команда tsc --init, которая сгенерирует конфиг с самыми основными опциями
При этом конфиг будет содержать большое множество закомментированных опций с их описанием. Читаем описание опции, если находите её полезной - раскомментируем, если нет- удаляем. Посмотреть, как это выглядит можно здесь:
gist.github.com/barinbritva/cf…
Конфиг создан, можно настраивать
Много путаницы может возникать при указании файлов для компиляции. Речь идёт о директивах files, include, exclude. Опция files, позволяет указать конкретные файлы, что можно использовать если у вас всего несколько файлов в проекте. Но на деле это скорее служебная директива
Обычно используется include с указанием массива масок путей, например ["src"]. Поэтому опцию files использовать нет необходимости. В действительности она используется под капотом. Анализируя маски путей из include, TS составляет полный список файлов и заполняет их за нас
Это можно заметить выполнив малоизвестную команду tsc --showConfig. Несмотря на то, что мы указали в конфиге лишь include: ["src"], мы можем наблюдать появление опции files с указанием каждого файла, лежащим внутри src. По сути, команда позволяет нам дебажить конфиг
К сожалению, команда не демонстрирует другие особенности готовки итогового конфига. А их, на самом деле, очень много. Есть issue на GitHub, чтобы сделать функцию более полной - github.com/microsoft/Type… Надеюсь, однажды у нас будет полноценный инструмент дебага
Что же будет если указать и files и include? TS просто сделает merge. С включением файлов разобрались. А что на счёт exclude?
Данная опция является фильтром опции include. Это может быть удобно, например, чтобы быстро включить всю папку src, а потом исключить из неё файлы тестов
Соответственно, exclude не может исключить файлы, указанные в files. Так же exclude не сможет исключить файл, если он импортируется в другом файле.
Посмотреть итоговый список всех файлов, которые будут включены в билд, включая файлы из node_modules, можно командой tsc –listFiles
С input'ом файлов разобрались. Немного про output. У нас есть 2 опции outDir и outFile. Первой, думаю, пользуются все — это папка хранения артефактов билда. Вторая же опция умеет конкатенировать все выходные файлы в один.
Вау! Бандлинг из коробки! Почему я не знал об этом?
Именно такие мысли были у меня, когда я увидел эту опцию. Но не тут-то было. Почему?
Потому что outFile не работает с модульной системой CommonJS или ES6. А именно они и нужны в 90% случаев
Если же вам не нужна модульная система или подойдёт AMD, то можно смело использовать опцию
Наверняка, вам приходилось и не раз писать подобное?
import * as React from 'react'
React содержит CommonJS синтаксис экспорта, а не ES6. Однако TS умеет преобразовывать такие конструкции, что позволяет нам не писать миксы из require и import в коде. Большое спасибо ему за это!
Но включив флаг allowSyntheticDefaultImports в tsconfig, мы можем сделать ещё один шаг к унификации импортов и писать вот так
import React from 'react'
Флаг не меняет исходный код, а просто закрывает глаза на то, что в тайпингах не объявлен дефолтный ES6 экспорт
Разумеется, это работает и с другими библиотеками. Но бывают случаи, когда после таких трюков проект собирается, но не работает. Например, если подключить вышеуказанным способом библиотеку moment. Какая-то внутренняя кухня готовки модулей. Я, честно, не знаю всех тонкостей
Исправить ситуацию позволяет флаг esModuleInterop. Он добавляет некоторый бойлерплейт в экспорт модулей, который делает так, что всё экспортируется правильно. А мы получаем возможность во всех случаях писать единообразные импорты
Пожалуй, для меня это личное. После того как в 2015 я писал первый проект на TS без понимания про тайпинги и модульные системы и мои импорты выглядели как-то так
gist.github.com/barinbritva/cf…

А последнее время мне кажется отличной идея полностью отказаться от дефолтных экспортов. Подсмотрел у @nestframework.
Тогда остаётся только один формат импортов
import {something} from 'lib'
Выглядит красиво, можно линтером упорядочивать по алфавиту - красота и порядок😍
Но не суть.
Если вас заинтересовали подробности тюнинга tsconfig, то предлагаю вашему вниманию статью, в которой я расписал все основные опции конфига:
habr.com/ru/post/542234/
