У нас тут хоть и неофициальный, но очень способный наследничек объявился — Jaspr! 

Привет, меня зовут Алексей. В Пиробайте я разрабатываю мобильные приложения на Flutter. Расскажу, почему у этого фреймворка на стороне разработки сайтов все не так уж плохо. Спойлер — потому что Jaspr перехватывает всю инициативу на себя.

Каждый раз, когда мы начинаем сравнивать кроссплатформенные решения, например, Flutter и React Native, мы концентрируем свое внимание на весе конечного приложения, количества FPS при анимации, проценте нагрузки на оперативку и процессоре устройства. В итоге трудно объяснить, почему один лучше другого. 

У RN, конечно, есть одно неоспоримое преимущество — одна кодовая база под веб- и мобильные приложения. Понятное дело, что говорим мы не про презентационный слой, а про логику. Но ведь есть Flutter Web! Правда, мертвый. Или нет? (об этом можно поспорить в комментариях)

«‎Flutter Web мертв!‎» — сильное заявление, скажете вы. 

Canvas вместо нормального интерфейса, низкая скорость загрузки, отсутствие внятного server side rendering’а и невозможность (ну или сильная ограниченность) настройки SEO — скажу я. 

В целом, если вы разрабатываете независимое от SEO веб-приложение, то, наверное, Flutter Web неплохой вариант. Но для большинства решений оно не подойдет. Последние решения от команды разработки Flutter Web — это Flutter embedded, который позволяет встраивать виджеты в HTML. 

Однако, это все еще виджеты Flutter со всеми их проблемами (проблемами для веба). У разработчиков Flutter Web есть планы по улучшению производительности, интеграции WASM. Правда, этого недостаточно, и судя по всему, у них нет никаких планов по интеграции SSR и инструментов для работы с SEO. 

Ситуация, откровенно говоря, тупиковая. Но когда большие дяди с большими бюджетами тормозят и не делают решительных шагов, на сцену выходит комьюнити. Наш сегодняшний герой — веб-фреймворк для разработки на Flutter, с коротким именем Jaspr.

Что такое Jaspr? 

Если обратиться к документации, то это «‎современный веб-фреймворк для разработки веб-сайтов на Dart, который поддерживает как рендеринг со стороны клиента, так и со стороны сервера». То есть это фреймворк для Flutter. Jaspr переписывает его ядро, стараясь оставить основные концепции, чтобы программирование было максимально похоже на Flutter.

Пример: основной строительный блок интерфейса у Flutter — это виджет. Jaspr такой берет, думает — ага, ну работает круто, все оставляем, но называем это КОМПОНЕНТ (а все остальное, вплоть до вида этих компонентов, взяты из Flutter)

Что, фреймворк для разработки на Dart? Это что, новый Dart Angular?

И да, и нет. Чтобы лучше понять, снова процитируем документацию.

Для чего? Jaspr был разработан для того, чтобы сделать современный веб-фреймворк, который выглядит и ощущается как Flutter, но рендерит нормальный HTML/css как React, Vue или Angular. 

Для кого? Jaspr нацелен на Flutter-разработчиков, которые хотели бы создать совершенно любой сайт (особенно такой, который невозможно реализовать с помощью Flutter Web)

Что это? Jaspr стремиться расширить границы Dart на вебе и сервере, дав возможность использовать продуманный fullstack для веба, полностью написанный на Dart. С технической точки зрения да, это больше Dart, чем Flutter. Однако с точки зрения использования кода — это все же Flutter (с переписанным ядром). 

Как выглядят местные виджеты на Jaspr 

В Jaspr вместо виджетов используются компоненты (хоть выглядят и работают они так же, как и обычные виджеты). Чтобы лучше понять вышесказанное, предлагаю взглянуть на местные компоненты:

Похоже, не правда ли? Что-то вроде виджета, что-то вроде HTML… 

И это каждый раз так нужно писать DomComponent (tag: ‘тег который хочу’)? — спросите вы. 

Не совсем, вот пример поинтереснее: 

Да, Jaspr позволяет писать привычные HTML-теги внутри компонентов (с непривычным количеством скобочек). И, собственно, рендерятся они как обычный HTML.

И не нужно писать никакой параллельной структуры с помощью пакета seo_renderer

Окей, а что там с входной точкой? Какой-то HTML.index есть?

Есть лучше — компонент Document, который описывает основные мета-теги, пути до стилей и скриптов (прописывается он у нас в main.dart)

Однако, если хочется использовать обычный index.HTML, то можно расписать сначала его, а потом использовать Document.file.

С компонентами ясно, а что там с SSR? (основная фича, как никак)

И с этим Jaspr справляется достаточно лаконично. Как происходит загрузка файлов на сервер? Достаточно простого миксина и… вы великолепны!

А что по синхронизации с клиентом? И тут без откровений, опять миксины 

В общем, работает отлично и достаточно просто. В первый раз, конечно, так не кажется, потому что из-за скудной документации приходится немного попотеть. 

Энтрипоинты и гидрации Jaspr 

Здесь у фреймворка тоже все просто и делается с помощью кодогенерации:

Аннотация @client автоматически генерирует для нас энтрипоинты. У нас отпадает необходимость прописывать все ручками. И это потрясающе. Естественно, этой аннотацией можно отметить несколько компонентов и реализовать островную архитектуру. Jasp, ты просто космос. 

А что там по файлам билда? 

