Inertia.js – современный монолит

от автора

Inertia – современный монолит

Вы знаете, как пишутся SPA на Laravel? Если коротко, не очень удобно. Конечно, можно использовать любой фронтенд-фреймворк. Традиционно принято работать со связкой Laravel + Vue.js.

Мы пишем весь фронтенд на Vue.js в resources/js, а Laravel используем как API.

Примерно вот так:

Vue.js

// resources/js/pages/Users.vue <template>     <div v-for="user in users" :key="user.id">         <a :href="`/users/${user.id}`">           {{ user.name }}         </a>         <div>{{ user.email }}</div>     </div> </template>  <script>     export default {         data() {             return {                 users: []             }         },         methods: {             async loadUsers() {                 const { data } = await this.$axios.get('/api/users');.                 this.users = data;             }         },         async beforeMount() {             await this.loadUsers();         }     } </script>

Laravel

// routes/api.php Route::get('/users', function index(User $user) {     return $user->all(); });

То есть сначала мы создаем на бэкенде эндпоинт, а затем на фронте получаем с него данные через AJAX-запрос.

Удобно ли это? Смотря для кого. Фронтендерам не привыкать. AJAX на сегодня – самый классический способ получения данных с сервера. Но, если вы до этого много работали с Blade, вы понимаете, насколько это больше телодвижений.

Хотелось бы как с Blade, просто вернуть страницу уже с массивом данных, доступном на фронте как переменные:

return view('users', [     'users' => $user->all() ]);

Какая разница? Она заметна, если нам нужно добавить еще какую-нибудь информацию во фронтенд-компонент. С Blade мы просто добавляем новую пару ключ-значение в массив данных. Но если Laravel – это просто API, нам нужно по-хорошему создавать отдельный эндпоинт. И т.д. и т.п.

От этого неудобства нас избавляет библиотека Inertia.js. С её помощью мы можем писать своё приложение так, будто бы мы пишем всё на Blade. Однако вместо него на стороне фронта использовать любимый фреймворк – Vue, React или Svelte.

Кроме Laravel, Inertia.js также может работать с бэкендом на Rails. И это только официально. Сторонние разработчики также добавляют поддержку других фреймворков и библиотек (например, Symfony или Yii2).

Далее все примеры будут на Vue.js и Laravel. Но при этом держите в уме, что всё это же можно делать и с другими вышеуказанными библиотеками.

Теперь на стороне сервера мы пишем

return Inertia::render('Users', [     'users' => $user->all() ]);

А на фронте получаем данные как props.

props: {   users: Array, },

Круто! Но это еще не всё.

Киллер-фича №2: Роутеры (Vue Router, React Router) больше не нужны. Теперь все страницы – это записи в routes и Vue-компоненты в папке resources/js/Pages (название папки кастомизируется). Всё, как с Blade, единственное, теперь вместо component.blade.php у вас Component.vue.

Ну и моё любимое: валидация на сервере. Больше не нужно отправлять ошибки AJAX-ом, а потом парсить их на фронте, где-то сохранять и таскать оттуда. Теперь можно просто расшарить ошибки из сессии в AppServiceProvider

Inertia::share([     'errors' => function () {         return Session::get('errors')             ? Session::get('errors')->getBag('default')->getMessages()             : (object) [];     }, ]);

и получать их во Vue-компонентах как $page.errors.

<div v-if="$page.errors.first_name">{{ $page.errors.first_name[0] }}</div>

Тоже самое для уведомлений и любых других общих для всех компонентов данных.

При этом, данные можно шарить как синхронно (как в примере выше), так и "лениво", просто передавая в массив вместо самих данных колбэк, который их возвращает.

Inertia::share([     // Синхронно     'app' => [         'name' => Config::get('app.name')     ],     // Лениво     'auth' => function () {         return [             'user' => Auth::user() ? [                 'id' => Auth::user()->id,                 'first_name' => Auth::user()->first_name,                 'last_name' => Auth::user()->last_name,             ] : null         ];     } ]);

Чтобы начать пользоваться, переходим в документации на страницу установки, выбираем нужные адаптеры – один для фронта, другой для бэка – и просто следуем инструкциям (1, 2).

Кстати, документация очень небольшая и удобная, всё наглядно и понятно, есть примеры на всех официально поддерживаемых фреймворках. Есть даже демо-приложение для того, чтобы посмотреть на всё в работе.

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

Но как и в любой бочке мёда, тут есть своя ложка дегтя.

Во-первых, Inertia.js должен контролировать рендеринг. Это значит, что нельзя просто перевести какой-то конкретный компонент на Inertia.js, нужно переносить всё приложение. По крайней мере, весь инстанс (если у вас микрофронтенды).

Во-вторых, тут нет Server-Side Rendering (SSR). Что, в принципе, неудивительно, ведь это просто прослойка между фронтом и бэком, а фронт как был SPA без SSR, так и остается. Но, возможно, эту функциональность добавят в будущем, разработчики говорят, что это возможно. Если вам кровь из носа нужен SSR, стоит посмотреть на бойца в противоположном углу ринга – Livewire. Но про него как-нибудь в другой раз.

Ну и в-третьих, Inertia.js – еще очень молодой проект. Последняя версия на момент написания статьи – v0.1.9. Поэтому смотрите сами, хотите ли вы использовать его в продакшене.

Тем не менее, я советую всем web-разработчикам попробовать и оценить самим этот замечательный инструмент.

ссылка на оригинал статьи https://habr.com/ru/post/511470/


Комментарии

Добавить комментарий

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