Установка и первый сервер
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 expressnpm скачает 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) лишние инструменты не скачиваются, образ приложения получается меньше и безопаснее. Привыкай сразу классифицировать каждую новую зависимость — потом это экономит и место, и нервы при деплое.