Что такое Node.js

Node.js - JavaScript на сервере

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

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

Технически Node.js - обёртка над движком V8 (тем самым, что работает в браузере Chrome), дополненная встроенными модулями для работы с файловой системой, сетью и операционной системой.

Александр
Идём дальше!
История

Как появился Node.js

Node.js создал Райан Даль (Ryan Dahl) в 2009 году. Он хотел решить проблему медленных серверов: традиционные серверы (например Apache) создавали новый поток операционной системы для каждого запроса. При тысячах одновременных пользователей это потребляло огромное количество памяти.

Даль предложил другой подход - однопоточная обработка с асинхронным вводом-выводом. Вместо ожидания ответа от базы данных или файловой системы сервер обрабатывает следующий запрос, а когда данные готовы - возвращается к первому через механизм событий.

Первый публичный анонс состоялся на конференции JSConf в мае 2009 года. Реакция сообщества оказалась восторженной - идея оказалась революционной.

Движок V8

Что такое V8

V8 - это движок JavaScript, разработанный Google для браузера Chrome. Он компилирует JavaScript-код напрямую в машинный код процессора, минуя промежуточные шаги. Это делает выполнение JS значительно быстрее, чем у интерпретаторов, которые разбирают код построчно во время выполнения.

Node.js встраивает V8 в своё ядро и добавляет поверх него слой API для работы с операционной системой. Код, написанный для Node.js, компилируется тем же движком, что в браузере.

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

Мария
То есть Chrome и Node.js используют один и тот же движок?
Цикл событий

Event Loop - сердце Node.js

Обычные серверы при ожидании ответа от базы данных «замирают» - поток заблокирован. Node.js устроен иначе: он регистрирует задачу и тут же переходит к следующей. Когда результат готов, специальный механизм - цикл событий (event loop) - возвращает управление нужной функции.

Цикл событий постоянно проверяет очередь: есть ли завершённые операции ввода-вывода, истёкшие таймеры, входящие сетевые подключения. Если есть - выполняет соответствующие callback-функции.

Это и есть «неблокирующий ввод-вывод»: пока диск читает файл или база данных выполняет запрос, Node.js продолжает принимать и обрабатывать другие запросы.

Цикл событий

Синхронный и асинхронный код

Синхронный код выполняется последовательно: каждая строка ждёт завершения предыдущей. Асинхронный код запускает операцию и не ждёт её завершения - управление сразу передаётся дальше, а результат придёт в callback или через Promise.

В Node.js почти все операции ввода-вывода асинхронны по умолчанию. Функция для чтения файла не возвращает содержимое сразу - она принимает callback, который будет вызван, когда файл прочитан.

Это требует привыкания, особенно если вы пришли из Python или PHP, где большинство операций синхронные. Зато один Node.js-процесс легко обрабатывает десятки тысяч одновременных соединений.

npm

npm - менеджер пакетов

npm (Node Package Manager) - официальный менеджер пакетов для Node.js. Он поставляется вместе с Node.js и позволяет устанавливать библиотеки одной командой. Реестр npm содержит более двух миллионов пакетов - от крошечных утилит до полноценных фреймворков.

Команда npm install имя-пакета скачивает пакет и сохраняет его в папку node_modules. Зависимости фиксируются в файле package.json, который хранится в корне проекта.

Файл package.json описывает проект: название, версию, список зависимостей, команды запуска. Это аналог requirements.txt в Python, но более функциональный.

Дмитрий
Два миллиона пакетов? Это же больше, чем у PyPI!
Первая программа

Hello, Node.js!

Создать и запустить первую программу на Node.js очень просто. Создайте файл hello.js и напишите:

console.log('Привет, Node.js!'); console.log('Сумма 2 + 3 =', 2 + 3);

Запустите в терминале командой node hello.js. Node.js выполнит файл и выведет результат прямо в консоль. Никакого браузера, никакого сервера - просто скрипт, который работает как обычная программа.

Функция console.log() знакома всем, кто работал с JavaScript в браузере. В Node.js она работает точно так же, но выводит текст в терминал, а не в инструменты разработчика.

Модули

Система модулей CommonJS

Node.js использует систему модулей CommonJS: каждый файл является отдельным модулем. Чтобы использовать функции из другого файла или встроенного модуля, применяют require().

// Подключить встроенный модуль const path = require('path'); // Подключить свой файл const utils = require('./utils.js'); // Экспортировать из модуля module.exports = { myFunction };

Встроенные модули Node.js (fs, http, path, os и другие) подключаются по имени без указания пути. Сторонние пакеты из npm также подключаются по имени после установки.

Модули

Встроенные модули

Node.js поставляется с богатым набором встроенных модулей. Самые востребованные:

  • fs - работа с файловой системой (чтение, запись, удаление файлов);
  • http / https - создание HTTP-серверов и выполнение запросов;
  • path - работа с путями к файлам (объединение, извлечение расширения);
  • os - информация об операционной системе (тип ОС, память, процессор);
  • events - базовый класс EventEmitter для создания событийных объектов.

