Установка и первый сервер

npm init, установка express, первый сервер на пять строк и автоперезагрузка через --watch.
«Любой проект на Node начинается с package.json — это паспорт приложения и список его зависимостей.»

Прежде чем писать маршруты, нужно собрать рабочее окружение: создать проект, поставить Express и научиться запускать сервер так, чтобы он перезапускался при каждом изменении кода. Это скучная, но фундаментальная часть: настроишь один раз — и дальше будешь думать только о логике.

В этом уроке мы пройдём путь от пустой папки до работающего сервера. Заодно разберём, что такое package.json, чем dependencies отличаются от devDependencies и как устроены npm-скрипты.

Создаём проект

Сначала инициализируем проект. Команда создаёт файл package.json, где будут жить метаданные и список зависимостей:

mkdir my-api && cd my-api
npm init -y

Флаг -y означает "согласиться со всем по умолчанию". Теперь поставим Express:

npm install express

npm скачает Express и его зависимости в папку node_modules и пропишет версию в package.json. Эту папку никогда не коммитят в git — её всегда можно восстановить командой npm install.

Первый сервер

Создай файл index.js и напиши минимальный сервер:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Сервер работает!');
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Слушаю http://localhost:${PORT}`);
});

Запусти его командой node index.js и открой в браузере адрес из консоли. Поздравляю — это твой первый бэкенд.

Автоперезагрузка

Каждый раз останавливать и запускать сервер вручную утомительно. В современном Node (18.11+) встроен флаг --watch, который сам перезапускает процесс при изменении файлов:

node --watch index.js

Раньше для этого ставили пакет nodemon — он до сих пор популярен и умеет чуть больше, но для старта хватает встроенного --watch. Удобно завернуть запуск в npm-скрипт:

{
  "scripts": {
    "dev": "node --watch index.js",
    "start": "node index.js"
  }
}

Теперь npm run dev поднимает сервер в режиме разработки.

Как работает под капотом

Когда ты пишешь require('express'), Node ищет пакет в node_modules, читает его package.json, находит точку входа и возвращает экспортированную функцию. Версии в твоём package.json записаны с символом ^ — это значит "можно ставить любые совместимые минорные обновления". Точные версии каждой зависимости фиксируются в package-lock.json, чтобы у всех в команде была одинаковая сборка.

package.json      -> что хочу поставить (^5.0.0)
package-lock.json -> что реально стоит (5.0.1, и все под-зависимости)
node_modules/     -> сами файлы пакетов

Частые ошибки

  • Коммитить node_modules. Эта папка огромна и легко восстанавливается. Добавь её в .gitignore.
  • Забыть про package-lock.json. Его, наоборот, коммитят — он гарантирует одинаковые версии у всех.
  • Хардкодить порт. Лучше читать его из переменной окружения (об этом — в разделе про деплой).

Best practices

  • Заводи скрипты dev и start сразу — это стандарт, который ждут все инструменты.
  • Используй --watch или nodemon только в разработке, в проде сервер запускают иначе.
  • Держи .gitignore с node_modules и .env с первого коммита.

Итоги

Ты собрал рабочее окружение: проект, зависимости, первый сервер и автоперезагрузку. Это база, на которую ляжет всё остальное. Дальше разберём, как именно Express обрабатывает входящий запрос и что такое цикл событий, благодаря которому Node тянет тысячи соединений одним потоком.

dependencies против devDependencies

В package.json зависимости делятся на две группы. В dependencies попадает то, без чего приложение не работает в продакшене: сам Express, драйвер базы, библиотека для JWT. В devDependencies — инструменты только для разработки: линтеры, тестовые фреймворки, сборщики. Флаг npm install пакет --save-dev кладёт зависимость во вторую группу. Это разделение не косметика: при продакшен-установке (npm install --omit=dev) лишние инструменты не скачиваются, образ приложения получается меньше и безопаснее. Привыкай сразу классифицировать каждую новую зависимость — потом это экономит и место, и нервы при деплое.

Проверьте себя
1. Зачем нужен файл package-lock.json?
AЧтобы хранить исходники Express
BЧтобы зафиксировать точные версии зависимостей для всей команды
CЧтобы ускорить запуск сервера
DЭто резервная копия package.json
2. Что делает флаг node --watch?
AЛогирует все запросы
BПерезапускает процесс при изменении файлов
CВключает режим продакшена
DСжимает ответы сервера