[Из песочницы] Почему лучше заранее компилировать 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
…
Полез узнавать в чем дело и выяснилось:
(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.