Использовать их просто: const fs = require('fs'); - и модуль готов к работе. Сторонние пакеты устанавливаются через npm и подключаются точно так же.

Александр
А как подключить модуль для работы с датами?
Файловая система

Чтение и запись файлов

Модуль fs предоставляет функции для работы с файлами. Есть два варианта каждой операции - синхронный и асинхронный. Рекомендуется асинхронный, чтобы не блокировать цикл событий.

const fs = require('fs'); // Асинхронное чтение fs.readFile('data.txt', 'utf8', function(err, content) { if (err) { console.error(err); return; } console.log(content); }); // Асинхронная запись fs.writeFile('out.txt', 'Hello!', function(err) { if (err) console.error(err); });

Первый аргумент callback - всегда ошибка (или null, если всё хорошо). Это стандартный паттерн в Node.js - «ошибка первой».

HTTP-сервер

Создаём простой сервер

Встроенный модуль http позволяет создать HTTP-сервер буквально за несколько строк. Это основа любого веб-приложения на Node.js.

const http = require('http'); const server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end('Привет от Node.js!'); }); server.listen(3000, function() { console.log('Сервер запущен: http://localhost:3000'); });

После запуска командой node server.js откройте http://localhost:3000 в браузере - и увидите ответ. Функция-обработчик получает объекты запроса (req) и ответа (res).

HTTP-сервер

Объекты запроса и ответа

Объект req (IncomingMessage) содержит данные о входящем запросе: метод (req.method - GET, POST и т.д.), URL (req.url), заголовки (req.headers), тело запроса (через события).

Объект res (ServerResponse) управляет ответом: res.writeHead(код, заголовки) задаёт статус и заголовки, res.write(данные) добавляет данные, res.end() завершает ответ. Пока res.end() не вызван, соединение остаётся открытым.

На основе req.url можно реализовать простой роутинг: разные URL возвращают разный контент. Именно так работают фреймворки вроде Express - они строят удобный слой поверх стандартного http.

Мария
Это сложнее, чем в Flask. Там декоратор и готово.
Промисы и async/await

Промисы - современный способ работы с асинхронностью

Callback-функции работают, но при вложенности порождают так называемый «ад коллбэков» - код становится трудночитаемым. Промисы (Promises) - объекты, представляющие результат асинхронной операции, которая ещё не завершилась.

// Промис fetch('https://api.example.com/data') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err));

Промис находится в одном из трёх состояний: pending (ожидание), fulfilled (выполнен успешно), rejected (завершён с ошибкой). Метод .then() подписывается на успешный результат, .catch() - на ошибку.

async/await

async/await - читаемый асинхронный код

Синтаксис async/await, появившийся в ES2017, делает работу с промисами визуально похожей на синхронный код. Функция помечается ключевым словом async, внутри неё можно использовать await перед промисом.

const fs = require('fs').promises; async function readConfig() { try { const data = await fs.readFile('config.json', 'utf8'); return JSON.parse(data); } catch (err) { console.error('Ошибка чтения:', err.message); } }

await приостанавливает выполнение функции до получения результата промиса, но не блокирует цикл событий. Остальной код Node.js продолжает работать.

Дмитрий
Вот это уже читается почти как синхронный Python!
Express.js

Express - популярный фреймворк

Express - минималистичный фреймворк для Node.js, самый популярный в экосистеме. Он упрощает роутинг, обработку запросов и подключение промежуточных обработчиков (middleware). Устанавливается через npm install express.

const express = require('express'); const app = express(); app.get('/', function(req, res) { res.send('Главная страница'); }); app.get('/about', function(req, res) { res.json({ page: 'about', version: 1 }); }); app.listen(3000, () => console.log('Работает!'));

Декларативный роутинг Express гораздо нагляднее, чем ручная проверка req.url. На сегодня этот урок построен именно на Express.

package.json

Структура проекта и package.json

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

{ "name": "my-server", "version": "1.0.0", "scripts": { "start": "node server.js", "dev": "nodemon server.js" }, "dependencies": { "express": "^4.18.2" } }

Поле scripts позволяет запускать команды через npm start или npm run dev. Папку node_modules никогда не включают в git - достаточно package.json, и любой разработчик восстановит зависимости командой npm install.

Где применяется Node.js

Области применения

Node.js особенно хорошо подходит для задач с большим числом одновременных соединений и потоковой обработкой данных:

  • REST API и GraphQL-серверы - быстрые, легко масштабируемые;
  • Real-time приложения - чаты, онлайн-игры, совместное редактирование (через WebSocket);
  • Инструменты сборки - webpack, Vite, eslint написаны на Node.js;
  • Серверный рендеринг - Next.js, Nuxt.js используют Node.js для рендеринга страниц;
  • Микросервисы - небольшие сервисы, которые легко деплоить и масштабировать.

