Как вы уже поняли по предыдущим заметкам, бэкенд и фронтенд Vesp не зависят друг от друга вообще никак. На прошлом занятии мы отправляли запросы в API из консоли через cURL и всё нормально работало.
Вместо консоли это могло быть и мобильное приложение, и любой веб-сайт. Я же предлагаю использовать веб-приложение, написанное на VueJS, с использованием NuxtJS - потому что они мне очень нравятся. И сейчас расскажу, почему.
VueJS - это реактивный фреймворк, написанный на JavaScript. В отличие от jQuery и подобных библиотек, которые манипулируют уже готовым DOM страницы: выбирают элементы, добавляют, меняют и т.д., Vue полностью строит этот DOM исходя из своих данных. То есть, для jQuery источником данных являются теги на странице, а для Vue же источником данных является сам Vue, а страница отображает его состояние.
Поэтому когда что-то меняется в данных Vue, то изменения сразу отображаются на странице. Вам не нужно искать какой-то DOM элемент по имени класса и менять ему значение, нет. Вы меняете значение в Vue, и он сам обновляет страницу. Именно поэтому подобные фреймворки и называют реактивными.
NuxtJS, в свою очередь, берёт Vue и добавляет в него структуру и всякие удобные штуки, вроде серверного рендеринга. Примерно как Laravel является фреймфорком для PHP, Nuxt является фреймворком для Vue.
Вместе они позволяют писать настоящие приложения очень быстро и удобно, особенно когда в них разберёшься =)
Лично я немного пробовал и другие рективные фреймфорки: AngularJS и ReactJS, но как-то не пошло, показалось что они переусложнены. А вот Vue наоборот, очень понятный и простой. Если вы с ним еще не знакомы, посмотрите вот эту страничку.
Vesp устанавливает по умолчанию сразу 2 независимых веб-приложения: admin и site. Соответственно, админку проекта и его публичную часть. Админка генерируется в статичные файлы (html, js, css), а публичный сайт расчитан на серверный рендеринг. Их можно и нужно разрабатывать и выгружать на хостинг раздельно, они совершенно никак не связаны, только работой с одним общим бэкендом.
Оба приложения находятся в соответствующих директориях в frontend/src/
, а в корне frontend
лежат служебные файлы:
eslintrc.js
- конфигурация правил линтера, про него ниже.eslintignore
- список файлов, исключенных из проверки линтером.prettierrc
- правила форматирования кода, расскажу вместе с линтеромecosystem.config.js
- конфигурация для запуска сервера pm2, это когда мы будем рендерить фронт на сервереpackage.json
- набор зависимостей проектаwebpack.config.js
- ненастоящий конфиг webpack, нужен только для автодополнения в PhpStorm.Там же директории:
.nuxt
- кэш сборки приложений, создаётся автоматически после удаленияdist
- а сюда собираются готовые статические приложения, так же в директории admin
и site
.node_modules
- установленные зависимости проектаsrc
- исходный код наших приложений, с которым мы и будем работатьОсновной зависимостью наших фронтенд приложений является @vesp/frontend
, в который я собрал всё нужное для работы - смотрите его зависимости в package.json.
Основная конфигурация проекта и всех его расширений хранится в одном-единственном файле nuxt.config.js.
Наши приложения site и admin будут наследовать и расширять именно эту конфигурацию по-умолчанию.
@vesp/frontend
по умолчанию подключает линтер и prettier (украшатель, наверное, по-русски). Зачем они нужны?
ESLint проверяет синтаксис в исходных файлах приложения и заставляет вас исправлять ошибки во время разработки.
Вот здесь вам говорят, что при проходе через массив, каждый элемент обязан иметь уникальный ключ - и пока вы его не добавите, ничего работать не будет. Таким образом правильно настроенный линтер ловит ваши основные ошибки и очень сильно облегчает работу.
А Prettier расширяет линтер, добавляя проверку не самого кода, а его форматирования. Он регламентирует ширину отступов, правила выставления пустых строк, запятых и всего такого.
Вместе они гарантируют, что все ваши фронтенд-проекты будут выглядеть одинаково, что само по себе уже хорошо, а если вы работаете в команде - так и вовсе прекрасно.
Например, если в правилах прописаны 4 пробела для отступов, а кто-то пихает таб, то проект просто не будет собираться и работать.
Это приложение очень простое, с самым минимумом зависимостей. Конфигурация находится в frontend/src/site/nuxt.config.js
и расширяет конфиг из @vesp/frontend
.
Давайте посмотрим на неё:
// Импортируем нужные функции из родительской библиотеки
import {Config, findEnv, loadEnv} from '@vesp/frontend'
// Эти настройки обычно не требуется менять
// приложение поддерживает серверный рендеринг
Config.ssr = true
// директория с исходниками - это текущая директория, та где лежит конфиг
Config.srcDir = __dirname
// Цель сборки может быть static или server, то есть статичные файлы или для сервера
Config.target = 'server'
// Временная директория для файлов сборки
Config.buildDir = '.nuxt/site'
// Настройки статической генерации
Config.generate = {
dir: 'dist/site',
exclude: [/^\//],
}
// Здесь мы читаем наш .env файл, чтобы бэкенд и фронт использовали
// одни и те же настройки
const env = loadEnv(findEnv('../'))
// Дальше идут настройки HTML тега head:
Config.head.title = env.APP_NAME || 'Vesp Framework'
// Здесь ссылки на иконки приложения
Config.head.link = [
{rel: 'icon', type: 'image/x-icon', href: '/favicons/favicon.ico'},
{rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicons/favicon-32x32.png'},
{rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicons/favicon-16x16.png'},
{rel: 'apple-touch-icon', sizes: '180x180', href: '/favicons/apple-touch-icon.png'},
{rel: 'manifest', href: '/favicons/site.webmanifest'},
]
// Дополнительные расширения Nuxt
// Именно здесь подключается ESLint, например
Config.buildModules = ['@nuxtjs/style-resources', '@nuxtjs/eslint-module']
// А здесь библиотека Bootstrap-Vue с UX компонентами и PWA модуль
Config.modules = ['bootstrap-vue/nuxt', '@nuxtjs/pwa']
// Иконка Progressive Web Application
Config.pwa = {
icon: {
fileName: 'favicons/android-chrome-512x512.png',
},
}
// Мы используем только определённые компоненты Bootstrap-Vue
// чтобы сделать сборку легче
Config.bootstrapVue.componentPlugins = ['LayoutPlugin', 'ImagePlugin', 'LinkPlugin']
// Файл должен вернуть массив с настройками
export default Config
Логика точно такая же, как при расширении классов PHP - импортируем что нужно, меняем и возвращаем.
До сих пор все команды мы запускали через composer
, но на самом деле это просто такой shortcut, ссылка.
Например composer node:generate
делает переход во frontend
и запускает там yarn generate:admin
и yarn generate:site
.
Все доступные команды прописаны в package.json и мы вполне можем вызывать их самостоятельно из директории frontend
. Давайте посмотрим, что там есть для приложения site:
analyze:site
- сборка приложения для анализа входящих в него пакетов и занимаемого ими места. Очень полезная штука, если вы не хотите раздувать своё приложение.dev:site
- запуск приложения в режиме "для разработки", открывается локальный nuxt сервер, который обновляет страницы при изменении исходных файлов. Так называемый hot reload, очень удобноbuild:site
- сборка приложения для продакшена в директорию frontend/.nuxt/site
generate:site
- генерация статических файлов для размешения на хостинге без запуска сервера Nuxt, то есть просто набор HTML, JS и CSSstart:site
- а вот это как раз запуск собранного приложения в серверном режиме с серверным рендерингом, через Process Manager (pm2). Про это будем говорить позже.Для примера давайте запустим
yarn analyze:site
Если у вас не установлен yarn
, то сделайне npm i --global yarn
В браузере должна открыться вот такая чудесная страница со структурой вашего приложения и всеми зависимостями. Она вполне интерактивная и позволяет всё подробно рассмотреть.
Рекомендую время от времени запускать анализ для контроля размера вашего приложения, это очень полезно.
Команда yarn generate:site
сгенерирует статические файлы в src/frontend/site
, которые будут открыты нашим локальным Valet при помощи драйвера для Vesp.
Благодаря использованию Nuxt мы всегда имеем одну и ту же структуру приложения, с одинаковыми директориями. Никакой фантазии, понимаю, но в этом случае она и не нужна!
assets
- наши картинки, стили, шрифты и прочие ассеты, которые будут импортироваться в проектlayouts
- шаблоны для страниц, как template в MODXpages
- собственно страницы приложения, как ресурсы в MODXstatic
- директория со статичными файлами, которые будут размещены в корне собранного приложения. Например, фавиконки.Nuxt автоматически генерирует структуру сайта исходя из файлов в pages, пока что там один index.vue
. При добавлении новых страниц мы получим новые адреса на сайте.
Оформляются они с помощью шаблона frontend/src/site/layouts/default.vue
, там обязательно должен быть тег <nuxt />
- именно туда и будет вставлено содержимое страницы.
При навигации по сайту содержимое этого тега меняться будет, а шаблона - нет. Примерно так и получается Single Page Application (SPA), когда весь сайт работает без перезагрузки страницы.
Давайте запустим разработку сайта в директории frontend
:
yarn dev:site
Эта команда запускает локальный сервер Nuxt с горячей перезагрузкой.
после запуска вы видите адрес, по которому доступен сервер. У меня это http://192.168.0.254:4100
, но у вас может быть другой - зависит от настроек вашей сети.
Переходим по нему и видим наш текущий сайт.
Теперь идём в frontend/src/site/pages/index.vue
. Файл состоит из 3х секций:
template
- разметка страницы с HTML тегами и компонентами Vuescript
- javascript код, который будет работать с этой разметкойstyle
- SCSS оформление templateМы можем просто взять и поменять в style
цвет фона страницы на $red
- все SCSS переменные берутся из site/assets/_variables.scss
и как следствие из Bootstrap:
body {
background-color: $red;
color: $gray-500;
}
И вот результат, который вы должны увидеть сразу же, без перезагрузки страницы:
Можно дальше менять страницу и смотреть в браузере, что получается.
Думаю, для одного занятия инфорации пока достаточно, в следующий раз будем рассматривать второе, более сложное приложение - админку.
А потом начнём уже и сами что-то создавать.
Понимаю, что информации много и не всё может быть понятно, но прошу запастись терпением, во время практической работы всё обязательно встанет на свои места.
Я, как старый страпёр, собираю всё ещё на gulp'е (при чём, меня он устраивает, но у меня там всё для modx заточено), а тут оказывается уже webpack'ом народ пользуeтся! Однако, закинул удочку своему корешу по веб-разработке, и он советует сразу использовать vite, минуя вебпак - мол проще разбраться, и бытрей работает. Кто-нибудь пробовал его на vesp? или, не стоит заморачиваться, и работать просто с webpack'ом?
Да, мне тоже нравится Vite и он по умолчанию используется в Vue 3 и Nuxt 3. Более того, он вроде как и создан автором Vue с командой. Но здесь мы изучаем Nuxt 2, и в нём используется Webpack.
Учитывая, насколько всё это удобно интегрировано в Nuxt - разницы особой и нет, просто читаешь документацию по настройкам нужной версии Nuxt и всё передаётся в её бандлер.
Это видимо работает только на локалке? У меня VESP на VPS висит и там после этой команды что-то формируется, но эту страницу на реальном домене открыть не получается. Или же нужно дополнительно настраивать пути сервера, для выполнения этой команды? Ну если это вообще нужно.
[ всё локально разрабатываю, запускать
analyze
на удалённом сервере и настраивать для него Nginx ни разу не пробовал.Ок, понял, спасибо