В Ahrefs мы используем BuckleScript и ReasonML в производстве более двух лет. У нас уже есть кодовая база из десятков тысяч строк кода с несколькими веб-приложениями, которые требуют большого объема данных и взаимодействуют с серверными службами, написанными на OCaml, с использованием таких инструментов, как atd.

Принимая во внимание наши инвестиции в эти технологии, мы внимательно следим за недавними изменениями в ReScript с его ребрендингом и переименованием, а также за разделением проекта ReasonML, описанным в сообщении блога проекта.

ReScript: стать отдельным языком

Мы очень довольны тем, как ReScript объединяет возможности и упрощает разработчикам, начинающим работу, поиск документации в одном месте, а также по-прежнему уделяет большое внимание производительности и удобочитаемости вывода JavaScript.

С другой стороны, мы пытаемся выяснить последствия этого изменения в среднесрочной и долгосрочной перспективе, особенно в отношении интеграции с экосистемой OCaml. И что еще более важно, что эта эволюция будет означать для таких производственных пользователей, как мы, которые полагаются на эту интеграцию.

Интеграция ReScript с OCaml исторически была беспроблемной, поскольку BuckleScript изначально создавался как новый бэкэнд для компилятора OCaml. Однако в последние месяцы появилось несколько намеков на то, что ReScript хочет развиваться, чтобы стать собственным языком:

Таким образом, даже если официально ReScript не объявил о нарушении обратной совместимости с OCaml, сам факт того, что он придерживается старой версии компилятора OCaml, создает для нас некоторые проблемы с точки зрения инструментов. Неуверенность в будущем и темп изменений добавляют некоторый риск к высокоуровневым целям, которые мы ставим перед нашими командами и кодовой базой: мы хотели бы делиться большим кодом между интерфейсом и серверной частью, а не меньше.

Melange: форк ReScript, ориентированный на совместимость с OCaml.

Когда Антониу Монтейро анонсировал Melange, ответвление ReScript, но с упором на сохранение совместимости с OCaml, мы решили попробовать его и посмотреть, как он может сработать для нас.

В конечном итоге эксперимент удался. Нам удалось собрать все наши интерфейсные приложения с помощью Melange, сохранив при этом существующую настройку пакетирования, которая в настоящее время использует Webpack.

В ходе этого процесса нам пришлось изменить некоторые части кода. Теперь мы рассмотрим наиболее важные части процесса:

  • Обновление до OCaml 4.12: наиболее важной частью было прекращение использования модуля Pervasives для использования Stdlib.
  • Используйте ppxlib в наших ppx: нам пришлось обновить два ppx, которые мы используем в кодовой базе внешнего интерфейса, до последней версии компилятора, bs-Emotion-ppx и собственного ppx для интернационализации.
  • Настроить esy: мы уже использовали esy для переноса инструментов редактора в область действия среды разработчика, поэтому нам просто нужно было убедиться, что melange также будет включен в конфигурацию json.
  • Обновление до Reason 3.7.0: тоже довольно простое изменение, так как весь процесс автоматизирован с использованием refmt. В качестве примечания, мы столкнулись с небольшой ошибкой с некоторыми аннотациями типов, которую мы смогли обойти.
  • «Поднимите» рабочее пространство дюн к корню нашего монорепозитория: это, наверное, самое навязчивое изменение. Поскольку у нас общий код между серверной частью и фронтендом, а Dune должен иметь доступ ко всем источникам в своей рабочей области, нам пришлось «поднять» рабочее пространство Dune из каталога backend в корень monorepo.

Добро

Этот эксперимент позволил нам испытать, что такой проект, как Melange, может предложить для нашего варианта использования. Вот некоторые из вещей, которые мы могли бы использовать в кодовой базе, созданной с помощью Melange:

  • Последняя версия компилятора OCaml: в какой-то момент мы могли закрепить версию компилятора между командами бэкэнд и фронтенд, что упростило обновление, поскольку оно происходило бы атомарно.
  • Общие инструменты редактора: официальное расширение vscode для OCaml отлично работает с Melange, а также с любой другой интеграцией редактора OCaml. Если бэкэнд- и фронтенд-команды используют схожую настройку редактора, нам не нужно выполнять много работы по обслуживанию.
  • Потребление ppx из источника: Melange позволяет потреблять ppx из источника, что также устраняет проблемы с предварительно скомпилированными ppx (как эта проблема с недавними M1 Mac).
  • Melange позволяет запускать все ppx из одного исполняемого файла, что дает хорошие преимущества в производительности.
  • Используйте Dune для генераторов файлов atd: генераторы ReScript, к сожалению, больше не документированы, но мы широко используем их для генерации файлов atd. Возможность делиться правилами Dune в бэкэнде и во внешнем интерфейсе упростит настройку нашей сборки.
  • Доступ к инструментам документации OCaml: Melange позволяет использовать существующие инструменты для создания документации, такие как odoc.
  • Синтаксис Async: последняя версия Reason поддерживает синтаксис let op, что удобно для клиентского кода.

Плохо

Хотя в Меланже есть много интересных моментов, есть и другие части, которые можно улучшить.

  • Производительность сборки: мы уже знали, что производительность будет намного хуже, чем у ReScript, поскольку Меланж использует Dune не так, как он был разработан. В наших тестах сборки с Melange примерно на 1 порядок медленнее, чем с ReScript.
  • Первоклассная поддержка Dune: если бы между Dune и Melange была более глубокая интеграция, мы могли бы изучить такие функции, как общие библиотеки или общие правила между серверной частью и внешним интерфейсом. На сегодняшний день Dune ничего не знает о среде Melange, поэтому она может выполнять основные правила, но нет доступа к строфам высокого уровня, таким как library в Melange.
  • Двуглавая цель: наконец, мы видим более стратегический риск в предложении Меланжа. Сейчас у него две цели: сохранить совместимость как с ReScript, так и с OCaml. Но мы не знаем, как долго эти цели будут достижимы. Если в какой-то момент ReScript решит полностью отказаться от компилятора OCaml, то пользователи Melange больше не смогут получать какие-либо обновления экосистемы ReScript.

Хорошо, но вы переходите на Melange или ReScript?

Учитывая всю доступную информацию, ответ таков: мы еще не знаем. 😄 Мы хотим продолжить изучение всех доступных вариантов и получить как можно больше информации, прежде чем совершать дальнейшие действия. Итак, на данный момент мы обновляем кодовую базу до последних версий ReScript, но задерживаем функции, которые работают только в одном направлении. Например, мы еще не перевели нашу кодовую базу на синтаксис ReScript, так как нет возможности вернуться к синтаксису Reason.

А пока мы продолжим изучать, насколько можно смягчить ограничения Melange. Продолжение следует! 🚀

Спасибо Игорю и Фейхонгу за просмотр и улучшение предыдущих версий этого сообщения.