Крупные компании - Netflix, LinkedIn, PayPal - перешли на Node.js и сообщили о значительном росте производительности и снижении затрат на инфраструктуру.

Александр
Это же и означает, что наш урок работает на Node.js!
Сравнение с Python

Node.js и Python: главные отличия

Python и Node.js часто используются для схожих задач - API, автоматизация, скрипты. Понимание разницы помогает выбрать подходящий инструмент.

  • Синтаксис: Python использует отступы, Node.js (JavaScript) - фигурные скобки. Python многие считают более читаемым для новичков.
  • Асинхронность: в Node.js она встроена на уровне платформы; в Python появилась позже (asyncio) и не так органична.
  • Экосистема: у обоих огромная. npm-реестр крупнее, но PyPI сильнее в data science и ML.
  • Типизация: JavaScript поддерживает TypeScript; Python имеет встроенные type hints.

Для веб-серверов и real-time - Node.js; для машинного обучения и анализа данных - Python. На практике оба языка часто живут рядом в одном проекте.

Установка и запуск

Как установить и запустить Node.js

Скачайте Node.js с официального сайта nodejs.org. Рекомендуется версия LTS (Long-Term Support) - она стабильна и поддерживается несколько лет. После установки в терминале будут доступны команды node и npm.

Проверьте установку:

node --version # выведет, например, v20.11.0 npm --version # выведет, например, 10.2.4

Для разработки удобно установить nodemon (npm install -g nodemon) - он перезапускает сервер при сохранении файлов, не нужно каждый раз останавливать процесс вручную. Это как «горячая перезагрузка» для серверного кода.

Итоги теории

Что мы узнали

Давайте закрепим основное: Node.js - это среда выполнения JavaScript на базе движка V8. Ключевые особенности: однопоточная модель, неблокирующий ввод-вывод и цикл событий. Это делает Node.js эффективным для обработки большого числа одновременных соединений.

Встроенные модули (http, fs, path) и огромная экосистема npm позволяют быстро строить серверы, читать файлы и работать с сетью. Для удобного роутинга используют Express.js.

Асинхронность - главная концепция Node.js. Callback-функции, промисы и async/await - три поколения синтаксиса для работы с асинхронными операциями. Современный Node.js рекомендует async/await.

Мария
Хорошо. Я наконец-то понимаю, почему у Express такой синтаксис!
Сравнение языков

Node.js: преимущества и недостатки

По сравнению с Python и PHP у Node.js есть свои сильные стороны и ограничения.

В чём Node.js лучше: один язык (JavaScript) на фронтенде и бэкенде - не нужно переключаться между синтаксисами, код и типы данных можно переиспользовать. Неблокирующий ввод-вывод и event loop дают высокую пропускную способность при большом числе одновременных соединений - для real-time приложений, чатов и API Node.js часто выигрывает у Python и PHP. Огромный реестр npm и быстрый цикл разработки. Отличная основа для современных инструментов сборки (webpack, Vite) и серверного рендеринга (Next.js).

Недостатки: однопоточность - тяжёлые CPU-bound задачи блокируют цикл событий; для вычислений и машинного обучения Python предпочтительнее. Без дисциплины код легко превращается в «ад коллбэков», хотя async/await это смягчает. Нет встроенной модели «страница = файл», как в PHP - роутинг и структура приложения остаются на разработчике. Для классических сайтов с серверным рендерингом шаблонов PHP и фреймворки вроде Laravel могут быть проще в освоении.

Задание 1

Расставь шаги создания HTTP-сервера

Перетащи шаги в правильном порядке (сверху вниз):

Перетаскивай карточки внутри зоны.

Задание 2

Вопросы по теории Node.js

1. Что такое event loop в Node.js?

2. Какой командой запустить файл app.js?

3. Для чего используют require()?

Задание 3

Сопоставь модуль с его назначением

Для каждого модуля выбери правильное описание:

fs
http
path
os
Задание 4

Проверь понимание async/await и npm

1. Что делает ключевое слово await?

2. Что хранится в папке node_modules?

3. Какой метод завершает HTTP-ответ в Node.js?

Финальный тест

Допуск к практике

Ответь на 8 вопросов. Для допуска нужно не менее 80% (6 из 8).

1. Что такое Node.js?

2. Какой принцип лежит в основе эффективности Node.js?

3. Как называется файл описания проекта Node.js?

4. Какую команду используют для установки пакета?

5. Что такое V8?

6. Какой встроенный модуль создаёт HTTP-сервер?

7. Что делает module.exports?

8. Какой синтаксис рекомендован для работы с асинхронным кодом в современном Node.js?

Практика

Задание: простой HTTP-сервер на Node.js

Что нужно сделать:

Критерии проверки (100 баллов):

Минимум для зачёта: 60 баллов.

Загрузи файл server.js