Что такое Node.js

Зачем нужно

Node.js — среда выполнения JavaScript вне браузера. Построена на движке V8 (Chrome) и библиотеке libuv для асинхронного ввода/вывода. Node.js позволяет писать серверы, CLI-утилиты, скрипты автоматизации и полноценные бэкенд-приложения на JavaScript.

Где используется

  • Веб-серверы и API (Express, Fastify, Nest.js)
  • Real-time приложения (чаты, игры — через WebSocket)
  • CLI-инструменты (Webpack, ESLint, Prettier)
  • Сборщики и таск-раннеры (npm scripts, Gulp)
  • Микросервисы, serverless-функции
  • Desktop-приложения (Electron: VS Code, Discord)

Архитектура Node.js

JavaScript-код (ваш код)
        ↓
    Node.js API (fs, http, path, ...)
        ↓
┌───────────────────────────────────┐
│           Node.js Core            │
│                                   │
│   V8 Engine          libuv        │
│   (компиляция JS     (event loop, │
│    в машинный код)    async I/O,  │
│                       thread pool)│
└───────────────────────────────────┘
        ↓
    Операционная система (файлы, сеть, процессы)

V8 Engine

// V8 компилирует JavaScript в машинный код (JIT-компиляция)
// Тот же движок, что в Google Chrome

// V8 НЕ включает: DOM, window, document, fetch
// V8 ВКЛЮЧАЕТ: ECMAScript (переменные, функции, классы, Promise, async/await)

Событийно-ориентированная модель

// Node.js — однопоточный, но неблокирующий
// Вместо создания потока на каждый запрос — Event Loop

// ❌ Блокирующий подход (PHP, Ruby без async):
// Запрос 1 → читать файл (ждём 100ms) → ответить → Запрос 2
// Пока файл читается — сервер простаивает

// ✅ Node.js — неблокирующий:
// Запрос 1 → начать чтение файла (callback) → Запрос 2 → Запрос 3
// Файл прочитан → выполнить callback → ответить на Запрос 1

Non-blocking I/O

const fs = require('fs');

// ❌ Блокирующий (синхронный)
const data = fs.readFileSync('big-file.txt', 'utf-8');
console.log(data); // Всё замерло пока файл читается
console.log('Это выполнится ПОСЛЕ чтения');

// ✅ Неблокирующий (асинхронный)
fs.readFile('big-file.txt', 'utf-8', (err, data) => {
  if (err) throw err;
  console.log(data); // Выполнится когда файл прочитан
});
console.log('Это выполнится СРАЗУ, не дожидаясь файла');

Hello World

// === HTTP-сервер ===
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
  res.end('Привет, Node.js!');
});

server.listen(3000, () => {
  console.log('Сервер запущен: http://localhost:3000');
});
node server.js
# Сервер запущен: http://localhost:3000

Глобальные объекты Node.js

// Вместо window (браузер) — global (Node.js)
// В модулях лучше использовать globalThis (универсально)

console.log(process.version);   // v20.11.0
console.log(process.platform);  // win32, linux, darwin
console.log(process.cwd);     // Текущая директория
console.log(process.env.PATH);  // Переменные окружения

console.log(__dirname);   // Директория текущего файла
console.log(__filename);  // Полный путь к текущему файлу

// Таймеры (как в браузере)
setTimeout(() => {}, 1000);
setInterval(() => {}, 1000);
setImmediate(() => {}); // Выполнить после текущего I/O цикла (Node-only)

// Buffer — работа с бинарными данными
const buf = Buffer.from('Привет');
console.log(buf); // <Buffer d0 9f d1 80 d0 b8 d0 b2 d0 b5 d1 82>

Модульная система

// === CommonJS (по умолчанию в Node.js) ===
// Экспорт
module.exports = { add, multiply };
// или
exports.add = function(a, b) { return a + b; };

// Импорт
const { add } = require('./math');
const fs = require('fs');

// === ES Modules (с package.json "type": "module") ===
// Экспорт
export function add(a, b) { return a + b; }
export default class Calculator { }

