Перейти к основному содержимому

Первая программа на Node.js

Разработчику Архитектору

Play ITЗагрузка интерактивного демо…


Первая программа на Node.js

В браузере JavaScript ограничен правилами безопасности: нельзя слушать произвольный порт или читать файлы на диске без разрешения. Node.js запускает тот же язык как обычную программу на компьютере или сервере — с доступом к сети, файловой системе и процессам.

Практикум идёт по шагам — консоль и npm, встроенный http, затем Express и учебное REST API "Заметки".

ШагТемаЗачем
1node -v, терминалУбедиться, что среда готова
2Файл .js и node app.jsПервая программа вне браузера (схемы запуска)
3REPLБыстрые эксперименты в консоли
4process.argv, readlineCLI-утилиты и ввод пользователя
5package.json, npm runМанифест проекта и скрипты
6http.createServerHTTP без фреймворка
7Express REST APIМаршруты, JSON, middleware
МатериалЗачем
Node.js — серверный JavaScriptEvent loop, модули CJS/ESM
npminstall, scripts, lock, audit
Структура проектаsrc/, env, конвенции
fs и httpВстроенные модули без Express
Точка входа — require.mainПрямой node file.js vs import
Express — middlewareRouter, CORS, ошибки
Справочник по NodeСправочник API Node
FullstackCORS, прокси, два порта

Навигация по блоку Node.js

Редактор и терминал

