Структура Vue 3 проекта
Какие бывают структуры файлов для Vue 3 проектов?
Плоская структура
При запуске небольшого проекта Vue, такого как Proof of Concept, вы можете предпочесть простую структуру папок, чтобы избежать сложностей:
/src
|-- /components
| |-- BaseButton.vue
| |-- BaseCard.vue
| |-- PokemonList.vue
| |-- PokemonCard.vue
|-- /composables
| |-- usePokemon.js
|-- /utils
| |-- validators.js
|-- /layout
| |-- DefaultLayout.vue
| |-- AdminLayout.vue
|-- /plugins
| |-- translate.js
|-- /views
| |-- Home.vue
| |-- PokemonDetail.vue
|-- /router
| |-- index.js
|-- /store
| |-- index.js
|-- /assets
| |-- /images
| |-- /styles
|-- /tests
| |-- ...
|-- App.vue
|-- main.js
Атомарный дизайн
Для больших приложений Vue может оказаться полезным использование методологии Atomic Design. Этот подход организует компоненты в иерархию от самого простого к самому сложному:
- Атомы: Базовые элементы (например, кнопки, иконки).
- Молекулы: Группы атомов (например, строки поиска).
- Организмы: Сложные компоненты (например, панели навигации)
- Шаблоны: Макеты, отображающие структуру компонентов
- Страницы: Реальные экраны пользовательского интерфейса с реальными данными.
Этот метод обеспечивает масштабируемость и поддерживаемость, облегчая плавный переход от простых к сложным компонентам.
/src
|-- /components
| |-- /atoms
| | |-- AtomButton.vue
| | |-- AtomIcon.vue
| |-- /molecules
| | |-- MoleculeSearchInput.vue
| | |-- MoleculePokemonThumbnail.vue
| |-- /organisms
| | |-- OrganismPokemonCard.vue
| | |-- OrganismHeader.vue
| |-- /templates
| | |-- TemplatePokemonList.vue
| | |-- TemplatePokemonDetail.vue
|-- /pages
| |-- PageHome.vue
| |-- PagePokemonDetail.vue
|-- /composables
| |-- usePokemon.js
|-- /utils
| |-- validators.js
|-- /layout
| |-- LayoutDefault.vue
| |-- LayoutAdmin.vue
|-- /plugins
| |-- translate.js
|-- /router
| |-- index.js
|-- /store
| |-- index.js
|-- /assets
| |-- /images
| |-- /styles
|-- /tests
| |-- ...
|-- App.vue
|-- main.js
Модульный дизайн
Модульная архитектура инкапсулирует каждую функцию или предметную область, повышая поддерживаемость и готовя к потенциальной эволюции в сторону микрофронтендов:
/src
|-- /core
| |-- /components
| | |-- BaseButton.vue
| | |-- BaseIcon.vue
| |-- /models
| |-- /store
| |-- /services
| |-- /views
| | |-- DefaultLayout.vue
| | |-- AdminLayout.vue
| |-- /utils
| | |-- validators.js
|-- /modules
| |-- /pokemon
| | |-- /components
| | | |-- PokemonThumbnail.vue
| | | |-- PokemonCard.vue
| | | |-- PokemonListTemplate.vue
| | | |-- PokemonDetailTemplate.vue
| | |-- /models
| | |-- /store
| | | |-- pokemonStore.js
| | |-- /services
| | |-- /views
| | | |-- PokemonDetailPage.vue
| | |-- /tests
| | | |-- pokemonTests.spec.js
| |-- /search
| | |-- /components
| | | |-- SearchInput.vue
| | |-- /models
| | |-- /store
| | | |-- searchStore.js
| | |-- /services
| | |-- /views
| | |-- /tests
| | | |-- searchTests.spec.js
|-- /assets
| |-- /images
| |-- /styles
|-- /scss
|-- App.vue
|-- main.ts
|-- router.ts
|-- store.ts
|-- /tests
| |-- ...
|-- /plugins
| |-- translate.js
Feature Sliced Design
Feature-Sliced Design - это способ организации больших и долгосрочных проектов, чтобы ими было легче управлять и развивать. При таком подходе приложение разбивается на различные слои, каждый из которых играет определенную роль:
- App: Приложение: Глобальные настройки, стили и провайдеры.
- Pages: Создание полноценных страниц с использованием сущностей, функций и виджетов.
- Widgets: Объединяют сущности и функции в целостные блоки пользовательского интерфейса, например IssueList или UserProfile.
- Features: Обрабатывают пользовательские взаимодействия, которые представляют ценность, такие как отправка комментариев, добавление в корзину или поиск пользователей.
- Entities: Представляют основные бизнес-модели, такие как пользователь, продукт и заказ.
- Shared: Предоставляет многократно используемые утилиты и компоненты, не связанные с конкретной бизнес-логикой, такие как UIKit, библиотеки и API.
/src
|-- /app
| |-- App.vue
| |-- main.js
| |-- app.scss
|-- /processes
|-- /pages
| |-- Home.vue
| |-- PokemonDetailPage.vue
|-- /widgets
| |-- UserProfile.vue
| |-- PokemonStatsWidget.vue
|-- /features
| |-- pokemon
| | |-- CatchPokemon.vue
| | |-- PokemonList.vue
| |-- user
| | |-- Login.vue
| | |-- Register.vue
|-- /entities
| |-- user
| | |-- userService.js
| | |-- userModel.js
| |-- pokemon
| | |-- pokemonService.js
| | |-- pokemonModel.js
|-- /shared
| |-- ui
| | |-- BaseButton.vue
| | |-- BaseInput.vue
| | |-- Loader.vue
| |-- lib
| | |-- api.js
| | |-- helpers.js
|-- /assets
| |-- /images
| |-- /styles
|-- /router
| |-- index.js
|-- /store
| |-- index.js
|-- /tests
| |-- featureTests.spec.js
Микрофронтенды
Микрофронтенды берут за основу идею микросервисов и применяют ее к фронтенд-части веб-приложений. Это означает, что разные команды могут работать над разными разделами веб-приложения, не мешая друг другу. Каждый раздел, или «микрофронтенд», работает сам по себе и может изменяться независимо. Вот базовый обзор SPA.
- Оболочка приложения: Это основной контроллер, который управляет базовой версткой и маршрутизацией сайта. Он соединяет все микрофронтенды вместе.
- Декомпозированные пользовательские интерфейсы: Каждый микрофронтенд фокусируется на определенной части приложения. Они могут быть разработаны с использованием разных технологий и обновляться отдельно.
Основное преимущество заключается в том, что микрофронтенды позволяют командам обновлять отдельные части приложения, не дожидаясь остальных, что ускоряет разработку. Однако такая настройка может сделать приложение более сложным в управлении и поддержании последовательности.
Полезные ресурсы:
- Micro Frontends - Extending Microservice Ideas to Frontend Development
- Martin Fowler on Microfrontends
Эта стратегия подходит для крупных, сложных проектов с несколькими командами разработчиков. Каждая команда может сосредоточиться на конкретных бизнес-требованиях, не влияя на работу других, и потенциально использовать технологии, которые лучше всего подходят для их части приложения.
Сравнительная таблица
Подход | Описание | Плюсы | Минусы |
---|---|---|---|
Плоский подход | Простая структура, идеально подходящая для небольших проектов или проверки концепции. | - Простота реализации - Минимальная настройка | - Не масштабируется - Беспорядок по мере роста проекта |
Атомный дизайн | Иерархическая структура, основанная на сложности компонентов. | - Масштабируемые - Организованные - Многоразовые компоненты | - Накладные расходы на управление слоями - Сложная настройка |
Модули | Модульная структура, инкапсулирующая функции. | - Масштабируемость - Инкапсулированные функции | - Возможное дублирование - Может стать сложным |
FSD | Организует проект по функциональным слоям и фрагментам. | - Высокая сплоченность - Четкое разделение функций | - Начальная сложность - Требует тщательного планирования |
Микрофронтенды | Каждая часть приложения развертывается отдельно. | - Независимые развертывания - Масштабируемость | - Высокая сложность - Необходима координация между командами |
(с) source
Подходящая структура для Vue 3 проекта
Самая удобная архитектура для Vue 3 приложения - Модульная
.
Изначально, приложение разбивается на логические модули, слабо связанные друг с другом. Например, для онлайн магазина это могут быть модуль каталога товаров, модуль отдельного товара, модуль личного кабинета / аккаунта пользователя.
Кроме того, есть модуль оболочки - то, что иногда называет app shell
. Шаблон с хедером, футером, боковым меню и главным окном. В этот модуль целесообразно поместить утилиты и ресурсы, используемые по всему приложению - например, api
, useI18n
, BaseButton
и stringHelpers
.
В каждом модуле свои components
, composables
, assets
, utils
; возможно, api
, routes
, views
, layouts
.
Внутри components
каждого модуля при необходимости можно устроить иерархию компонентов наподобие атомарного дизайна
Слабая связанность позволяет разрабатывать каждый модуль достаточно независимо, что значительно повышает вероятность успешности проекта.
Плоская структура
- вырожденная форма модульной с одним модулем. В то же время модульная структура органично перерастает при необходимости в Микрофронтенды
.
Атомарный дизайн
и FSD
изобретались не для Vue, а для фронтенда в целом, в следствие чего содержат избыточную сложность и неудобства.