К содержанию
Первый Коммит

Модуль 1

Введение в Express.js

  • Что такое Express
  • Основы Node.js
  • Установка
  • Первый сервер
  • Структура проекта
  • nodemon

Это развилка основного курса NodeJS. В курсе NodeJS фреймворк Express появляется лишь в обзорном модуле 5 («Express.js — основы»). Этот курс — углублённый альтернативный путь: вместо одного модуля M5 изучается полный 12-модульный трек по Express, а недостающие темы при необходимости берутся из курса NodeJS.

Что нужно знать заранее: материал модулей 1–4 курса NodeJS — основы JavaScript и Node.js, модули и npm, асинхронность (Promises, async/await), файловая система и встроенный http-модуль. Модуль 4 курса NodeJS заканчивается вопросом «Зачем нужен Express?» — здесь мы на него и отвечаем, надстраивая Express над «голым» HTTP, уже знакомым по курсу NodeJS.

Сверх обзорного M5 курс охватывает: глубокую работу с middleware, серверный рендеринг (шаблоны EJS), архитектуру REST (Routes → Controllers → Models), паттерны обработки ошибок, загрузку файлов, безопасность и деплой — вплоть до итогового проекта (REST API блога). Темы, которых здесь нет (SQL/Prisma, WebSocket, тестирование, email, Redis), берутся из курса NodeJS — конкретные модули перечислены в модуле 12.

Одно отличие в стиле кода: основной курс NodeJS использует ES-модули (import/export), а здесь — CommonJS (require), так как он по-прежнему широко распространён в Express-проектах. Принципы идентичны; как перейти на import/export, показано в разделе 1.5.

#1.1 Что такое Express.js

Express.js — минималистичный и гибкий веб-фреймворк для Node.js. Он предоставляет набор инструментов для создания веб-приложений и API. Express не навязывает архитектуру — организация кода остаётся за разработчиком. Это самый популярный фреймворк для Node.js: большинство бэкенд-проектов на Node построены на нём.

Зачем нужен Express, если есть встроенный http-модуль Node.js:

  • Удобная маршрутизация — вместо ручного разбора URL
  • Middleware — цепочка обработчиков запроса
  • Встроенная обработка JSON, форм, статических файлов
  • Огромная экосистема плагинов (npm)
  • Простой и понятный API

Express используется для REST API, серверного рендеринга (SSR), микросервисов, прокси-серверов, приложений реального времени (с Socket.IO).

#1.2 Предварительные требования

Предполагается, что модули 1–4 курса NodeJS пройдены: основы JavaScript и Node.js, модули (require/import) и npm, асинхронность (callbacks, Promises, async/await), файловая система и встроенный http-модуль (методы GET/POST/PUT/DELETE, заголовки, статус-коды, тело запроса). При пробелах в этих темах повторите указанные модули перед началом курса.

Убедитесь, что Node.js установлен:

Терминал
# Проверка версии
node -v    # рекомендуется v24 (LTS)
npm -v     # менеджер пакетов

#1.3 Создание проекта

Каждый Node.js-проект начинается с инициализации package.json — файла, описывающего проект, его зависимости и скрипты. Команда npm init создаёт его интерактивно, а с флагом -y все значения принимаются по умолчанию.

Терминал
# Создание папки проекта
mkdir my-express-app
cd my-express-app

# Инициализация package.json
npm init -y

# Установка Express
npm install express@5.2.1

После установки появятся папка node_modules/ (зависимости) и файл package-lock.json (точные версии). Папку node_modules не коммитят в Git — она восстанавливается через npm install.

Код
# .gitignore
node_modules/
.env
*.log

.env — файл для переменных окружения (секретов и настроек, например строки подключения к базе данных); его заранее вносят в .gitignore, чтобы эти значения не попали в Git. Назначение файла и способы задания переменных подробно разбираются в модуле 3 — в этом модуле сам файл ещё не понадобится.

Практическая деталь для Windows: файл .gitignore (как и будущий .env) начинается с точки, а в Проводнике такое имя задать неудобно — создавайте эти файлы в редакторе кода (например, VS Code) или командой в терминале.

