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

в 10:27, , рубрики: flow, javascript, TypeScript, Блог компании RUVDS.com, платежные системы, разработка, Разработка веб-сайтов

Недавно мы опубликовали материал, в котором Эрик Эллиот критиковал 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), обновления которой обычно не содержат в себе чего-то такого, что способно нарушить работу кода, полагающегося на неё. В результате достаточно поддерживать в актуальном состоянии лишь одну зависимость и спокойно заниматься разработкой приложений.

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

  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.

Меня окончательно оттолкнули от 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?

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

Автор: ru_vds

Источник

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


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