Архитектура
- Нужны определённые правила и ограничения для организации кода, которые позволяют не запутаться в уже написанном коде
- Поддерживать на протяжении длительного времени, внедряя туда новые фичи
- Разработка продуктов ведётся в командах, и важно, чтобы специалисты легко понимали чужой код, что требует дополнительных соглашений внутри команды.
- разработчики подобных крупных проектов, не пишут код хаотично в «лоб». Вместо этого они изначально договариваются об определённых принципах, ограничениях и правилах организации кода, и уже потом приступают к разработке.
- Подобные правила и ограничения принято называть архитектурой проекта. Это похоже на строительство зданий. Перед тем как класть кирпичи, всегда составляют проект, и лишь потом переходят к строительству. Иначе невозможно создать надёжное и функциональное здание. То же само е справедливо и для сайтов. Поэтому правильная архитектура обычно является важным или даже ключевым фактором в разработке крупного сайта.
Архитектура — это набор принципов и ограничений, применяемых для упорядочения и организации кода приложения. Она определяет структуру и отношения между компонентами приложения, помогает разделить код на маленькие и маневренные части, что упрощает его отладку, тестирование и модификацию. Архитектура также может определять правила и стандарты для организации кода и сотрудничества в команде разработки, что помогает сохранять целостность и согласованность проекта.
Таким образом, архитектура позволяет улучшить качества кода. Основные цели принципов, применяемых в архитектуре, состоят в том, чтобы сделать код:
- Поддерживаемым — легко добавлять новые возможности в уже разработанный сайт и развивать существующие.
- Понятным — код понятен участникам команды и новым разработчикам, знакомым с архитектурой.
- Переиспользуемым — уже готовые в проекте решения могут быть переиспользованы для р ешения новых задач.
- Лёгким в отладке — можно относительно легко и быстро находить ошибки в коде и править их.
Грамотная архитектура отвечает следующим принципам:
- Модульность. Современные сайты огромны. Разрабатывать их как единое целое, держа в голове весь функционал, попросту невозможно. Поэтому их обычно делят на составные части — модули. Каждый из них можно разрабатывать по отдельности, абстрагируясь от остального функционала ресурса, сосредотачиваясь на возможностях самого модуля. Каждый модуль в определённой степени независим и отвечает за свою функциональность. Модульность характерна не только для разработки ПО, но и в целом для сложных инженерных задач. Например, инженеры не строят с ходу сам автомобиль, вместо этого сложный предмет обычно разбивают на более простые модули: кузов, двигатель, колёсная база и так далее. И уже из этих хорошо продуманных и протестированных модулей, словно из конструктора, собирают автомобиль.
- Правила управления данными. Одна из ключевых задач Frontend-разработчика — это преобразование данных в интерфейс пользователя. Поэтому важно иметь правила, позволяющие просто и понятно работать с данными, легко находить ошибки, связанные с потерей данных или другими особенностями.
- Простота. Современные приложения достаточно сложны. Но грамотная архитектура за счёт принципов, повторяющихся решений, ограничений делает код таких приложений более простым для понимания.
- Расширяемость (масштабируемость). Продуктовое приложение — это не статичный код, зависший во времени, это живой организм. В код постоянно требуется вносить изменения, добавляя новые фичи и улучшая уже имеющийся функционал. Поэтому приложение должно быть легко расширяемым, чтобы добавлять новые возможности и модули в будущем без значительных изменений в существующем коде.
Config files
.env
.eslintignore
.eslintrc.json
.gitignore
.prettierignore
.prettierrc
next.config.js
package.json
README.md
tsconfig.json
Директории
.vscode/
api/
components/
icons/
layout/
pages/
page1/
page2/
...
pageN/
ui/
constants/
mock/
pages/
page1/
page2/
...
pageN/
public/
fonts/
images/
favicon.ico
styles/
types/
utils/
build/ (или dist/)
Папка static/
В static складывается весь статичный контент, который не требует постобработки бандлером, а только копируется в корневой уровень build. В основном это:
- иконки разного размера для браузеров,
- картинки, которые не импортируются в модулях и не требуют обработки,
- шрифты,
- HTML-файлы,
- файлы для поисковых роботов.
Папка build/
Бандлер обрабатывает файлы из srс/ и помещает их в папку build/, затем копирует файлы из static/ в корневой уровень build/.
Файлы стилей рекомендуется импортировать из JavaScript, всё остальное стоит складывать в static. В библиотеках такая папка чаще всего называется dist (сокращённо от distributable — «подлежащий распределению»).
Папка src/
Есть несколько популярных принципов хранения файлов. Одни из них основаны на группировке файлов по «фичам», другие на группировке по типам файлов, а некоторые даже имеют спецификацию. Один из таких принципов — атомарный дизайн. Не стоит много времени уделять выбору системы, можно менять её по мере роста проекта.
В NextJS можно не использовать директорию src/ вообще, исходники монут лежать сразу в корневой директории.
Дерево проекта может выглядеть так:
src/
├── components/
│ └── button/
│ ├── button.*css
│ ├── button.js
│ ├── button.tmpl.js
│ └── index.js
├── layout/
│ └── main/
│ ├── main.*css
│ ├── main.js
│ ├── main.tmpl.js
│ └── index.js
├── modules/
│ └── chats/
│ ├── utils
│ │ └── getFullname.js
│ │ └── getIsOnline.js
│ ├── components/
│ │ └── message/
│ │ ├── message.*css
│ │ ├── message.js
│ │ ├── message.tmpl.js
│ │ └── index.js
│ ├── chats.*css
│ ├── chats.js
│ ├── chats.tmpl.js
│ └── index.js
├── pages/
│ ├── home/
│ │ ├── modules/
│ │ │ ├── login/
│ │ │ │ ├── login.*css
│ │ │ │ ├── login.js
│ │ │ │ ├── login.tmpl.js
│ │ │ │ └── index.js
│ │ │ └── logout/
│ │ │ ├── logout.*css
│ │ │ ├── logout.js
│ │ │ ├── logout.tmpl.js
│ │ │ └── index.js
│ │ ├── home.*css
│ │ ├── home.js
│ │ ├── home.tmpl.js
│ │ └── index.js
│ └── about/
│ ├── about.*css
│ ├── about.js
│ ├── about.tmpl.js
│ └── index.js
└── utils/
├── get.js
├── http.js
├── isEmpty.js
└── templator.js
Папка components/
Компоненты, которые будут использованы в двух и более модулях стоит держать в папке components/. Эти компоненты не должны зависеть от внешнего состояния или иметь сторонние эффекты. Если компонент будет использован только в одном модуле, стоит поместить его в локальную папку ./components для индикации явной зависимости. Такой подход позволяет не засорять общую папку components и упрощает переход к дизайн-системе, если в ней возникла необходимость. Если провести аналогию с системой атомарного хранения, то компоненты — это атомы и молекулы, так как часто в компонентах будут и группы компонентов (например, field, который может содержать в себе input и label).
Папка pages/
Если в проекте есть роутинг, то удобно держать страницы в папке pages/. Обычно страницы отображают контент, собранный из импортированных модулей и компонентов. В рамках аналогии с атомарным дизайном это страницы.
Папка utils/
Многие приложения имеют утилитарные функции, которые могут использоваться как в одном, так и в нескольких местах. Чтобы определить подходящее место в проекте для утилитарной функции, стоит ответить на два вопроса:
- Функция может использоваться в одном файле или в его зависимых файлах? Тогда её лучше определить в локальной папке. Если таких функций несколько, можно поместить их в папку utils около файла.
- Функция может использоваться в нескольких модулях или компонентах внутри общих папок? Тогда её лучше поместить в общую папку utils.
Опционально
api/- файлы, связанные с APIconsts/- константы_design/- файлы макетами дизайнаmock/- мок-данныеpublic/- статичные файлы (шрифты, изображения, иконки, svg, docs и т.д.)stores/- файлы для state-managmentstypes/- стилиtypes/- файлы типов для TypeScript
В больших проектах часто не хватает основной структуры, поэтому для удобства иног да используют дополнительные папки для семантического разделения по функциональности.
В некоторых проектах можно встретить папку src/modules. В ней собираются модули (иногда их называют контейнерами), которые являются связующим звеном между состоянием приложения и компонентами для его отображения. Иногда они содержат функционал, бизнес-логику, которая используется в нескольких местах приложения. Если модуль используется только на одной странице, лучше помещать его в локальную папку страницы, чтобы не засорять общую папку модулей. В атомарном дизайне модули можно считать организмами.
Страницы могут иметь несколько видов отображения (например, с хедером или без). Эти макеты можно держать в папке src/layout. Макеты содержат общие для определённого вида страниц стили и внутри себя отображают контент из pages. В системе атомарного дизайна это темплейты. Часто встречаются в проектах, использующих Gatsby.