#1.4 Первый сервер

Создадим минимальный Express-сервер. Функция express() создаёт приложение (app). Метод app.get() регистрирует обработчик GET-запроса на указанный путь. Метод app.listen() запускает сервер на указанном порту.

JavaScript
// index.js
const express = require('express');
const app = express();
const PORT = 3000;

// Обработчик GET-запроса на корневой путь
app.get('/', (req, res) => {
    res.send('Hello, Express!');
});

// Запуск сервера
app.listen(PORT, () => {
    console.log(`Сервер запущен: http://localhost:${PORT}`);
});

Сохраните файл и запустите сервер командой в терминале (строки, начинающиеся с #, — это комментарии, набирать их не нужно):

Код
# Запуск
node index.js

# Откройте http://localhost:3000 в браузере

Разберём код:

  • require('express') — импортируем Express
  • express() — создаём экземпляр приложения
  • app.get('/', callback) — при GET-запросе на / вызвать callback
  • req — объект запроса (от клиента)
  • res — объект ответа (от сервера)
  • res.send() — отправить ответ клиенту
  • app.listen(PORT) — слушать указанный порт

#1.5 ES Modules (import/export)

Node.js поддерживает два формата модулей: CommonJS (require) и ES Modules (import). Чтобы перейти на import/export, укажите в package.json "type": "module": npm 11 при npm init -y уже записал туда "type": "commonjs" — замените значение, а второе поле type не добавляйте. В курсе используется CommonJS (require), так как он более распространён в Express-экосистеме, но показаны оба варианта.

JavaScript
// CommonJS (по умолчанию)
const express = require('express');
module.exports = router;

// ES Modules (в package.json — "type": "module")
import express from 'express';
export default router;

Объект router в примере — это маршрутизатор (express.Router()), который подробно рассматривается в модуле 2. Здесь важен только синтаксис экспорта: CommonJS отдаёт значение через module.exports, ES Modules — через export default, а в другом файле оно подключается соответственно через require или import.

#1.6 nodemon — автоперезапуск

При разработке неудобно вручную перезапускать сервер после каждого изменения. nodemon отслеживает файлы и автоматически перезапускает Node.js-процесс. Устанавливается как dev-зависимость (не нужен в production).

Терминал
# Установка
npm install --save-dev nodemon@3.1.14

# Запуск
npx nodemon index.js

Здесь npx — утилита из комплекта npm (устанавливается вместе с ним): она запускает исполняемый файл пакета из локального node_modules без глобальной установки, поэтому npx nodemon находит только что установленный пакет.

Добавьте скрипты в package.json для удобства:

Код
// package.json
{
    "scripts": {
        "start": "node index.js",
        "dev": "nodemon index.js"
    }
}

Теперь сервер запускается короткими командами:

Терминал
npm run dev     # разработка (с nodemon)
npm start       # production

#1.7 Структура проекта

Для небольших проектов достаточно одного файла. Но по мере роста приложения код нужно разделять. Типичная структура Express-проекта:

Код
my-express-app/
├── node_modules/
├── src/
│   ├── routes/          # маршруты
│   │   ├── users.js
│   │   └── posts.js
│   ├── controllers/     # логика обработки
│   │   ├── userController.js
│   │   └── postController.js
│   ├── models/          # модели данных
│   │   ├── User.js
│   │   └── Post.js
│   ├── middleware/       # middleware
│   │   ├── auth.js
│   │   └── errorHandler.js
│   ├── config/          # конфигурация
│   │   └── db.js
│   └── app.js           # настройка Express
├── public/              # статические файлы
├── .env                 # переменные окружения
├── .gitignore
├── package.json
└── index.js             # точка входа

Эта структура выстраивается постепенно на протяжении курса.

#1.8 Отправка разных типов ответов

Express поддерживает отправку данных разных типов. res.send() выбирает Content-Type по типу аргумента: строку отправляет как text/html (поэтому и /text, и /html из примера ниже придут как HTML), объект — как JSON. res.json() явно отправляет JSON (самый частый формат для API). res.status() устанавливает HTTP-код ответа.

JavaScript
app.get('/text', (req, res) => {
    res.send('Простой текст');
});

app.get('/html', (req, res) => {
    res.send('<h1>HTML-ответ</h1><p>Параграф</p>');
});

app.get('/json', (req, res) => {
    res.json({ message: 'Hello', status: 'ok' });
});

app.get('/status', (req, res) => {
    res.status(201).json({ created: true });
});

// Цепочка методов
app.get('/error', (req, res) => {
    res.status(404).json({ error: 'Не найдено' });
});

#1.9 Практика

#Задание 1.1 — первый Express-сервер

  • Инициализируйте проект (npm init -y)
  • Установите express и nodemon
  • Создайте 5 маршрутов: /, /about, /api/status, /api/time, /api/random
  • / — HTML-приветствие
  • /about — JSON с информацией о проекте
  • /api/status — { status: "ok", uptime: process.uptime() }
  • /api/time — текущее время
  • /api/random — случайное число от 1 до 100
  • Настройте npm run dev с nodemon

#Итоги модуля 1

  • Курс — развилка основного курса NodeJS: вместо обзорного модуля 5 изучается полный трек по Express на CommonJS; нужна база модулей 1–4 NodeJS (JavaScript, npm, асинхронность, http-модуль).
  • Express.js — минималистичный веб-фреймворк над встроенным http-модулем: вместо ручного разбора запросов — удобная маршрутизация, middleware, обработка JSON, форм и статики плюс экосистема npm.
  • npm init -y создаёт package.json — описание проекта с зависимостями и скриптами; npm install express ставит фреймворк; node_modules и .env вносят в .gitignore и не коммитят.
  • express() создаёт приложение, app.get(путь, обработчик) регистрирует маршрут GET-запроса, app.listen(порт) запускает сервер.
  • Обработчик маршрута получает req (объект запроса от клиента) и res (объект ответа сервера); res.send отправляет ответ клиенту.
  • Форматы модулей: CommonJS (require, module.exports) — стандарт этого курса; ES Modules (import/export) включаются полем type: module в package.json.
  • nodemon перезапускает сервер при каждом изменении файлов — ставится как dev-зависимость (npm install --save-dev nodemon) и в production не нужен.
  • Скрипты package.json разделяют режимы запуска: npm run dev — разработка с nodemon, npm start — production-запуск node index.js.
  • Типовая структура Express-проекта: routes, controllers, models, middleware, config плюс public и точка входа index.js — по мере роста приложения код разделяют по назначению.
  • res.send сам выбирает Content-Type по типу аргумента (строка — text/html, объект — JSON), res.json явно отправляет JSON (основной формат API), res.status задаёт HTTP-код и встраивается в цепочку: res.status(404).json(...).

#Домашнее задание

Создайте с нуля отдельный проект — мини-API сервиса прогноза погоды — и выполните задания по порядку.

  • Инициализируйте проект weather-service: npm init -y, установите express и nodemon, настройте скрипты start и dev в package.json.
  • Реализуйте маршрут /, возвращающий HTML-страницу с названием сервиса и списком доступных маршрутов.
  • Добавьте маршруты /api/cities (JSON-массив из 5 городов) и /api/weather (объект с городом, температурой и описанием погоды — значения задайте в коде).
  • Добавьте /api/forecast, возвращающий массив из 7 объектов-дней со случайной температурой от -10 до +30 и датой.
  • Создайте .gitignore с node_modules и .env и проверьте оба режима запуска: npm start и npm run dev (с автоперезапуском при правке кода).
  • (со звёздочкой) Вынесите список городов в файл data/cities.js, экспортируйте его через module.exports, подключите в index.js через require и добавьте маршрут /api/cities/random, возвращающий случайный город.

Войдите, чтобы отмечать пройденные модули и видеть прогресс по курсу.

Введите запрос: название модуля, тема или раздел.

Стрелки — выбор, Enter — открыть. Ищет по названиям модулей, темам и разделам.