[Из песочницы] Почему лучше заранее компилировать TS в JS

Однажды встал вопрос: «Использовать ранеры, которые будут на лету компилировать TypeScript в JavaScript (например, node-ts), или компилировать самому заранее (например, через `tsc`) и запускать уже JavaScript код?» — гугление не дало четкого ответа, поэтому я сформулировал его императивным путем:

TypeScript стоит компилировать заранее, через специализированные компиляторы (например, tsc) и запускать уже JS код.


Пара злободневных причин:

Кроссплатформенность


Вы никогда не знаете, где будете разворачивать ваш код.

Сегодня это сервер контролируемый вами, где можно использовать node-ts, завтра это AWS Lambda или Google App Engine, куда нужно деплоить JS код.

При переходе с node-ts на предварительную компиляцию могут возникнуть непредвиденные ошибки и возня с изменениями в конфигурации CI/CD и подобного, поэтому надежнее сразу начинать с предварительной компиляции.

Поймай если сможешь!


Отвратительные неочевидные ошибки…

С одной из них я столкнулся совершенно недавно: написал Node.js приложение на TypeScript, скомпилировал его и задеплоил на Google App Engine.

На личном Маке все работало, а на сервере появлялась ошибка, что нет файла по пути some/folder/path/FileName.ts

Error: Cannot find module 'some/folder/path/FileName.ts' at ...


Можно было бы подумать, что код просто не компилируется, или я загружаю старую версию, или сорвался NODE_PATH и подобное, но все оказалось гораздо хуже:

Поскольку я компилировал заранее, можно было посмотреть какой js код отправляется на сервер. И тут стало ясно, что только этот ОДИН файл компилируется не с оригинальным название: FileName.ts –, а с маленькой буквы: fileName.ts

image

Полез узнавать в чем дело и выяснилось:

(1) Компилятор TS называет скомпилированные файлы не в соответствии с названием их оригиналов, а в соответствии с импортами в коде.

То есть, если вы написали с маленькой буквы import * from "some/folder/path/fileName", а оригинал называется с большой буквы (FileName.ts), то TS скомпилирует его в файл с маленькой буквы. Даже если в остальном коде будут везде импорты с большой буквы: import * from "some/folder/path/FileName"

(2) На мак Node.js приложения не учитывает регистр, поэтому все спокойно работало

(3) На Google App Engine регистр учитывается…

У меня была опция компилировать ts файлы на лету и отправлять их в Google App Engine и тогда бы я потратил слишком много времени на выяснение подобной проблемы. Но поскольку я шел путем предварительной компиляции, я мог спокойно зайти в отправляемые JS файлы и подебажить их.

Итог


Если вы используете TS, то сначала компилируйте его соответствующими инструментами (tsc, webpack и т.д.), а только потом запускайте / деплойте на нужную платформу.

Вот когда появится у TS своя VM, тогда… еще пару лет будем компилировать, пока она не появится в разных экосистемах типа Google, Amazon, .etc, а вот уже потоооом заживем.

Что вы думаете на этот счет: есть ли преимущества использования node-ts? Сталкивались ли вы с неочевидными проблемами без предварительной компиляции?

Всем удачи, не дайте дебагингу убить счастье от кодинга!

P.S.


Еще, чтобы в JS вообще не было проблем с наименованием, лучше придерживаться «кябаб-кейса», как советует дядюшка Google.

© Habrahabr.ru