Архитектура
- Нужны определённые правила и ограничения для организации кода, которые позволяют не запутаться в уже написанном коде
- Поддерживать на протяжении длительного времени, внедряя туда новые фичи
- Разработка продуктов ведётся в командах, и важно, чтобы специалисты легко понимали чужой код, что требует дополнительных соглашений внутри команды.
- разработчики подобных крупных проектов, не пишут код хаотично в «лоб». Вместо этого они изначально договариваются об определённых принципах, ограничениях и правилах организации кода, и уже потом приступают к разработке.
- Подобные правила и ограничения принято называть архитектурой проекта. Это похоже на строительство зданий. Перед тем как класть кирпичи, всегда составляют проект, и лишь потом переходят к строительству. Иначе невозможно создать надёжное и функциональное здание. То же самое справедливо и для сайтов. Поэтому правильная архитектура обычно является важным или даже ключевым фактором в разработке крупного сайта.
Архитектура — это набор принципов и ограничений, применяемых для упорядочения и организации кода приложения. Она определяет структуру и отношения между компонентами приложения, помогает разделить код на маленькие и маневренные части, что упрощает его отладку, тестирование и модификацию. Архитектура также может определять правила и стандарты для организации кода и сотрудничества в команде разработки, что помогает сохранять целостность и согласованность проекта.
Таким образом, архитектура позволяет улучшить качества кода. Основные цели принципов, применяемых в архитектуре, состоят в том, чтобы сделать код:
- Поддерживаемым — легко добавлять новые возможности в уже разработанный сайт и развивать существующие.
- Понятным — код понятен участникам команды и новым разработчикам, знакомым с архитектурой.
- Переиспользуемым — уже готовые в проекте решения могут быть переиспользованы для решения новых задач.
- Лёгким в отладке — можно относительно легко и быстро находить ошибки в коде и править их.
Грамотная архитектура отвечает следующим принципам:
- Модульность. Современные сайты огромны. Разрабатывать их как единое целое, держа в голове весь функционал, попросту невозможно. Поэтому их обычно делят на составные части — модули. Каждый из них можно разрабатывать по отдельности, абстрагируясь от остального функционала ресурса, сосредотачиваясь на возможностях самого модуля. Каждый модуль в определённой степени независим и отвечает за свою функциональность. Модульность характерна не только для разработки ПО, но и в целом для сложных инженерных задач. Например, инженеры не строят с ходу сам автомобиль, вместо этого сложный предмет обычно разбивают на более простые модули: кузов, двигатель, колёсная база и так далее. И уже из этих хорошо продуманных и протестированных модулей, словно из конструктора, собирают автомобиль.
- Правила управления данными. Одна из ключевых задач 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.
Общие рекомендации
Старайтесь максимально декомпозировать компоненты. Если есть стили — выносите в отдельный файл рядом с самим компонентом. Незачем хранить все CSS-файлы в отдельной папке — так только сложнее найти описание стиля.
index.js
каждого блока и компонента позволяют экспортировать только нужное. Например, вот так:
export { default } from './button';
export { template as buttonTemplate } from './button.tmpl';
...
У компонента должна быть единая точка входа. В index.js
можно делать все необходимые экспорты, но в рамках текущей папки и вложенных в неё (если такие есть).
Старайтесь не мусорить в файлах компонентов и блоков. Например, для констант создайте файл const.js
и перенесите их туда. Если же константа используется между разными компонентами, модулями или блоками — сделайте её общей.
Readme
Даже законченный проект остаётся только заготовкой, пока им не начнут пользоваться. Но сначала пользователь должен понять, зачем ему пользоваться вашим кодом. В этом помогает файл README.
README — первое, что прочитает пользователь, когда попадёт в репозиторий на «Гитхабе». Хороший REAMDE отвечает на четыре вопроса:
- Готов ли проект к использованию?
- В чём его польза?
- Как установить?
- Как применять?
Бейджи
Быстро понять статус проекта помогают бейджи на «Гитхабе». Иногда разработчики ограничиваются парой бейджев, которые сообщат о статусе тестов кода:
Если пользователь увидит ошибку в работе тестов, то поймёт: использовать текущую версию в важном проекте — не лучшая идея.
Бейджи помогают похвастаться достижениями: насколько популярен проект, как много разработчиков создавало этот код. Через бейджи можно даже пригласить пользователя в чат:
В README Webpack строка бейджев подробно рассказывает о покрытии кода тестами. Когда проект протестирован, это вызывает доверие пользователя. Последний бейдж приглашает присоединиться к разработке.
Другая строка убедит пользователя в стабильности инфраструктуры и популярности проекта. Последний бейдж зовёт в чат проекта.
Описание
Краткое опишите, какую задачу решает проект. Пользователь не верит обещаниям и не готов читать «полотна» текста. Поэтому в описании достаточно нескольких строк:
Авторы React дробят описание на абзацы и списки — так проще пробежаться глазами по тексту и найти ключевую информацию.
Если у проекта есть сайт, добавьте ссылку в заголовок.
Установка, скрипты
Лучше всего пользователя убеждает собственный опыт. Чем быстрее он начнёт пользоваться проектом, тем раньше почувствует пользу. Для этого помогите ему установить приложение: напишите краткую пошаговую инструкцию.
Если проект предназначен для разработчиков, добавьте информацию об установке тестовых версий. Например:
npm install
— установка стабильной версии,npm start
— запуск версии для разработчика,npm run build:prod
— сборка стабильной версии.
Примеры использования
Хорошо, если сразу после установки пользователь сможет решить свои задачи без изучения проекта. Это особенно верно, если ваш пользователь — не профессиональный разработчик. Но даже профессионал поймёт вас лучше, если показать примеры использования:
Для более подробных инструкции добавьте новые разделы или ссылки:
- на документацию,
- вики проекта,
- описание API.
В учебном проекте будут полезен раздел с описанием стиля кода и правилами разработки: как работать с ветками, пул-реквестами и релизами.
Команда
Если вы работаете в команде, укажите основных участников: им будет приятно, а новые разработчики охотнее присоединятся к проекту. «Гитхаб» — не просто инструмент, это социальная сеть разработчиков.
Примеры README
- «Реакт»,
- «Эхо»,
- «Вебпак»,
- «ТДенгине»,
- «Соул-хантинг».