- PVSM.RU - https://www.pvsm.ru -
16 апреля зарелизился ClojureDart, а это значит, что для любителей Clojure открылась возможность писать мобильные, веб- и десктоп-приложения на Flutter. Зачем использовать для этого Clojure, как бы очевидно это ни было, выходит за границы фокуса статьи.
На текущий момент инструменты еще не отшлифованы, нет репла(!) и автодополнений для dart-интеропа, но пользоваться можно, и некоторые плюшки кложуры уже показали себя (например, nest [1]-макрос, убирающий проблему вложенности, а вот код side-by-side [2]).
В этой статье хочу рассказать, как написать свое первое flutter-приложение на Clojure, какими инструментами удобно пользоваться, где искать ответы на вопросы. Статья для тех, кто имеет хотя бы минимальный опыт работы с Clojure.
И еще, статья [3] будет поддерживаться на гитхабе.
Ставим Flutter по официальной инструкции [4] и cli [5] для Clojure. Дополнительно не помешает clj-kondo [6], через который сейчас работают ворнинги для макроса apha/widget [7].
Вот как это выглядит:
На данный момент нет поддержки интеропа с дартом, и приходится использовать хаки, о которых подробнее расскажу ниже, но сперва немного о редакторах.
Я не пользователь VSCode, но насколько мне известно, это самый простой способ начать. Устанавливаем Calva, и все заработает само:
Не помешает поставить Flutter extenstion, подробнее тут [8].
Плюсы:
скорость и простота использования;
уникальный плагин Joyride [9], позволяющий писать настройки редактора с реплом на Clojure.
Результат, на который можно рассчитывать сейчас:
Есть автодополенения для Clojure (пример с reduce-
выше), но интеропа с дартом нет и отключить эти ворнинги нельзя.
Плюсы:
почти ничего не нужно настраивать и чинить;
поддержка придет в ближайшем будущем, и все заработает без вашего участия.
Минусы:
экстремально медленно открывается проект (до минуты на hello-world на моем air-е, с вимом я жду 125 мс);
нет возможности настроить подсветку и автодополнения (только выключить);
Чтобы настроить поддержку *.cljd, необходимо указать расширение для clojure:
preferences -> editor -> filetypes -> clojure file -> file patterns -> + -> *.cljd
Поддержка Flutter настраивается плагинами для Дарта и Флаттера, подробнее тут [10].
Поддержка ворнингов clj-kondo работает с плагином clojure-extras [11].
Тот же пример с reduce-
Плюсы:
скорость открытия, возможность открывать с десяток(сотню) проектов одновременно за миллисекунды;
расширенная кастомизация;
репл сам интегрируется в работу с выходом репла для ClojureDart;
возможность писать конфиги на лиспе (см. ниже).
Минусы:
нужно научиться пользоваться вимом;
нужно потратить время и настроить все самому;
иногда нужно заниматься починкой после обновления плагинов и самого вима.
Есть несколько опций, как завести вим для ClojureDart.
Ставим плагин [12] и 2 сервера — для Clojure [13] и Flutter [14] (полезные для флаттер-разработки команды [15] + базовый функционал для работы с дартом).
Прописываем настройку для распознавания *.cljd как Clojure:
au! BufRead,BufNewFile *.cljd setfiletype clojure
Я сейчас пользуюсь такой конфигурацией, и за исключением интеропа с дартом в ней есть практически все (рефакторинг, goto definition, find usages, автодополнения, документация, чистка неймспесов) .
Мой конфиг [16] описан на Fennel. Подробный разбор за рамками статьи, но если все же захочется использовать лисп, то я бы посоветовал начать с плагина aniseed [17] и дотфайлов [18] автора. В качестве начального конфига так же можно взять этот проект [19], либо готовую сборку nyoom [20].
Нужно настроить VimIced по инструкции [21] и подключить clj-kondo в качестве линтера (по этой [22] инструкции). Пока еще нет ClojureDart-репла, большей частью функционала будет пользоваться нельзя.
Не проверял этот плагин [23], но наверняка будет работать сопоставимо с VimIced, если где-то в виме прописать, что cljd -> это кложур.
au! BufRead,BufNewFile *.cljd setfiletype clojure
Разработчики ClojureDart пользуются Emacs, в Clojure-mode [24] уже добавили распознавание *.cljd. На мой взгляд, плюсы и минусы сопоставимы с вимом, а остальное — на любителя.
Рекомендую начать с hello-world [25], чтобы убедиться, что все работает.
В процессе работы удобно держать открытыми (под рукой) 3 окна:
Любой файл на дарте (можно создать дарт-файл в директории lib/), чтобы тут же экспериментировать, смотреть сигнатуры, методы, поля и пр.
Терминал, чтобы видеть логи и взаимодействовать с проектом.
Эмулятор (по моему опыту андроид-эмулятор стабильнее и быстрее веб-версии). Самый простой способ настроить его — установить AndroidStudio, и воспользоваться Tools->DeviceManagement.
После запуска "watcher"-а:сlj -M -m cljd.build flutter
Входим в петлю интерактивной разработки: пишем код, сохраняем файл, видим результат, снова пишем код...
Если нужен hot-reload, сохраняем файл.
Если нужен hot-restart, жмем Enter в терминале.
Если все перестает работать, удаляем папку .clojuredart/ и перезапускаем "watcher".
Как и в обычным Flutter-проекте, добавляем библиотеки в pubspec.yaml файл. Импортируем строкой, как и в *.dart файлах в формате, как в обычном Clojure:
(:require
[clojure.string :refer [join]]
["package:graphql/client.dart" :as g])
Единственный способ использовать свои dart-классы — выложить их отдельный проектом и добавить в pubspec.yaml. Возможно, в будущем добавят поддержку.
Практически всегда имеет смысл создать функцию (как в примерах [26]:2 от авторов), а не объявить класс с deftype (как я сделал тут [27]:4). Для создания же StatefulWidget удобнее всего использовать макрос alpha/widget [7].
В первую очередь, рекомендую прочесть доку [28] от авторов.
Другое отличие, с которым вы обязательно столкнетесь, это отсутствие библиотек, которые бы переводили данные в старые-добрые кложуровские PersistentHashMap. В примере [29](3) с GraphQL я написал функцию для перевода дартовой Map в кложуровую PersistentHashMap.
Сообщество сидит в слеке clojurians [30], канал #clojuredart. Большую часть вопросов уже задали, и можно "загуглить" их в чате. Авторы активно помогают, отвечают на все вопросы. Можно даже залить проект на гитхаб, и попросить совета/помощи в чате. Кто-то обязательно посмотрит.
Официальная документация [31] по ClojureDart.
Примеры кода [26] от авторов.
Пример приложения [32] c GraphQL и TEA-архитектурой.
Пример [27] написания кастомных виджетов с deftype.
Сообщество в Слеке — clojurians [30], канал #clojuredart
Автор: Артур Думчев
Источник [33]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/dart/374732
Ссылки в тексте:
[1] nest: https://github.com/Tensegritics/ClojureDart/blob/main/doc/flutter-helpers.md#nest-macro
[2] side-by-side: https://twitter.com/cgrand/status/1517652416396730369?t=T2md7PwYw8kfbulzAlVhUQ&s=09
[3] статья: https://github.com/Liverm0r/HowToClojureDart/blob/main/README.md
[4] инструкции: https://docs.flutter.dev/get-started/install
[5] cli: https://clojure.org/guides/deps_and_cli
[6] clj-kondo: https://github.com/clj-kondo/clj-kondo
[7] apha/widget: https://github.com/Tensegritics/ClojureDart/blob/main/doc/flutter-helpers.md#widget-macro
[8] тут: https://docs.flutter.dev/development/tools/vs-code
[9] Joyride: https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.joyride
[10] тут: https://docs.flutter.dev/development/tools/android-studio
[11] clojure-extras: https://plugins.jetbrains.com/plugin/18108-clojure-extras
[12] плагин: https://github.com/neovim/nvim-lspconfig
[13] Clojure: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#clojure_lsp
[14] Flutter: https://github.com/akinsho/flutter-tools.nvim
[15] команды: https://github.com/akinsho/flutter-tools.nvim#usage
[16] конфиг: https://github.com/Liverm0r/dotfiles/blob/master/.config/nvim/fnl/plugin/lspconfig.fnl
[17] aniseed: https://github.com/Olical/aniseed
[18] дотфайлов: https://github.com/Olical/dotfiles/tree/main/stowed/.config/nvim
[19] проект: https://github.com/rafaeldelboni/nvim-fennel-lsp-conjure-as-clojure-ide
[20] nyoom: https://github.com/shaunsingh/nyoom.nvim
[21] инструкции: https://liquidz.github.io/vim-iced/
[22] этой: https://github.com/clj-kondo/clj-kondo/blob/master/doc/editor-integration.md#ale
[23] этот плагин: https://github.com/tpope/vim-fireplace
[24] Clojure-mode: https://github.com/clojure-emacs/clojure-mode/blob/master/clojure-mode.el
[25] hello-world: https://github.com/Tensegritics/ClojureDart/blob/main/doc/flutter-quick-start.md
[26] примерах: https://github.com/Tensegritics/ClojureDart/tree/main/samples
[27] тут: https://github.com/Liverm0r/minataurus/blob/custom-widget/src/minataurus/fab.cljd
[28] доку: https://github.com/Tensegritics/ClojureDart/blob/main/doc/differences.md
[29] примере: https://github.com/Liverm0r/ClojureDartTeaExample/blob/main/src/tea/api.cljd
[30] clojurians: https://clojurians.slack.com
[31] документация: https://github.com/Tensegritics/ClojureDart/tree/main/doc
[32] Пример приложения: https://github.com/Liverm0r/ClojureDartTeaExample
[33] Источник: https://habr.com/ru/post/664026/?utm_source=habrahabr&utm_medium=rss&utm_campaign=664026
Нажмите здесь для печати.