Информационный портал по безопасности » Программирование » Основа для большого модульного SPA на Laravel + Vue + ElementUI с CRUD генератором

 

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

Автор: admin от 5-06-2020, 10:37, посмотрело: 651

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



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



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

Используя накопленный опыт, задался целью собрать все лучшие решения, на мой взгляд, и создать свою основу для 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. Было бы хорошо, услышать рекомендации, замечания.



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



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

Источник: Хабр / Интересные публикации

Категория: Программирование

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

Добавление комментария

Имя:*
E-Mail:
Комментарий:
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent