Архитектура проекта

Архитектура

система договорённостей внутри команды о том, как организован код: где лежат файлы, как они называются, как взаимодействуют между собой

Плюсы архитектуры

  • онбординг
  • масштабируемость
  • поддержка

Признаки плохой архитектуры

  • Файлы по 1000+ строк
  • Перемешанные файлы
  • Название не соответствуют шаблону

Паттерн

проверенный способ решить типичную задачу

выбор между ними зависит от размера проекта и команды

Flat Structure

Плоская архитектура

все файлы лежат в одной папке

Подходят для:

  • лендинг на одну страницу
  • учебное задание
project/
├── index.html
├── style.css
└── script.js
                        

File Structure

Разделение по типу файлов

файлы лежат по папкам согласно их расширению: всё .css в папку css/ , всё .js в папку js/ , все изображения в images/

project/
├── index.html
├── about.html
├── css/
│   ├── style.css
│   └── responsive.css
├── js/
│   ├── main.js
│   └── slider.js
└── images/
    ├── hero.jpg
    └── logo.png
                        

Компонентный подход

Файлы группируются по функциональности

project/
├── index.html
├── components/
│   ├── header/
│   │   ├── header.html
│   │   ├── header.css
│   │   └── header.js
│   ├── card/
│   │   ├── card.html
│   │   └── card.css
│   └── footer/
│       ├── footer.html
│       └── footer.css
├── pages/
│   ├── about.html
│   └── catalog.html
└── assets/
    └── images/

FSD

Feature Sliced Design

По разделам

файлы лежат по бизнес-функции или разделу сайта

project/
├── app/                ← инициализация, глобальные стили
├── pages/              ← страницы целиком
│   ├── home/
│   └── catalog/
├── features/           ← бизнес-функции
│   ├── search/
│   └── cart/
├── entities/           ← бизнес-сущности (товар, пользователь)
│   ├── product/
│   └── user/
└── shared/             ← переиспользуемое (кнопки, утилиты)
    ├── ui/
    └── utils/
                        

Методология CSS

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

БЭМ

Блок, Элемент, Модификатор

Разработан компанией Яндекс в середине 2000-х

Блок

независимый компонент интерфейса, который может существовать сам по себе

  • .card
  • .main-nav
  • .search-form

Элемент

составная часть блока, которая не имеет смысла вне его

  • .card__title
  • .card__image
  • .main-nav__item

Модификатор

вариация блока или элемента, изменяющая его внешний вид или поведение

  • .card--featured
  • .main-nav__item--active
  • .button--large

Главное правило БЭМ -

плоские классы без вложенности


Так делать нельзя

.card .title { }
                        


                        

SMACSS

Масштабируемая модульная архитектура CSS

способ организации CSS по категориям

Base

базовые стили, применяемые к HTML-тегам напрямую:

body , a , h1-h6

Layout

крупные структурные блоки страницы. принято называть с префикса l-

l-header , l-sidebar , l-main

Module

переиспользуемые компоненты интерфейса

карточки , кнопки , формы

State

состояния элементов. Начинаются с префикса is-

is-active , is-hidden , is-loading

Theme

переменные и правила, связанные с темной/светлой темой


:root {
  --color-primary: #3b82f6;
  --color-bg: #ffffff;
  --color-text: #1f2937;
}
                                    
project/
├── index.html
├── css/
│   ├── base.css        ← сброс стилей, html, body, типографика
│   ├── layout.css      ← шапка, подвал, сетка, колонки
│   ├── modules.css     ← карточки, кнопки, формы, слайдер
│   ├── state.css       ← is-active, is-hidden, is-loading
│   └── theme.css       ← цвета, шрифты (светлая / тёмная тема)
├── js/
│   └── main.js
└── assets/
    └── images/
                        

CSS переменные

именованные значения, которые задаются один раз и используются в любом месте таблицы стилей

Объявление

Внутри селектора :root указываются переменные начинаясь с двух префиксом


:root {
  --color-primary: #3b82f6;
}
                        

Применение

Используется внутри свойства через функцию var()


.button {
  background-color: var(--color-primary);
}
                        

Пример


:root {
  /* Цвета */
  --color-primary:      #3b82f6;
  --color-primary-dark: #2563eb;
  --color-text:         #1f2937;
  --color-text-muted:   #6b7280;
  --color-bg:           #ffffff;
  --color-border:       #e5e7eb;

  /* Типографика */
  --font-base:  'Inter', sans-serif;
  --text-sm:    0.875rem;   /* 14px */
  --text-base:  1rem;       /* 16px */
  --text-lg:    1.125rem;   /* 18px */
  --text-xl:    1.25rem;    /* 20px */

  /* Отступы */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 40px;

  /* Прочее */
  --radius-sm:    4px;
  --radius-md:    8px;
  --shadow-card:  0 2px 8px rgba(0, 0, 0, 0.08);
}
                        

Темы без JS

:root может выступать палитрой, которая будет зависеть от темы устройства


:root {
  --color-bg:   #ffffff;
  --color-text: #1f2937;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-bg:   #111827;
    --color-text: #f9fafb;
  }
}
                        

Utility-first CSS