Команды удобно выполнять во вкладке Терминал VS Code (Ctrl+`). Отладка и работа с IDE — статья "Отладка".


Шаг 1 — проверка установки

Скачайте LTS с nodejs.org и проверьте версии:

node -v
npm -v

Команда node -v показывает версию runtime (для новых проектов берите LTS 20 или 22). npm -v — менеджер пакетов из той же установки. Если терминал пишет, что node не найден, проверьте PATH — см. статью про Node.js.

Создайте рабочую папку, например notes-api, и откройте её в редакторе — дальше все команды выполняются из неё.


Шаг 2 — программа из файла

Файл hello.js (кодировка UTF-8):

console.log('Привет, мир!');

Запуск:

node hello.js

Разбор:

  • node передаёт файл интерпретатору V8; браузер здесь не участвует.
  • Расширение .js в команде можно опустить: node hello тоже сработает.
  • console.log пишет в stdout — стандартный поток вывода консоли.
Кодировка на Windows

Сохраняйте исходники в UTF-8. Node.js сам преобразует текст при выводе в консоль; кириллица в console.log обычно отображается корректно.


Шаг 3 — интерактивный режим (REPL)

Команда node без аргументов открывает REPL — read-eval-print loop:

node
> 10 + 12 * 2
34
> console.log('test')
test
undefined
> .exit

Разбор:

  • Каждое выражение выполняется сразу после Enter — удобно для калькулятора и проверки синтаксиса.
  • console.log возвращает undefined, поэтому REPL печатает его на отдельной строке.
  • Последний результат доступен в переменной _ (одно подчёркивание).
  • Выход: .exit, Ctrl+D или дважды Ctrl+C.

REPL подходит для коротких экспериментов; полноценные программы храните в файлах.


Шаг 4 — аргументы командной строки и ввод с клавиатуры

process.argv

При запуске node script.js arg1 arg2 массив process.argv содержит путь к node, путь к скрипту и переданные аргументы:

// argv-demo.js
console.log(process.argv);
node argv-demo.js --help version

Первые два элемента — служебные; пользовательские аргументы начинаются с индекса 2. Значение с пробелами передавайте в кавычках: node app.js "hello world".

readline — диалог в консоли

Для интерактивного ввода после старта программы:

// ask.js

import readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';

const rl = readline.createInterface({ input, output });
const name = await rl.question('Как вас зовут? ');
console.log(`Здравствуйте, ${name}!`);
await rl.close();

Разбор:

  • readline/promises даёт await rl.question() вместо колбэков.
  • stdin / stdout связывают интерфейс с консолью.
  • rl.close() освобождает ресурсы; без этого процесс может не завершиться.

Более сложные CLI-примеры — в простых приложениях на JavaScript.

Завершение процесса

process.exitCode = 1; // код ошибки для ОС (0 — успех)
// или немедленно:
process.exit(1);

Перед process.exit() дождитесь вывода в консоль: буфер stdout может не успеть сброситься.


Шаг 5 — package.json и npm-скрипты

Превратите каталог в npm-пакет:

npm init -y

Флаг -y создаёт package.json с значениями по умолчанию. Основные поля:

ПолеСмысл
nameИмя пакета
versionSemVer (1.0.0)
mainТочка входа (index.js)
scriptsКоманды для npm run
dependenciesПакеты для runtime
devDependenciesИнструменты разработки

Добавьте ESM и скрипт запуска:

{
"name": "notes-api",
"type": "module",
"scripts": {
"hello": "node hello.js"
}
}
npm run hello

Разбор:

  • "type": "module" включает import / export (Node.js 18+).
  • npm run <имя> ищет команду в scripts и добавляет в PATH каталог node_modules/.bin.
  • npm install <пакет> записывает зависимость в package.json; npm install без аргументов восстанавливает всё из манифеста.

Шаг 6 — HTTP-сервер на встроенном http

Express строится поверх модуля http. Полезно один раз собрать сервер без фреймворка — так видно, что Express добавляет поверх createServer.

Файл server-raw.js:

Код ITЗагрузка примера кода…

node server-raw.js
curl http://127.0.0.1:3000/health

Разбор:

  • http.createServer принимает callback (req, res) на каждый запрос.
  • req.method и req.url — метод HTTP и путь без хоста.
  • res.writeHead задаёт статус и заголовки; res.end отправляет тело и закрывает ответ.
  • Маршрутизацию, разбор JSON и middleware приходится писать вручную — Express берёт это на себя.

Подробный разбор http, потоков и req/res — во встроенных модулях Node.js.


Шаг 7 — REST API на Express

Логичный шаг после синтаксиса JS и async/await — поднять HTTP-сервер, который отвечает JSON. Express даёт маршруты, middleware и удобные req / res поверх http.

Мы соберём REST API "Заметки" — тот же учебный сценарий, что в Gin и Ktor. Данные пока в памяти: после перезапуска список пустой.

Что такое REST в двух словах

REST — стиль API, где ресурсы имеют URL, а действие задаёт HTTP-метод:

МетодОбычный смыслВ нашем API
GETПрочитатьСписок или одна заметка
POSTСоздатьНовая заметка в теле JSON
DELETEУдалитьЗаметка по id в пути

Что получится

МетодПутьДействие
GET/healthСервер жив
GET/notesСписок заметок
POST/notesТело &#123; "text": "..." &#125; — создать
DELETE/notes/:idУдалить по id

Инициализация проекта

npm install express
npm install -D nodemon

Обновите package.json:

{
"name": "notes-api",
"type": "module",
"scripts": {
"dev": "nodemon server.js",
"start": "node server.js"
}
}
Поле / пакетСмысл
expressМаршруты и middleware
nodemonПерезапуск при сохранении файла
npm run devРазработка с watch
npm startОбычный запуск

Минимальный сервер Express

Файл server.js — точка входа.

  1. express() — объект приложения.
  2. app.use(express.json()) — разбор JSON-тела в req.body.
  3. Маршруты — обработчики, которые срабатывают, когда совпали URL и HTTP-метод.
  4. app.listen(PORT) — слушать порт (по умолчанию 3000).

Код ITЗагрузка примера кода…

Запуск: npm run dev. Остановка — Ctrl+C. Подробнее про dev-сервер и браузер — Запуск и перезапуск приложений.


Разбор фрагментов

КодСмысл
_reqПараметр не используем, сигнатура нужна
req.body?.textOptional chaining
?? ''Замена null/undefined на пустую строку
return res.status(400)...Прерывание обработчика
201Created — ресурс создан
req.params.idЧасть URL /notes/:id
204Успех без тела (DELETE)
process.env.PORTПорт из окружения (хостинг)

Проверка через curl

curl http://127.0.0.1:3000/health
curl http://127.0.0.1:3000/notes
curl -X POST http://127.0.0.1:3000/notes \
-H "Content-Type: application/json" \
-d "{\"text\": \"Изучить Node\"}"
curl http://127.0.0.1:3000/notes
curl -X DELETE http://127.0.0.1:3000/notes/1

Connection refused — сервер не запущен. Пустой req.body — нет express.json() или заголовка Content-Type: application/json.


Middleware — цепочка до маршрута

Middleware — функция (req, res, next). Express вызывает их по порядку регистрации.

MiddlewareЗадача
express.json()Разобрать JSON-тело
Логированиеmethod, url, время
corsБраузерный фронт с другого порта — Express — middleware, маршруты и ошибки

Пример логирования:

app.use((req, res, next) => {
const started = Date.now();
res.on('finish', () => {
console.log(req.method, req.url, res.statusCode, `${Date.now() - started}ms`);
});
next();
});

Подробнее: Express 263.


Router — вынести маршруты

routes/notes.js:

Код ITЗагрузка примера кода…

В server.js: app.use('/notes', createNotesRouter(store));router.get('/') + префикс /notes = GET /notes.


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

СимптомПричинаЧто сделать
node не найденNode не в PATHПереустановить или добавить путь — Node.js - серверный JavaScript
Cannot find module 'express'Нет npm installnpm install в каталоге проекта
req.body undefinedНет express.json()Middleware выше маршрутов; curl с -H Content-Type
DELETE не находит idНеверный шаблон пути/notes/:id, читать req.params.id
Изменения не видныЗапущен node, не nodemonnpm run dev
CORS в браузереФронт :5173, API :3000Express — middleware, маршруты и ошибки или Fullstack на JavaScript — API и фронтенд

Что попробовать дальше

  1. Центральный errorHandlerExpress — middleware, маршруты и ошибки.
  2. SQLite / Prisma — заметки переживут перезапуск.
  3. React + fetch272, Fullstack на JavaScript — API и фронтенд, Fetch / axios — типовые запросы, галерея компонентов (блок список с API).
  4. Тесты supertest — Тестирование JavaScript — Vitest и Testing Library.

Как превратить учебный API в рабочий сервис

План эволюции

  1. In-memory store для отладки маршрутов.
  2. Подключение БД и миграций.
  3. Единый формат ошибок и валидация входных данных.
  4. Тесты на ключевые сценарии.
  5. Логи, метрики и контролируемое завершение процесса.

Базовые контракты API

ЭндпоинтУспехОшибка клиентаОшибка сервера
GET /notes200 + массив400 при неверных параметрах500
POST /notes201 + объект400 при пустом text500
DELETE /notes/:id204404, если id не найден500

Связанные материалы

ТемаМатериал
Express углублённоExpress — middleware, маршруты и ошибки
FullstackFullstack на JavaScript — API и фронтенд
TypeScript на сервереTypeScript
Теория NodeNode.js - серверный JavaScript
Production

Для боевого сервера — process manager (PM2, systemd), секреты в переменных окружения, HTTPS за reverse proxy (Nginx, Caddy).

Пример proxy_pass и заголовков — Nginx — конфиги под задачу.

Данные в памяти теряются при перезапуске — нужна БД и бэкапы.

Основа по протоколу

Базовый разбор HTTP и HTTPS — HTTP как основа веб-интеграций.


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — Первая программа на TypeScript, Первая программа на Kotlin, Первая программа на C++, Первая программа на Ruby, Первая программа на C#, Первая программа на Rust.