// Импорт
import { add } from './math.js';
import fs from 'fs';

LTS vs Current

LTS (Long-Term Support):
  - Стабильная версия для production
  - Поддержка 30 месяцев
  - Чётные мажорные версии: 18, 20, 22

Current:
  - Новые фичи, может быть нестабильной
  - Поддержка 6 месяцев
  - Нечётные: 19, 21, 23

Рекомендация: всегда использовать LTS для проектов

Когда НЕ подходит Node.js

  • Тяжёлые вычисления (обработка видео, ML) — один поток заблокирует Event Loop
  • CPU-bound задачи без Worker Threads
  • Приложения с жёсткими требованиями к типизации (лучше Go, Rust)

Решения для CPU-bound:

  • Worker Threads — параллельные потоки в Node.js
  • Вынести вычисления в отдельный сервис (Python, Go)
  • Child processes (child_process.fork)

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

  1. Блокирующие операцииreadFileSync в обработчике HTTP-запроса блокирует весь сервер
  2. Не обрабатывают ошибки — unhandled promise rejection крашит процесс
  3. Путают браузерное APIdocument, window, fetch (до Node 18) не существуют
  4. Нет .js в ESM-импортахimport { x } from './math' → нужно './math.js'
  5. Глобальные переменные — загрязнение global вместо использования модулей

Практика

  1. Установить Node.js через nvm, проверить node -v
  2. Написать HTTP-сервер на http.createServer
  3. Прочитать файл асинхронно и синхронно, сравнить поведение
  4. Использовать process.argv для чтения аргументов командной строки
  5. Создать модуль с функциями и подключить через require

Связанные темы

Ресурсы


🎓 Источник: Node.js Введение в технологию

  • 📅 2018-09-18 · YouTube · [Marp](../../../Documents/TimurShemsedinov/2018-09-18 — 🎧 Node.js Введение в технологию (WBcHgaoHh1k).md)
  • Тезисы:
    • Один язык на frontend, backend и базе — full-stack без переключения контекста
    • Состав Node.js: V8 (JS-движок), libuv (Event Loop + неблокирующий I/O), OpenSSL (crypto)
    • JSON — сквозной формат от UI до базы, без сериализации между слоями
    • Долгоживущий процесс с состоянием в памяти — не нужны REST и пересоздание контекста на запрос
    • Веб-сервер внутри приложения, не приложение внутри сервера (как в PHP/Apache)
    • JS однопоточный → консистентность данных без локов, никто не портит общую память
    • Меньше изоляции запросов: ошибка в одном запросе может уронить процесс — отсюда требование к качеству кода
    • Лимит памяти V8: ~1.5 GB по умолчанию, флаг --max-old-space-size
  • Цитата: «JavaScript — единственный язык, на котором можно писать и фронт, и бэк, и БД-логику в одном стеке»

🎓 Источник: Node.js Введение в технологию 2022

  • 📅 2022-12-31 · YouTube · [Marp](../../../Documents/TimurShemsedinov/2022-12-31 — 🚀 Node.js 🧑‍💻 Введение в технологию ✨ (mRvzgBGLVyM).md)
  • Тезисы: обновлённая обзорная лекция: V8, libuv, OpenSSL, npm, package.json, LTS-релизы

🎓 Источник: Введение в Node js и серверный JavaScript

  • 📅 2019-11-16 · YouTube · [Marp](../../../Documents/TimurShemsedinov/2019-11-16 — 4. Летняя школа 2017 - Введение в Node js и серверный JavaScript (iT1oDAyhybQ).md)
  • Тезисы:
    • JS однопоточный, но Node многопоточный за счёт libuv thread pool
    • Долгоживущий процесс хранит состояние — сессии, кеш, открытые соединения с БД
    • Процессов запускать по числу ядер (cluster), узкое место — общая шина
    • Скрытые классы V8: не меняй форму объекта в hot path, добавляй все поля при создании
    • В 2 раза медленнее C++ — норма для прикладного кода, выигрыш в скорости разработки