используется набор маленьких классов, каждый из которых делает ровно одно действие


<div class="google-blue text-gray-100 hover:text-white shadow font-bold text-sm py-3 px-4 rounded flex justify-start items-center cursor-pointer w-64">
    <span class="pl-3">Sign up with Google</span>
</div>
                    

Структура папок

project/
│
├── pages/                  ← HTML-страницы (кроме главной)
│   ├── about.html
│   ├── catalog.html
│   └── contacts.html
│
├── components/             ← переиспользуемые части интерфейса
│   ├── header/
│   │   ├── header.css
│   │   └── header.js
│   ├── footer/
│   │   └── footer.css
│   ├── card/
│   │   └── card.css
│   └── modal/
│       ├── modal.css
│       └── modal.js
│
├── assets/                 ← статические файлы (не код)
│   ├── images/
│   ├── fonts/
│   └── icons/
│
├── css/                    ← глобальные стили
│   ├── reset.css
│   ├── variables.css
│   └── global.css
│
├── js/
│   ├── main.js
│   └── utils.js
│
└── index.html
                        

assets/

всё, что не является кодом: изображения, шрифты, иконки, видео, PDF-документы

Можно создавать подпапки

assets/images/

изображения контента (фотографии товаров, аватары авторов)

components/

переиспользуемые блоки интерфейса, которые встречаются на нескольких страницах

pages/

сами HTML-файлы страниц, либо стили и скрипты, специфичные для конкретной страницы

Пути

адрес, по которому браузер ищет ресурс

Относительный путь

отсчитывается от местоположения текущего файла

Абсолютный путь

отсчитывается от корня сайта и начинается с /





                        

Правило ../

Обозначает инструкцию подняться на одну папку вверх. Можно использовать несколько раз


../           — на один уровень вверх
../../        — на два уровня вверх
../images/    — вверх, затем в папку images/
                        

Работа с многостраничными сайтами

У HTML нет встроенного механизма включения одного файла в другой

Варианты решения проблемы:

  • Повторение кода
  • Генерирование с помощью JS
  • Использование фреймворков

Git

.gitignore

сообщает Git, какие файлы и папки следует игнорировать

Чаще всего игнорируются

  • node_modules/ - папка с зависимостями npm
  • .env — файлы с переменными окружения, API-ключами, паролями

Readme

README.md

документация, визитная карточка и инструкция по эксплуатации

  • Можно писать в формате Markdown ( .md )
  • Внутри можно применять некоторые теги HTML

Code style

набор соглашений о том, как выглядит код: отступы, пробелы, кавычки, порядок свойств, именование переменных


function GetDATA(user_id,UserName){
	let resultData = []
    var temp_value=0;

	if(user_id>0){
      for(let i=0;i<10;i++){
	  	resultData.push({ID:i, user_name:UserName, val:temp_value+i})
        }
	}else{
    for ( let J = 0; J < 5;J++ ){
			resultData.push({id:J,UserName:UserName,value: J*2})
		}
	}

	return resultData
}

const my_array = [1,2,3,4]

for(let index=0;index<my_array.length; index++){
	console.log(my_array[index])
}

let AnotherVar = 5
let another_var=10
let ANOTHERvar = 15

function doStuff(){
  console.log("doing stuff")
	 console.log("more stuff")
    console.log("even more stuff")
}
                        

Гайдлайны для читаемого кода

Отступы

2 или 4 пробела во всем проекте

Длина строки

не длиннее 80–100 символов

Пустые строки

разделяйте логические блоки кода пустой строкой

Именование

В CSS должна быть структура по типу BEM, а в JS camelCase

camelCase

Первое слово строчное, каждое следующее начинается с заглавной буквы


my variable  →  myVariable
get user name  →  getUserName
card background color  →  cardBackgroundColor
                        
При пересечении названия класса и переменной

.buy-button  {} →  const buyButton =
                        

Инструменты

Форматтер

инструмент, который автоматически приводит код к единому визуальному стилю

Prettier

самый популярный форматтер для веб-разработки

В VSCode запускается кнопками ALT + Shift + F

До


const user={name:'Иван',age:25,city:'Москва'}
function greet(user){return 'Привет, '+user.name+'! Тебе '+user.age+' лет'}
                                

После


const user = { name: 'Иван', age: 25, city: 'Москва' };
function greet(user) {
  return 'Привет, ' + user.name + '! Тебе ' + user.age + ' лет';
}
                                

Линтер

инструмент статического анализа кода

ESLint

линтер для JavaScript


// .eslintrc.json — правила проверки JS
{
  "rules": {
    "no-var": "error",           // запрет var — это ошибка
    "no-unused-vars": "warn",    // неиспользуемая переменная — предупреждение
    "prefer-const": "warn",      // предлагает заменить let на const
    "no-console": "warn"         // предупреждает о забытых console.log
  }
}
                                

Stylelint

линтер для JavaScript


// .stylelintrc.json — правила проверки CSS
{
  "rules": {
    "no-duplicate-properties": true,   // запрет дублирующихся свойств
    "color-no-invalid-hex": true,      // запрет неверных hex-цветов
    "property-no-unknown": true        // запрет несуществующих свойств
  }
}