Обновил Webstartpage.ru

В последнее время много работы, никак не связанной с Vesp, зато очень хорошо оплачиваемой.

Чтобы не потерять навыки, решил поиграться с Nuxt 3 в свободное время на реальной задаче - переписал весь фронтенд своей домашней странички webstartpage.ru.

Это мой самый первый проект, живой до сих пор. Там можно авторизоваться через соцсети и хранить свои ссылки. Понятно дело, что в 2023 году такие странички не особо востребованы, потому что они уже встроены в браузер - но я привык к своей. Она была сделана и на MODX Evolutuion, и на Revolution (2 раза), потом на Vesp с Nuxt 2, а теперь вот и на Nuxt 3.

Получается, что этот сайт у меня всегда на острие прогресса!

Что изменилось в этот раз:

  • Vue 2 -> Vue 3
  • Nuxt 2 -> Nuxt 3
  • Vuex -> Pinia
  • Bootstrap 4 -> Bootstrap 5

Бэкенд на PHP остался без изменений.

Про Vue 3

Основное изменение, превнесённое 3й версией - Composition API. Это новый синтаксис, который вместо возврата объекта с data, methods, computed и т.д., вызывает всякие функции и переменные в одном месте.

Например у нас вот такой шаблон:

<template>
    <div>Variable: {{ count }}</div>
    <button @click="iterate">{{ text }}</button>
</template

А в Vue 2 такой код для его работы:

<script>
export default {
    data() {
        return {
            text: 'Iterate variable',
            count: 0,
        }
    },
    methods: {
        iterate() {
            this.count++
        },
    }
}
</script>

В Vue 3 будет вот так:

<script setup>
import {ref} from 'vue'

const text = ref('Iterate variable!')
const count = ref(0)

function iterate() {
    count.value++
}
</script>

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

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

Конечно, Vue 3 поддерживает и старый Options API, но какой тогда смысл перехода на новую версию?

Также 3я версия нативно поддерживает TypeScript, который раньше я обходил стороной. Оказалось, что штука эта весьма полезна и позволяет серьёзно сократить количество возможных ошибок за счёт проверки типов переменных.

Про Nuxt 3

В этом же русле двигается и Nuxt 3 - всё на TypeScript, плюс автоматическая подготовка и загрузка типов, чтобы их не нужно было импортировать самостоятельно.

Полезные функции, вынесенные в директорию composables, загружаются самостоятельно. Например, работа с API у меня выглядит вот так:

<template>
    <div>
        <div v-show="!pending">Данные: {{ data }}</div>
        <button @click="refresh">Обновить данные</button>
    </div>
</template>
<script setup>
const {data, pending, refresh} = await useGet('end/point')
</script>

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

Функция useGet - моя собственная composable, которая внутри себя использует родной useFetch с добавлением обработки ошибок и заголовков для авторизации. Есть еще usePost, usePatch, useDelete и useApi для специальных запросов с ручным указанием дополнительных параметров.

В итоге очень быстро привыкаешь вместо this.$axios.get писать useGet и не думать, а есть ли у тебя в этом месте вообще this? Потому что composables есть везде.

Помимо всяких автозагрузок и прикольных новых методов у Nuxt теперь и новый сервер для сборки Vite, и свой серверный движок Nitro.

Разработка стала просто молниеносной, до сих пор удивляюсь скорости обновления.

Про Pinia

К сожалению, не все модули Nuxt были обновлены для работы с новой версией, и больше всего мне не хватило Nuxt Auth. Так что авторизацию и работу с пользователем пришлось написать самостоятельно, используя Pinia.

Это современная замена хранилища Vuex, более простая и вся на TypeScript. Поэтому с ней можно прописать себе типы для работы, чтобы везде были подсказки.

Например, я указал своих юзеров:

export type VespUser = {
  id: number
  username: string
  fullname: string
  email: string
  scope: [string]
  [key: string]: any
}
export type RefVespUser = Ref & {
  value: VespUser | null
}

Добавил composable функцию useAuth для быстрого доступа к этому хранилищу, и стало хорошо:

С одной стороны, пришлось это всё писать самостоятельно. А с другой, я разобрался как оно работает и сторонние плагины мне больше не нужны.

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

Про Bootstrap 5

Тут всё не так радужно, увы. Сам-то Bootstrap 5 в порядке, а вот Bootstrap-Vue пока что новую версию совсем не поддерживает. Ему прикрутили какой-то плагин для поддержки Vue 3, но вот именно CSS новой версии - нет.