Выполняется билд простой командой jaspr build. Но на выходе получается достаточно любопытное, так как Jaspr генерирует не только веб-статику, но еще и компилируемый файл app. По дефолту это экзешник, который и является ядром вашего приложения для деплоя, однако с помощью флага –target это можно изменить (например, выбрать компиляцию в aot или jit). Этот самый app необходимо запускать вместе со всей веб-статикой. 

Мы уже как-то рассказывали, стоит ли Flutter-разработчику знать нативные языки для успешной разработки приложений (спойлер — не все так однозначно) Для Jaspr тоже встает вопрос — а можно ли использовать JavaScript, CSS? Если кратко — да, можно. Стили вы и так, скорее всего, будете писать с помощью CSS (у компонентов есть поле styles, где стилизация гораздо больше походит на стилизацию во Flutter, однако генерируются они в итоге как инлайновые стили, что не очень хорошо). 

Можно ли использовать библиотеки типа dart:html или dart:io? 

Кратко — да. Если чуть более детально — не везде. Ведь dart:html может использоваться только на стороне клиента, а dart:io — только на сервере. Но мы же тут пишем сайт с использованием SSR, как быть, если очень хочется использовать эти библиотеки (например, динамически менять заголовок сайта)? 

У Jaspr есть отличный ответ на этот вопрос и звучит он как — зависимые от платформы импорты. Выглядят они так:

Таких импортов может быть и несколько:

Что у Jaspr по библиотекам и пакетам? 

Если пакет рассчитан на Flutter — использовать нельзя, если на dart — можно. Однако тут стоит уточнить: у Jaspr есть свои пакеты, которые по сути являются адаптацией пакетов с Flutter. Вот список официальных пакетов: 

  • jaspr_router — для роутинга, работает на go_router 

  • jaspr_riverpod — для стейт менеджмента 

  • jaspr_flutter_embed jaspr_tailwind — да-да, больше фреймворков богу фреймворков! 

Но ведь не может быть все так хорошо, верно? И да, и нет. Давайте обозначим самое главное, от чего исходят все остальные минусы этого фреймворка — Его. Разрабатывает. Один. Человек.

Тут уж каждый сам для себя решает — хорошо это или плохо. С одной стороны, фреймворк независим от Flutter (а это плюс, учитывая постоянные обновления последнего). С другой стороны — скудная документация и внезапные баги. Особенно при использовании Windows. 

Но вы можете внести свой вклад в разработку этого замечательного фреймворка (нам, например, довелось найти несколько багов при разработке на Windows, которых больше нет) 

Как и у любого приличного проекта на Dart, у Jaspr есть своя песочница, в которой можно ознакомиться с основными фичами проекта. 

***

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

Комментарии (4)


  1. hardtop
    08.12.2023 07:21
    +3

    Правильно ли я понимаю, что задача Джаспера рисовать веб не на канвасе, а именно отдавать html? При этом Дарт компилится в JS?

    Выглядит громоздко. И если взять пример со стилезацией на Бульме - всё становится ещё тяжелее. И не очень понятно, как делать вёрстку - все эти медиа-запросы, 1 колонка на мобильном, 3 на десктопе...

    Хотя, может если сделать библиотеку адаптированных компонентов - может и получится.


    1. surale
      08.12.2023 07:21
      +1

      Да, дарт компилится в js, который генерирует все html компоненты (если не ошибаюсь, то react делает тоже самое с помощью js, именно поэтому SSR снова вошёл в моду, чтобы сильно не нагружать клиент и отправлять ему уже готовый HTML). Про Бульму и Tailwind - это дело вкуса, однако они позволяют не лезть в css и писать всё внутри компонентов (даже медиа-запросы, можно воспринимать это как эдакий CSS-in-JS). Вёрстка - по сути обыкновенный html, который подчиняется тем же медиазапросам и стилям, однако можно использовать компонент DomComponent для написания собственных кастомных тегов (в скриншоте ниже пример). Однако можно и компоненты свои написать так, словно это кастомные виджеты на флаттере


  1. 7r1ld
    08.12.2023 07:21

    А что там по файлам билда? 

    Выполняется билд простой командой jaspr build. Но на выходе получается достаточно любопытное, так как Jaspr генерирует не только веб-статику, но еще и компилируемый файл app.

    Как я понимаю в случае полностью клиентского приложения будет сгенерирована только статика без бинарника?

    На сколько оправдано разрабатывать веб приложение на jaspr'е?
    Чего не хватает в данный момент (библиотеки, возможности)?
    Как выглядит работа с document.head?


    1. surale
      08.12.2023 07:21
      +2

      По поводу билда: да, всё верно. Тут стоит понимать, что у jaspr cli есть несколько шаблонов, от которых зависит будет ли у вас бинарник или нет. При этом, даже если вы выбрали шаблон с SSR, вы можете отключить его в пабспеке и всё. Здесь же скажу, что jaspr build сбилдит статику и бинарник (а может и без него, если вы выбрали такой шаблон), а есть jaspr generate который изначально генерирует только статику, которую можно закинуть на любой хостинг. Зачем тогда две команды, если можно просто отключить SSR? Сложно сказать, кроме того jaspr generate не хочет работать, а в документации мало информации о нём. Я предполагаю, что разработчик его вырежет (раньше нельзя было использовать флаг ssr: false). Оправдано ли разрабатывать: скорее да, чем нет, особенно если у вас нет времени на написание логики на привычном для вебе языке. Чего не хватает: нормальной реализации BLoC, более полной документации (она хорошая, если держать в голове, что разработчик один, но в ней мало примеров кода). Работа с document.head: вызываем библиотеку dart:html, оттуда достаём document, из него head. На самом деле всё