Средства frontend в экоситеме Laravel

В статье пойдет речь о том, какие инструменты и заготовки имеет в своем распоряжении экосистема Laravel 9 для создания современной frontend части web приложения. Достаточно ли они современны, какие плюсы и минусы имеют.

Livewire

Чтобы сделать сайты более диманическими (почти такими, как их делают Vue и React), не покидая рамки php, Laravel предлагает такой инструмент как Livewire. Это некоторая надстройка-фреймворк, позволяющая логику динамического frontend компонента описывать как класс в php, а шаблон компонента создавать в blade. Таким образом, становится возможным добавить страницам интерактивности не осваивая сложные JS фреймворки и библиотеки, а использовать только php.

В коде это выглядит так.

use Livewire\Component;
 
class SearchUsers extends Component
{
    public $search = '';
 
    public function render()
    {
        return view('livewire.search-users', [
            'users' => User::where('username', $this->search)->get(),
        ]);
    }
}
<div>
    <input wire:model="search" type="text" placeholder="Search users..."/>
 
    <ul>
        @foreach($users as $user)
            <li>{{ $user->username }}</li>
        @endforeach
    </ul>
</div>
<body>
    ...
    @livewire('search-users')
    ...
</body>

Логика компонента, конечно, может содержать реакцию на события (например нажатие кнопок), изменение реактивных свойств компонента и т.п. Очень похоже на то, как это работает в Vue или React. Однако при каком-либо действии пользователя, требующем реакции на событие, происходит обращение к серверу за новыми данными. Сервер отдает html код компонента, который необходимо перерисовать и еще некоторые данные. В этом сильное отличие от того, как работают современные JS фреймворки и библиотеки.

Для того, кто любит пробовать вживую есть сайт с демонстрацией работы компонентов Livewire.


Inertia

Будем двигаться дальше. Если возможностей Livewire не хватает, разработчик выбирает Vue или React. При этом продолжает использовать Laravel как backend. Ему приходится решать некоторые рутинные инфраструктурные задачи. Такие задачи, как создание маршрутов в клиентской (frontend) части, получение данных из серверной части в клиентскую, реализацию аутентификации, поддержку серверного рендеринга (Server-Side Rendering).

Чтобы проще было решить такие задачи в экосистеме Laravel есть еще один полезный еще один полезный инструмент – Inertia.

У кода Inertia есть серверная часть и клинетская часть. Эти составляющие в тандеме и обеспечивают работу роутинга и передачу данных от сервера клиенту.

При использовании Inertia маршруты создаются и обрабатываются на сервере в привычном для Laravel виде. Передача данных на стороне сервера выглядит подобно тому, как передаются данные в blade шаблон в классическом для Laravel виде.

Все остальное, кроме маршрутов и передачи данных с сервера клиенту, разработчик в JS коде продолжает делать также, как обычно во Vue и React.

JS компоненты хранятся в файлах папки resources/js/Pages в привычном для frontend разработчика виде.

<script setup>
import Layout from '@/Layouts/Authenticated.vue';
import { Head } from '@inertiajs/inertia-vue3';
 
const props = defineProps(['user']);
</script>
 
<template>
    <Head title="User Profile" />
 
    <Layout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Profile
            </h2>
        </template>
 
        <div class="py-12">
            Hello, {{ user.name }}
        </div>
    </Layout>
</template>

Вызов Inertia::render() с указанием нужного компонента отдает компонент и внедряет в него данные.

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\User;
use Inertia\Inertia;
 
