Ещё один способ сборки TypeScript проектов

в 14:25, , рубрики: grunt, javascript, node.js, nodejs, npm

Много рассказывать о том, что такое TypeScript, не буду. На мой взгляд, это уже устоявшаяся и хорошо зарекомендовавшая технология, которая предоставляет возможности программирования, которых не хватало раньше в JavaScript. Самыми основными возможностями языка, на мой взгляд, стало более четкое ООП и строгая типизация. И за эти качества я этот язык полюбил и он гармонично вписался в мои проекты.

Все начиналось с того, что я в командной строке вызывал компилятор после каждого изменения проекта и пересобирал проект. Это было жутко не удобно и очень сильно замедляло разработку. Для grunt было расширение grunt-ts которое решало мои задачи и я им какое-то время пользовался. У компилятора TypeScript есть одна особенность (не бага и не фитча, политкорректность), которую во всех расширениях, которые я перепробовал, не учитывалась. Это жутко мешало и заставило писать свой код. grunt-tsc — расширение для grunt, позволяющее собирать проекты на TypeScript, о нем я и хочу рассказать.

Особенность компилятора заключается в том, что при компилировании одного файла с зависимостями в выходной файл попадает код самого компилируемого файла, а также всех файлов указанных в зависимостях. Это очень сильно удивило меня, потому, что нормальный кейс для grunt это компилировать файлы «один к одному». И получается, что при компилировании проекта, когда необходимо иметь большую гору *.js файлов (скомпилированных аналогов *.ts, с общими зависимостями) получается очень много мусора в выходных файлах (очень много дублированного кода, который по сути не нужен). На тот момент, когда я начал писать свое решение, я не смог найти готового кода с фиксом такой особенности компилятора, возможно сейчас это не так. Я подглядел хак (возможно, это где-то задокументированно, не нашел) у watcher'ов idea, он оказался очень простой — запускать компилятор в той директории, в которой располагается *.ts файл и при указании файла не использовать путь, а только название файла, а также не работать с опцией «--out».

Из примера сразу станет все понятно:

tsc --out ./utils/deferred/Deferred.js ./utils/deferred/Deferred.ts

Такое использование приводит к тому, что в файлик Deferred.js содержит все зависимости, которые по сути я хотел компилировать отдельно и содержать в других файла.

cd ./utils/deferred && tsc Deferred.ts

Но, например, такое использование устраняет эту проблему и в выходной файл Deferred.js содержит скомпилированный код только Deferred.ts, при этом проверка зависимостей остается.

Это оказалось тем, что нужно и я написал свое решение. Выдающихся способностей у решения нет, оно просто правильно решает задачу компиляции. Также к grunt модулю добавлена возможность выбора версии компилятора, устранена зависимость от глобальной установки tsc, а также добавлен более гибкий способ указания зависимостей *.d.ts.

Устранение глобальных зависимостей и выбор версии компилятора

Само расширение, по умолчанию, не имеет зависимости от глобальной установки tsc. Компилятор находится внутри модуля и кроме установки модуля больше ничего не требуется. У модуля есть опция options.version при помощи которой можно указать версию компилятора. Можно задавать следующие значения (момент написания статьи): «1.0», «1.1», «1.3», «1.4», «default»(1.3), «latest»(1.4). Поддержка разных версий мне показалась очень полезной и она была реализована, например, если в старых проектах есть зависимость от старых версий компилятора.

Кроме того, компилятор можно указать явно, задав путь к нему при помощи опции options.compiler. При таком использовании опция options.version будет проигнорирована. Например, если все таки хочется использовать системно установленных компилятор, то опция должна иметь значение «/usr/local/lib/node_modules/typescript/bin/tsc.js». Да, тут есть очень важный момент, опция должна указывать на *.js файл.

Указание зависимостей

За зависимости отвечает 3 опции:

  • options.references — эта опция задается в виде строки или массива строк и является маской (расширение glob) поиска файлов деклараций *.d.ts.
  • options.libray — это булева опция, которая указывает на то, что должен быть подключен файл lib.d.ts текущего компилятора, даже если он задан через опцию options.compiler.
  • options.system — эта опция очень похожа на опцию options.references, за тем исключением, что поиск зависимостей осуществляется в папке текущего компилятора (для последних версий *.d.ts стало очень много), даже если он задан через опцию options.compiler.

Остальные опции расширения повторяют опции компилятора и в них легко можно разобраться, я их описывать не стану. Общее количество опций настройки очень большое, но это не должно пугать, это все опционально и компиляция заводится на дефолтных значениях.

Мне кажется, что расширение правильно выполняет свою задачу и дополнять его новыми возможностями не стоит. Единственное, что хочу добавить — это предпроцессинговые инструкции, но они могут повлиять на sourcemap'ы, вот думаю как аккуратнее это сделать. А также TypeScript развивается и мной будут поддерживаться свежие версии компилятор. Буду очень рад, если расширение кому либо пригодится, а также буду рад отзывам.

Официальный сайт TypeScript
Расширение glob
Расширение grunt-tsc

Автор: rodzewich_oleg

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js