Хорошо, что уже появлися новый проект, который они взяли под свое крыло - Bootstrap-Vue-Next. Это по сути ремейк оригинальной библиотеки, но на Vue 3 + TypeScript, и с 5й версией Bootstrap.

Он еще очень сырой и для серьёзной работы не готов. Многие модули по-прежнему используют родной Javascript от Bootstrap, который не работает при серверном рендере, например компонент Modal.

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

Интересно, что он из коробки поддерживает Nuxt 3, но пока что с ошибками. Через встроенный модуль у меня не заработал Dropdown - просто не реагировал на нажатия.

Пришлось отказаться от родного модуля и загружать компоненты вручную:

import {BDropdown} from 'bootstrap-vue-next'

Тогда работает без проблем.

Заключение

Новые версии Vue и Nuxt просто глоток свежего воздуха! Разработка стала гораздо быстрее, итоговая сборка в 2 раза меньше.

Слева на картинке сайт на Nuxt 2 грузит 2.14 Mb (515 Kb сжатых Gzip), а новый Nuxt 3 собрал всё в 854 Kb (246 Kb сжатых).

Все скрипты и стили помещаются в 246 килобайт! Функционал при этом тот же самый, ничего не убрано.

Единственное, что меня останавливает пока использовать этот стек везде - состояние Bootstrap-Vue-Next, он еще очень сырой. Для себя использовать можно, на заказ - рановато. На сервере не работает вообще, только на клиенте.

Если кому интересно сравнить новую и старую версии - я открыл доступ в репозиторий для всех желающих https://gitlab.com/bezumkin/webstartpage/

Вот здесь 2 ветки: Nuxt 2 и Master (Nuxt 3), можно склонировать и сравнивать было-стало. Там же есть конфигурация Docker, так что сложностей возникнуть не должно.

Если есть вопросы - задавайте в комментариях.

Комментарии (6)
Вася
04.04.2023 07:07

Если кому то нужен отдельно Dropdown на nuxt3 рабочий вариант еще есть floating-vue

bezumkinВасилий Наумкин
04.04.2023 07:33

Так он и в Bootstrap-Vue-Next рабочий, просто нужно импортировать вручную, а не через подключение модуля для Nuxt.

Андрей
21.04.2023 04:28

А зачем на этой странице вообще Bootstrap нужен? Для скорости разработки?

bezumkinВасилий Наумкин
21.04.2023 05:40

Для удобства, конечно. Не самому же мне все стили для форм и модалок писать.

Для этого же я и Nuxt использую, хотя мог бы всё на чистом Vue3 + Vite сделать, но зачем?

Андрей
21.04.2023 06:29

Думается, если выпилить бутстрап, то размер стилей радикально сократится )) И страница будет ещё компактней Не обязательно самому всё писать - есть замечательный tailwind. Он умеет кстати собирать только то, что используется. Хотя и новый бутстрап, может, тоже уже так умеет - давно на него не глядел...

bezumkinВасилий Наумкин
21.04.2023 06:52

Радикально - это насколько, еще на 50 килобайт из 250? А писанины это насколько увеличит?

Сейчас я просто использую готовые компоненты Bootstrap-Vue-Next вместе со стилями, а на замечательном Tailwind таких компонентов нет, нужно всё писать руками.

Я пробовал работать с Tailwind, мне не понравилось.

bezumkin
Василий Наумкин
01.03.2024 04:30
С PWA пока не разбирался, мне кажется это не особо популярная штука. Если надо просто иконки добавит...
bezumkin
Василий Наумкин
22.02.2024 09:23
На здоровье! Держи лайк =)
inetlover
Александр Наумов
27.01.2024 00:06
Василий, спасибо! Извини, тупанул.
bezumkin
Василий Наумкин
22.01.2024 04:43
Давай-давай!
bezumkin
Василий Наумкин
24.12.2023 11:26
Спасибо!
bezumkin
Василий Наумкин
27.11.2023 02:43
Ура!
bezumkin
Василий Наумкин
25.11.2023 08:30
Vesp тянет 2 зависимости: vesp-frontent для фронта и vesp-core для бэкенда. Их можно обновлять, но э...
bezumkin
Василий Наумкин
22.11.2023 08:09
Отлично, поздравляю!
bezumkin
Василий Наумкин
04.11.2023 10:31
На здоровье!
bezumkin
Василий Наумкин
30.10.2023 01:21
Спасибо!