🔥

Тред (Али Рагимов)


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…
notion image

А последнее время мне кажется отличной идея полностью отказаться от дефолтных экспортов. Подсмотрел у @nestframework. Тогда остаётся только один формат импортов import {something} from 'lib' Выглядит красиво, можно линтером упорядочивать по алфавиту - красота и порядок😍

Но не суть. Если вас заинтересовали подробности тюнинга tsconfig, то предлагаю вашему вниманию статью, в которой я расписал все основные опции конфига: habr.com/ru/post/542234/

Али РагимовАли Рагимов