Главная » Хабрахабр » [Перевод] Почему в основе каждого нового веб-приложения в PayPal лежит TypeScript?

[Перевод] Почему в основе каждого нового веб-приложения в PayPal лежит TypeScript?

Недавно мы опубликовали материал, в котором Эрик Эллиот критиковал TypeScript. Сегодня мы представляем вашему вниманию перевод статьи Кента Доддса. Тут он рассказывает о том, почему в PayPal перешли с Flow на TypeScript.

image

Предыстория

Я работаю в PayPal и занимаюсь библиотекой paypal-scripts, которая представляет собой набор инструментов, напоминающий react-scripts из create-react-app, или angular-cli, или ember-cli. Об этом я уже писал. В основе этой библиотеки лежит идея объединения всех инструментов, используемых в приложениях PayPal и в опубликованных модулях. Цель создания paypal-scripts заключается в том, чтобы взять все зависимости разработки, devDependencies, из package.json, все конфигурационные файлы, и свести всё это к одной записи в разделе devDependencies. И, так как все конфигурации находятся в единственном пакете, при создании которого придерживаются вполне определённой точки зрения на то, «что такое хорошо», для того, чтобы поддерживать инструменты в актуальном состоянии, достаточно обновить лишь одну зависимость (собственно — paypal-scripts), обновления которой обычно не содержат в себе чего-то такого, что способно нарушить работу кода, полагающегося на неё. В результате достаточно поддерживать в актуальном состоянии лишь одну зависимость и спокойно заниматься разработкой приложений.

Здесь для создания нового приложения достаточно щёлкнуть по нескольким кнопкам в веб-интерфейсе, в результате чего будет создан корпоративный GitHub-репозиторий, будут настроены средства развёртывания проекта, система непрерывной интеграции, и так далее. За последний год программисты в PayPal привыкли работать с paypal-scripts. Автоматически создаваемый репозиторий основан на репозитории sample-app.

Это означает, что в основе каждого нового приложения в PayPal будет лежать каркас, построенный на базе современных технологий и инструментов, об обновлении которых не нужно заботиться разработчику этого приложения. Буквально на прошлой неделе в него было включено моё добавление, рассчитанное на использование в нём paypal-script. Кроме прочего, подобное приложение будет статически типизировано с использованием TypeScript и протестировано средствами Jest.

Я не думал, что когда-нибудь мне удастся достигнуть подобного уровня в PayPal. Честно говоря, это стало Magnum Opus моей карьеры. Этот проект оказывает огромнейшее влияние, и я благодарен PayPal за то, что мне предоставлена возможность работать над чем-то столь масштабным.

Так, в курс дел я вас ввёл, теперь поговорим о TypeScript.

Ещё я работал (и продолжаю работать) над проектом pp-react, который представляет собой библиотеку компонентов (кнопок, окон, стилей), подходящих для повторного использования. В середине декабря я работал над тем, чтобы интегрировать paypal-scripts в sample-app. Месяц тому назад библиотека paypal-scripts включала в себя поддержку Flow. Так как paypal-scripts поддерживает модули, которые могут быть опубликованы, я, для сборки pp-react, использовал react-scripts. Такую поддержку было очень просто добавить в эту библиотеку благодаря Babel.

Я написал коллеге письмо, спросив его о том, как он смотрит на то, что я попытаюсь сделать так, чтобы в sample-app использовался бы TypeScript. 12 декабря, когда я работал над pp-react и новой версией sample-app в плане поддержки Flow, я почувствовал, что от Flow я уже очень устал (подробнее об этом я расскажу ниже) и принял неожиданное решение. Тогда я устроил опрос на Slack-канале #paypal-scripts, по результатам которого оказалось, что мою идею поддерживают все его участники. Он ответил: «Да, сделай». Примерно через неделю я полностью перевёл paypal-scripts с поддержки Flow на поддержку TypeScript. Для меня всего этого было достаточно для того, чтобы приступить к работе. Потом я потратил несколько дней на работу над PR в репозиторий sample-app, которая была направлена на использование новой улучшенной библиотеки paypal-scripts, и на переход с .js-файлов на .ts и .tsx-файлы. Большая часть этого времени ушла на то, чтобы научить все инструменты распознавать расширения файлов .ts и .tsx, и на то, чтобы позволить пакету paypal-scripts самому себя протестировать, что оказалось довольно-таки непростым делом. Как результат, теперь в каждом новом проекте в PayPal используется статическая TypeScript-типизация. Потом были праздники, а потом мой PR был одобрен.

Скажем, может удалить весь шаблонный код и писать его на 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 же мне особенно нравится то, что для того, чтобы включить его в свой рабочий процесс, нужно выполнить лишь несколько простых действий:

  1. Надо подключить к Babel пресет с поддержкой соответствующего синтаксиса.
  2. Нужно добавить в начало каждого файла, проверку типов в котором требуется организовать, конструкцию // @flow (существует плагин для ESLint, который позволяет это проверить).
  3. Добавить в проект скрипт, позволяющий запустить 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.

Плагины для редакторов работали, так сказать, с переменным успехом (должен признаться, что я не работал с Nuclide, и возможно, попробуй я его, моя жизнь сложилась бы иначе, но я пробовал работать с Flow в Atom и в VSCode), я постоянно сталкивался с какими-то странностями. Меня окончательно оттолкнули от Flow регулярно возникающие проблемы с его надёжностью. Это было весьма досадно, так как подрывало мою веру в используемую мной систему контроля типов.

Я, честно говоря, не мог перестать думать о том, чтобы как следует взяться за TypeScript. Когда я, в ноябре, увидел этот твит, он выразил то, о чём я уже размышлял; краткий рассказ о переходе с Flow на 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, чем пытаться изучать новый язык.

Одно дело — подвигнуть коллег на то, чтобы пользоваться, в сущности, тем, что можно назвать «типизированным JavaScript» (особенно если с их стороны не требуется поддержка неких конфигураций), и совсем другой разговор состоится в том случае, если попытаться призвать коллег использовать совершенно другой язык и совершенно другую экосистему (и тут совершенно неважно то, насколько хорошо этот язык взаимодействует с JS и npm). Вероятно, если бы я выбрал Reason, мой PR никогда не попал бы в репозиторий sample-app.

Итоги

Сейчас мне хотелось бы поблагодарить всех пользователей Твиттера, под влиянием которых сформировалось моё видение TypeScript. Как я уже говорил, то, что библиотека paypal-scripts попала в репозиторий sample-app в PayPal, возможно, главное достижение моей карьеры. И я считаю, что то, что теперь шаблоны всех новых приложений в компании по умолчанию оснащаются поддержкой TypeScript — это огромный плюс для всех сотрудников PayPal. Я безмерно рад тому, что выбрал TypeScript.

Уважаемые читатели! Как вы думаете, стоит ли тем, кто пользуется Flow, смотреть в сторону TypeScript?


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Как провалить внедрение CRM-системы?

Одной моей коллеге очень хотелось иметь iPhone 4S. Тогда это был просто верх понта. Получив премию, она отказалась от отпуска и купила его — белый, приятно увесистый, зависть всей коммерческой службы. Через некоторое время она начала жаловаться, что, мол, не ...

Проверка FreeRDP с помощью анализатора PVS-Studio

FreeRDP – свободная реализация клиента Remote Desktop Protocol (RDP), протокола, реализующего удаленное управление компьютером, разработанного компанией Microsoft. Проект поддерживает множество платформ, среди которых Windows, Linux, macOS и даже iOS с Android. Этот проект выбран первым в рамках цикла статей, посвященных ...