class UserController extends Controller
{
    /**
     * Show the profile for a given user.
     *
     * @param  int  $id
     * @return \Inertia\Response
     */
    public function show($id)
    {
        return Inertia::render('Users/Profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}

Все это позволяет писать меньше и при этом использовать всю мощь Vue или React. Таким способом можно создавать приложение с рендерингом на стороне клиента и в виде SPA, но без настройки маршрутов в клиентской части. Подход называется “современный монолит”.

Также Inertia поддерживает Server-Side Rendering.

И конечно можно посмотреть как Inertia работает вживую.

Starter Kits

Для того, чтобы избавить разработчика от рутины по поддержке аутентификации в современном приложении, экосистема Laravel предлагает стартовые инструменты Starter Kits. Это пакеты, которые содержат консольные команды для генерирования заготовок (scaffolding) вашего приложения, в которых уже решен вопрос аутентификации (регистрации, входа, сброса пароля и т.п).

Инструмента для старта приложения в Laravel 9 целых два – Breeze и Jetstream.

Breeze позволяет создать каркас приложения с использованием традиционных blade представлений оформленных с помощью Tailwind CSS. Или же можно выбрать создание frontend части с использованием Inertia (с Vue или React). Выбор между различными вариантами можно производить в командной строке при генерировании заготовки для приложения.

# Traditional blade implementation
php artisan breeze:install

# Or Inertia + Vue

php artisan breeze:install vue
 
# Or Inertia + React
 
php artisan breeze:install react
 
php artisan migrate
npm install
npm run dev

Для Server-Side Rendering с использованием Inertia SSR есть опция ssr:

php artisan breeze:install vue --ssr
php artisan breeze:install react --ssr

Второй пакет для старта приложения – Jetstream представляет собой более развитый инструмент, но вместе с тем и более сложный. Дизайн внешнего оформления сделан на базе Tailwind CSS. В качестве основы для frontend части Jetstream предлагает выбор между Livewire + Blade и Inertia + Vue.

Tailwind CSS

Немного слов об инструментарии для работы с CSS. Все готовые стили оформления в пакетах для старта приложения сделаны с использованием CSS фреймворка Tailwind CSS. Что он собой представляет? Это, так называемый, utility-first CSS framework, который задает все оформление прямо в html разметке при помощи специальных классов-утилит. Таких как, например, flex, pt-4, text-center. Вот как выглядит разметка.

<figure class="md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800">
  <img class="w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">
  <div class="pt-6 md:p-8 text-center md:text-left space-y-4">
    <blockquote>
      <p class="text-lg font-medium">
        “Tailwind CSS is the only framework that I've seen scale
        on large teams. It’s easy to customize, adapts to any design,
        and the build size is tiny.”
      </p>
    </blockquote>
    <figcaption class="font-medium">
      <div class="text-sky-500 dark:text-sky-400">
        Sarah Dayan
      </div>
      <div class="text-slate-700 dark:text-slate-500">
        Staff Engineer, Algolia
      </div>
    </figcaption>
  </div>
</figure>

Когда-то на заре html в нем использовались средства оформления через атрибуты тегов. Затем пришел CSS и мы получили удобство и гибкость. С одной разметкой стало можно получить множество вариаций оформления при помощи подключения разных стилей. Также стало возможным создавать классы для любых семантических блоков (например, аватар, комментарий, заголовок). Теперь же нам снова предлагаю отказаться от семантики и переиспользования кода и перейти на оформление внутри html.

Такой подход будет полезен, если нужно быстро создать прототип сайта, но при этом у вас нет достаточного количества квалифицированных в плане CSS разработчиков. Но со временем, если приложение будет жить и развиваться, такой подход создаст проблем.

Выводы

Экосистема Laravel предлагает ряд достаточно качественных решений для быстрого старта современного приложения (с разделением frontend и backend). Однако, если планируется развивать приложение и хочется избежать переписывания его через несколько месяцев, то лучше сразу создавать приложение используя практики, которые заслужили доверие и широко признаны. Сюда можно отнести

  • Выделение отдельной части frontend на современном фреймворке (или библиотеке). Например, vue или react.
  • Использование семантического подхода для оформления представления вместо различных CSS классов-утилит. Также стоит использовать какую-либо методологию. Например, БЭМ.

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

Laravel же стоит оставить для серверной части. В своей нише он прекрасен.

2 комментария

  1. Какие то голословные рекомендации. Хотелось бы увидеть, какие именно проблемы ждут на больших проектах с инерцией.

  2. Спасибо за внимание к статье. Я бы не назвал это рекомендациями. Это скорее выводы, которые сделал сам, и которые, может быть кому-то помогут.

    Касаемо Inertia. Мне лично не совсем понятно для чего она нужна, если во Vue и React есть маршрутизаторы. Да, конечно, немножечко быстрее можно создать маршрут и передать данные. Но стоит ли пилить новый инструмент для такого узкого применения? Это при том, что у Vue и React есть большие сообщества и их решения работают давно и стабильно на многих проектах. Основная масса кода же все равно реализует бизнес логику, а не работу с маршрутами.

    Правда, мне интересно будет услышать и альтернативную точку зрения. Если кто-то расскажет как он сэкономил массу времени и нервов отказавшись от роутинга во Vue в пользу Inertia, это станет полезной информацией.

Оставить ответ

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