Основа для большого модульного SPA на Laravel + Vue + ElementUI с CRUD генератором

от автора

image

Последние годы удалось поработать над несколькими большими и не очень проектами с использованием разных back-end и front-end фреймворков. Сталкивался с разными проблемами, возникавшими по мере роста приложения.

Сейчас могу сделать вывод из того, какие решения были удачными, а какие — не очень.
Используя накопленный опыт, задался целью собрать все лучшие решения, на мой взгляд, и создать свою основу для SPA.

Как создавать сайт на Laravel или что такое SPA, я рассказывать не буду. Такой информации хватает в интернете. Эта статья рассчитана на более-менее опытных разработчиков, поэтому некоторые детали я упущу.

Кому не терпится, в конце статьи ссылка на мой репозиторий на гитхабе.

Основными технологиями были выбраны Laravel и Vue.js + Vuex так как это мой основной стек.

Для быстрой разработки взял UI Kit — ElementUI.

Главная цель

Создать основание для среднего и большого проекта которое:

  • поможет избежать жёсткой сцепленности модулей
  • будет понятное для программиста c небольшим опытом
  • поможет избежать дублирования кода
  • будет легко расширяться
  • уменьшит время старта проекта
  • уменьшит время поддержки проекта и навигации по коду
  • заложит основу для написания качественного кода

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

Дальше каждый слой следует разделить сначала по функциональности, а потом уже каждый функциональный модуль — соответственно выбранному паттерну.

Вдохновляясь философией DDD, решил и фронт-енд и бэк-енд разделить на смысловые модули. Но это не те классические домены, что описывает Эванс. Его модель тоже не идеальна. В любом приложении со временем всегда появляются связи между компонентами — те же отношения между моделями.

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

На фронте создал каталог resources/js/modules, в котором и будут находиться разные модули. В каждом будет api — методы для работы с бэк-ендом, components — все компоненты и страницы, store — хранилище, и routes.

{moduleName}/ │ ├── routes.js │ ├── api/ │   └── index.js │ ├── components/ │   ├── {ModuleName}List.vue │   ├── {ModuleName}View.vue │   └── {ModuleName}Form.vue │ └── store/     ├── store.js     ├── types.js     └── actions.js 

В resources/js создана папка core, где помещены основные компоненты системы.
Также есть папки bootstrap и includes для настройки дополнительных библиотек и утилит соответственно.

В проекте используется динамическая погрузка моделей. А именно в core/routes и в core/states мы подгружаем соответствующие файлы роутов и хранилищ автоматом (ничего прописывать не надо).

Вот пример как были подгружены store.js с разных модулей автоматически.

// Load store modules dynamically. const requireContext = require.context('../../modules', true, /store\.js$/)    let modules = requireContext.keys()      .map(file =>          [file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)]      )     .reduce((modules, [path, module]) => {          let name = path.split('/')[0]          return { ...modules, [name]: module.store }      }, {})   modules = {...modules, core}    export default new Vuex.Store({     modules })  

На бэк-енде в каталоге app будут аналогичные модули. Каждый модуль будет содержать папки Controllers, Requests, Resources. Файл с роутами тоже вынесен сюда — routes_api.php.

{ModuleName}/ │ ├── routes_api.php │ ├── Controllers/ │   └──{ModuleName}Controller.php │ ├── Requests/ │   └──{ModuleName}Request.php │ └── Resources/     └── {ModuleName}Resource.php  

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

Все манипуляции с динамической загрузкой модулей сделаны для того, чтобы между ними било минимальное зацепление. Это позволяет без последствий добавлять и удалять модули. Теперь можно сделать artisan make команду для создания такого модуля. С ее помощью мы сможем быстро наполнить проект нужными сущностями вместе с CRUD функциональностью.

Выполнив команду php artisan make:module {ModuleName}, у нас появятся все нужные файлы включая модель и миграции для работы полноценного CRUD. Вам останется только выполнить миграции php artisan migrate и все будет работать. Скорее всего вам понадобиться добавить дополнительные поля, поэтому перед миграцией не забудьте добавить их в модель, миграцию, а также, вывести во vue.

В данном шаблоне для аутентификации использовалась технология JWT-Auth, но возможно она избыточная и стоит переделать на Laravel Sanctum. В свою очередь На фронт-енде используется vue-auth, она позволяет легко управлять авторизацией пользователей и ролями.

В дальнейшем хотелось бы улучшить систему. Добавить глобальную шину событий, подключить websockets. Добавить тесты. Возможно в отдельных ветках сделать вариант с управлением ролями или создать ветки с другими UI Kit. Было бы хорошо, услышать рекомендации, замечания.

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

Весь код можно посмотреть в моем репозиторие на гитхабе.

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


Комментарии

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

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