Файловая структура проекта
Продуманная структура проекта — одно из ключевых условий качественной архитектуры. Начинающим разработчикам бывает непросто определить, куда размещать тот или иной файл и почему. Разберёмся в этом вопросе.
При создании проекта командой npm init vue@latest вы увидите примерно следующую структуру (конкретный набор зависит от выбранных настроек):
--public
----favicon.ico
--src
----components
------HelloWorld.vue
----App.vue
----main.ts
--.gitignore
--index.html
--package.json
--README.md
--vite.config.json
Это стандартная структура, однако для средних и крупных приложений она не подходит.
Сосредоточимся на директории src.
Структура src
Давайте организуем наш проект и директорию src следующим образом:
src
--assets
--common
--layouts
--middlewares
--modules
--plugins
--router
--services
--stores
--views
Assets
В этом каталоге хранятся все файлы ресурсов: шрифты, иконки, изображения, стили и прочие вспомогательные файлы.
Common
Директория предназначена для общих файлов. Её можно разделить на:
- внутренние директории — директивы, миксины, компоненты;
- отдельные файлы —
functions.js,helpers.js,constants.js,config.jsи другие.
Файл помещается сюда, если его содержимое (функции, константы, компоненты) используется в нескольких местах, что помогает избежать дублирования кода и нарушения принципа DRY. Например, внутри src/common/components можно хранить Button.vue — общий компонент, используемый во всём приложении. В helpers.js можно определить универсальную функцию для многократного использования.
Layouts
Здесь будут храниться лейауты приложения. Подробнее о лейаутах мы поговорим на протяжении курса.
Middlewares
Эта директория тесно связана с маршрутизатором (vue-router). В ней хранятся навигационные хуки. Вот краткий пример одного из них:
export default function checkAuth(isAuthenticated) {
if (!isAuthenticated) {
return { name: 'Login' };
} else {
return { name: 'Home' };
}
}
Пример использования:
import { createRouter, createWebHistory } from 'vue-router'
import checkAuth from '../middlewares/checkAuth.js'
const isAuthenticated = true
export const router = createRouter({
history: createWebHistory(),
routes: []
})
router.beforeEach((to, from) => {
checkAuth(!isAuthenticated && to.name !== 'Login')
});
Тему маршрутизатора (vue-router) и навигационных хуков (Navigation guards) мы раскроем в третьем разделе.
Modules
Это ядро приложения. Здесь располагаются все модули — логически обособленные части приложения. Для каждого модуля рекомендуется создавать:
- Директорию внутренних компонентов, в которой хранятся Vue-компоненты, относящиеся к данному модулю.
- Директорию
testsдля тестирования компонентов.
Вот пример модуля задач, содержащего все связанные с задачами компоненты: список задач, детали задачи и прочее:
src
--modules
----tasks
------__tests__
--------TasksList.spec.js
--------TaskDetails.spec.js
------components
--------TasksList.vue
--------TaskDetails.vue
------helpers.js
Plugins
В этой директории создаются и подключаются плагины. Пример подключения:
import myPlugin from './myPlugin.js'
import { createApp } from 'vue'
const app = createApp({})
app.use(myPlugin, {
/* настройки */
})
О плагинах подробнее мы поговорим в третьем разделе.
Services
Директория для хранения сервисов. Здесь можно разместить, например, службу подключения к API или менеджер localStorage.
Router
В этом каталоге хранятся все файлы, относящиеся к маршрутизатору (vue-router). Это может быть единственный файл index.js с маршрутизатором и маршрутами (в этом случае его, вероятно, стоит разместить в корне директории src). Для лучшей читаемости и разделения ответственности рекомендуем выделять маршрутизатор и маршруты в два отдельных файла: index.js и routes.js.
Store
Каталог глобального хранилища (Pinia), в котором хранятся все файлы, связанные с Pinia.
Views
Вторая по значимости директория. Здесь располагаются все точки входа для маршрутов. Например, если в приложении есть маршруты /home, /about, /orders, то в views должны быть файлы HomeComponent.vue, AboutComponent.vue и OrdersComponent.vue.
Может возникнуть вопрос: зачем разделять представления (Views) и модули (Modules), если можно хранить всё в одном месте? Мы видим в этом несколько преимуществ:
- Более чёткая организация файлов.
- Можно быстро определить, какие маршруты есть в приложении.
- Легко найти корневой файл маршрута и понять, где начинается логика модуля.