https://habr.com/ru/company/ruvds/blog/437986/- Блог компании RUVDS.com
- JavaScript
- TypeScript
- Платежные системы
- Разработка веб-сайтов
Недавно мы опубликовали
материал, в котором Эрик Эллиот критиковал TypeScript. Сегодня мы представляем вашему вниманию перевод статьи Кента Доддса. Тут он рассказывает о том, почему в PayPal перешли с Flow на TypeScript.
Предыстория
Я работаю в PayPal и занимаюсь библиотекой
paypal-scripts
, которая представляет собой набор инструментов, напоминающий
react-scripts
из
create-react-app
, или
angular-cli
, или
ember-cli
. Об этом я
уже писал. В основе этой библиотеки лежит идея объединения всех инструментов, используемых в приложениях PayPal и в опубликованных модулях. Цель создания
paypal-scripts
заключается в том, чтобы взять все зависимости разработки,
devDependencies
, из
package.json
, все конфигурационные файлы, и свести всё это к одной записи в разделе
devDependencies
. И, так как все конфигурации находятся в единственном пакете, при создании которого придерживаются вполне определённой точки зрения на то, «что такое хорошо», для того, чтобы поддерживать инструменты в актуальном состоянии, достаточно обновить лишь одну зависимость (собственно —
paypal-scripts
), обновления которой обычно не содержат в себе чего-то такого, что способно нарушить работу кода, полагающегося на неё. В результате достаточно поддерживать в актуальном состоянии лишь одну зависимость и спокойно заниматься разработкой приложений.
За последний год программисты в PayPal привыкли работать с
paypal-scripts
. Здесь для создания нового приложения достаточно щёлкнуть по нескольким кнопкам в веб-интерфейсе, в результате чего будет создан корпоративный GitHub-репозиторий, будут настроены средства развёртывания проекта, система непрерывной интеграции, и так далее. Автоматически создаваемый репозиторий основан на репозитории
sample-app
.
Буквально на прошлой неделе в него было включено моё добавление, рассчитанное на использование в нём
paypal-script
. Это означает, что в основе каждого нового приложения в PayPal будет лежать каркас, построенный на базе современных технологий и инструментов, об обновлении которых не нужно заботиться разработчику этого приложения. Кроме прочего, подобное приложение будет статически типизировано с использованием TypeScript и протестировано средствами Jest.
Честно говоря, это стало Magnum Opus моей карьеры. Я не думал, что когда-нибудь мне удастся достигнуть подобного уровня в PayPal. Этот проект оказывает огромнейшее влияние, и я благодарен PayPal за то, что мне предоставлена возможность работать над чем-то столь масштабным.
Так, в курс дел я вас ввёл, теперь поговорим о TypeScript.
В середине декабря я работал над тем, чтобы интегрировать
paypal-scripts
в
sample-app
. Ещё я работал (и продолжаю работать) над проектом
pp-react
, который представляет собой библиотеку компонентов (кнопок, окон, стилей), подходящих для повторного использования. Так как
paypal-scripts
поддерживает модули, которые могут быть опубликованы, я, для сборки
pp-react
, использовал
react-scripts
. Месяц тому назад библиотека
paypal-scripts
включала в себя поддержку
Flow. Такую поддержку было очень просто добавить в эту библиотеку благодаря Babel.
12 декабря, когда я работал над
pp-react
и новой версией
sample-app
в плане поддержки Flow, я почувствовал, что от Flow я уже очень устал (подробнее об этом я расскажу ниже) и принял неожиданное решение. Я написал
коллеге письмо, спросив его о том, как он смотрит на то, что я попытаюсь сделать так, чтобы в
sample-app
использовался бы TypeScript. Он ответил: «Да, сделай». Тогда я устроил опрос на Slack-канале
#paypal-scripts
, по результатам которого оказалось, что мою идею поддерживают все его участники. Для меня всего этого было достаточно для того, чтобы приступить к работе. Примерно через неделю я полностью перевёл
paypal-scripts
с поддержки Flow на поддержку TypeScript. Большая часть этого времени ушла на то, чтобы научить все инструменты распознавать расширения файлов
.ts
и
.tsx
, и на то, чтобы позволить пакету
paypal-scripts
самому себя протестировать, что оказалось довольно-таки непростым делом. Потом я потратил несколько дней на работу над PR в репозиторий
sample-app
, которая была направлена на использование новой улучшенной библиотеки
paypal-scripts
, и на переход с
.js
-файлов на
.ts
и .
tsx
-файлы. Потом были праздники, а потом мой PR был одобрен. Как результат, теперь в каждом новом проекте в PayPal используется статическая TypeScript-типизация.
Конечно, после того, как некто создаёт новый проект, он может делать с ним всё, что ему захочется. Скажем, может удалить весь шаблонный код и писать его на Elm, или на чём угодно другом. Это совершенно нормально. Но авторы большинства проектов придерживаются тех технологий, которые были использованы при их создании благодаря так называемому «
эффекту умолчания».
Почему я так долго шёл к TypeScript?
Вопрос, вынесенный в заголовок этого раздела, часто задавали мне фанаты TypeScript. Дело в том, что я уже давно знаком с TypeScript, но отношения у меня с этим языком до некоторых пор не складывались. Так, я помню, как примерно в 2013 году коллега предложил мне перевести код объёмом примерно в 500 тысяч строк на TypeScript. Тогда я это предложение отверг, но не особенно жалею об этом, так как в те времена TS был достаточно молодым языком. А
однажды я даже брал интервью у
Андерса Хейлсберга, создателя TypeScript.
Вот из-за чего я всё это время держался в стороне от TypeScript.
▍Причина №1. Боязнь разрушить сложившуюся рабочую среду, основанную на Babel и ESLint
Для меня, очень долго, главнейшим плюсом Flow перед TypeScript было то, что Flow лучше сочетался с инструментами, к которым я привык. В частности, я уже многие годы с удовольствием пользуюсь Babel и ESLint, мне нравится писать собственные плагины и для того, и для другого (вы тоже, кстати, можете этому
научиться). Мне нравилось то, что вокруг Babel и ESLint сложились огромные сообщества. В результате отказываться от них я категорически не хотел. Собственно говоря, продолжалось это вплоть до недавних событий, так как, если бы я собрался с головой уйти в TypeScript, мне пришлось бы оставить и то и другое. Конечно, в мире TypeScript есть такая штука как TSLint, но сообщество ESLint значительно больше.
Во Flow же мне особенно нравится то, что для того, чтобы включить его в свой рабочий процесс, нужно выполнить лишь несколько простых действий:
- Надо подключить к Babel пресет с поддержкой соответствующего синтаксиса.
- Нужно добавить в начало каждого файла, проверку типов в котором требуется организовать, конструкцию
// @flow
(существует плагин для ESLint, который позволяет это проверить).
- Добавить в проект скрипт, позволяющий запустить Flow для проверки типов в кодовой базе.
Мне очень нравится то, что проверка типов (с помощью Flow) и сборка проектов (средствами Babel, Webpack или Rollup) разделены. Мне не хотелось связывать свою жизнь с TypeScript, в частности, из-за того, что его компилятор, в любом случае, не понимал бы плагинов для Babel моей собственной разработки. А ещё — из-за того, что у меня был Flow — вполне сносный инструмент.
Теперь же всё продолжает работать как обычно. Благодаря Babel 7 (в частности, речь идёт о
@babel/preset-typescript) можно сохранить привычные инструменты и, кроме того, получить в своё распоряжение большинство возможностей TypeScript. Главная проблема — это сделать так, чтобы инструменты принимали бы файлы с расширениями .
ts
и
.tsx
, но, к счастью, эта проблема решаема.
▍Причина №2. Контрибуторам придётся учить TypeScript для того, чтобы внести вклад в проект
Я говорю, в основном, об опенсорсе, но необходимость освоения TypeScript теми, кто хочет вносить вклад в проекты, относится и к тому, чем я занимаюсь на работе. При этом я всегда считал, что рабочие проекты должны быть типизированными, и достигалось это средствами Flow. Я старался не пользоваться Flow в моих опенсорсных проектах, потому что тем, кто решил бы к ним присоединиться, пришлось бы осваивать Flow. Я сам всегда об этом говорил, но, подсознательно, всегда приводил контраргумент, который заключается в том, что типизация — это, по своей сути, лишь ещё одна форма тестирования, а тем, кто хочет вносить вклад в опенсорс, всё равно, приходится разбираться с тестированием.
Честно говоря, отказ от использования некоей технологии в опенсорсе только из-за того, что потенциальный контрибутор может ей не владеть, кажется мне плохим оправданием отказа от этой технологии. И, по мере того, как всё больше и больше программистов осваивают TypeScript, я думаю, что, возможно, через некоторое время буду писать на TS и свои опенсорсные проекты.
▍Причина №3. Мощная система вывода типов Flow
Я читал
этот пост, и он мне очень понравился. В особенности его последняя строка, в соответствии с которой при использовании Flow типы добавляют для того, чтобы сделать сообщения об ошибках приятнее, а не для того, чтобы их выявлять.
Так оно и есть. В наши дни Flow имеет более мощную систему вывода типов, чем TypeScript, и это меня обнадёживало.
▍Причина №4. Flow, как и React, родом из Facebook
Я погрешу против истины, если скажу, что я не поддавался весьма распространённому заблуждению, заключающемуся в том, чтобы полагать, что если некая компания сделала что-то грандиозное, то всё остальное, что она делает, автоматически оказывается на столь же высоком уровне. Подобное совсем не гарантировано. Больше мне тут добавить нечего.
▍Причина №5. Фанатичные приверженцы TypeScript
Думаю, все знают, что если некто по-настоящему восхищён некоей технологией, то он, не замолкая, всем вокруг о ней рассказывает. Тут кто-нибудь пользуется
vim? И приверженцы TypeScript — не исключение.
В сообществе TypeScript, кстати, полно замечательных людей. Добрых, готовых прийти на помощь, полных энтузиазма, дружелюбных. Но мне приходилось пересекаться и с такими любителями TS, которые назовут человека дураком только из-за того, что он не пользуется TypeScript, или не понимает его, или пользуется чем-то другим. Они демонстрируют отсутствие способности к пониманию собеседника, а их позиция отдаёт снобизмом. Это — не то сообщество, частью которого я хотел бы стать. Я имею в виду то, что воодушевление, вызываемое выбранной кем-то технологией — это замечательно, но если оно заходит настолько далеко, что фанат этой технологии начинает притеснять тех, кто выбрал что-то другое, это уже
весьма печально.
У меня всё ещё остаются некоторые опасения по этому поводу. Но я надеюсь, что все вместе мы сделаем так, что сообщество TypeScript будет более позитивным.
Теперь, когда я рассказал о причинах, по которым не спешил переходить на TypeScript, расскажу о том, что меня не устраивает во Flow.
Проблемы Flow
Как я уже говорил, в определённый момент я очень устал от Flow. Вот один из
твитов, в котором я делился одной из главных проблем, с которой столкнулся при работе с Flow. Заключалась она в том, что для того, чтобы Flow заработал, регулярно приходится, после его неудачного запуска, его останавливать, а потом запускать снова. Вот ещё один мой
твит, где речь идёт о неправильной работе Flow.
Меня окончательно оттолкнули от Flow регулярно возникающие проблемы с его надёжностью. Плагины для редакторов работали, так сказать, с переменным успехом (должен признаться, что я не работал с Nuclide, и возможно, попробуй я его, моя жизнь сложилась бы иначе, но я пробовал работать с Flow в Atom и в VSCode), я постоянно сталкивался с какими-то странностями. Это было весьма досадно, так как подрывало мою веру в используемую мной систему контроля типов.
Когда я, в ноябре, увидел
этот твит, он выразил то, о чём я уже размышлял; краткий рассказ о переходе с Flow на TypeScript совпал с моим видением ситуации. Я, честно говоря, не мог перестать думать о том, чтобы как следует взяться за TypeScript. В итоге я так и поступил и я очень этому рад.
Вопросы и ответы
▍Почему вы не пользуетесь TSLint?
На самом деле, я реализовал поддержку
TSLint в
paypal-script
. Это был один из первых скриптов, который у меня заработал. Я собирался принимать решение о том, использовать ли TSLint или ESLint, основываясь на том, есть ли в проекте файл
tsconfig.json
. Но потом я вспомнил, что у нас есть некоторые ESLint-плагины собственной разработки (например, для проверки интернационализации), на переписывание которых в виде плагинов для TSLint мне не хотелось тратить время. Кроме того, интерфейс командной строки TSLint обладает меньшими возможностями, чем у ESLint, и он не очень хорошо подходил для совместной работы с
paypal-scripts
. Возможно, через некоторое время я снова присмотрюсь к TSLint.
Да, хочется отметить, что сообщество ESLint всё ещё гораздо больше, чем сообщество TSLint. Кроме того, я постепенно понимаю, что хорошая система контроля типов делает плагины для линтинга бесполезными. Пока же я использую с TypeScript ESLint, и то, что получается, выглядит совсем неплохо.
Вот моё видео на эту тему.
И, кстати, у меня такое ощущение, что команда TypeScript склоняется в сторону ESLint, поэтому я полагаю, что я сделал правильный выбор.
▍Почему вы не выбрали Reason?
Я, в переписке под
этим твитом, ответил на предложение попробовать TypeScript, сказав, что уж лучше перейду с Flow на ReasonML. На самом деле, я часто говорил о переходе на
Reason до перехода на TypeScript. Одной из главных причин подобных утверждений было мое желание сохранить привычные инструменты, о котором я уже рассказывал. Но, так как ни от чего отказываться мне не пришлось, TypeScript оказался для меня более привлекательным. Мне и сейчас очень нравится Reason, но переход на Reason означал бы необходимость огромных изменений для многих сотрудников PayPal. И хотя я думаю, что они с этим справились бы, я полагаю, что им комфортнее будет пользоваться TypeScript, чем пытаться изучать новый язык.
Вероятно, если бы я выбрал Reason, мой PR никогда не попал бы в репозиторий
sample-app
. Одно дело — подвигнуть коллег на то, чтобы пользоваться, в сущности, тем, что можно назвать «типизированным JavaScript» (особенно если с их стороны не требуется поддержка неких конфигураций), и совсем другой разговор состоится в том случае, если попытаться призвать коллег использовать совершенно другой язык и совершенно другую экосистему (и тут совершенно неважно то, насколько хорошо этот язык взаимодействует с JS и npm).
Итоги
Сейчас мне хотелось бы
поблагодарить всех пользователей Твиттера, под влиянием которых сформировалось моё видение TypeScript. Как я уже говорил, то, что библиотека
paypal-scripts
попала в репозиторий
sample-app
в PayPal, возможно, главное достижение моей карьеры. И я считаю, что то, что теперь шаблоны всех новых приложений в компании по умолчанию оснащаются поддержкой TypeScript — это огромный плюс для всех сотрудников PayPal. Я безмерно рад тому, что выбрал TypeScript.
Уважаемые читатели! Как вы думаете, стоит ли тем, кто пользуется Flow, смотреть в сторону TypeScript?
