- Объяснять, что такое Node.js и чем он отличается от JavaScript в браузере
- Создавать проект через
npm, устанавливать пакеты и запускать скрипты изpackage.json - Использовать ES-модули и встроенные
fs/promises,path,processдля работы с файлами и аргументами командной строки
До 2009 года JavaScript жил только внутри браузеров. В том году Райан Дал (Ryan Dahl) взял движок V8 из Chrome и представил Node.js — среду, которая запускает JavaScript на серверах и обычных компьютерах. Сегодня на Node.js работают бэкенды (API), инструменты командной строки и даже настольные приложения: Vite, ESLint и Prettier работают на Node.js, а редактор VS Code построен на Electron, который основан на Node.js.
Что такое Node.js
Node.js = движок V8 + libuv (цикл событий и асинхронный ввод-вывод) + встроенные модули (fs, path, http, crypto и другие). Язык тот же, среда другая: нет document и window, зато есть файлы, сеть и процессы. Твой JavaScript по-прежнему работает в одном потоке со знакомым циклом событий, а тяжёлый ввод-вывод система выполняет в фоне.
| Браузер | Node.js | |
|---|---|---|
| DOM | есть (document) | нет |
| Файлы | только если пользователь выберет | полный доступ (fs) |
| Глобальный объект | window / globalThis | global / globalThis |
| Модули | ES-модули | ES-модули и CommonJS |
| Где работает код | на устройстве пользователя | на сервере или твоём компьютере |
- 1Установи
Скачай версию LTS (долгосрочная поддержка) с сайта nodejs.org и установи её.
- 2Проверь
В терминале набери
node -vиnpm -v— должны появиться версии. - 3Создай файл
Напиши в файле
hello.jsстрокуconsole.log('Hello from Node!');. - 4Запусти
node hello.js. Командаnodeбез файла открывает интерактивную консоль (REPL); выйти —.exit.
Модули: ES и CommonJS
В Node.js две системы модулей. CommonJS (require и module.exports) — историческая, она повсюду в старых проектах. ES-модули (import/export) — стандарт, такой же, как в браузере. В новых проектах выбирай ES-модули: добавь в package.json строку "type": "module" или давай файлам расширение .mjs. Встроенные модули импортируй с префиксом node:: import fs from 'node:fs'.
// math.js
export const PI = 3.14159;
export function circleArea(r) {
return PI * r * r;
}
// app.js
import { circleArea } from './math.js';
import os from 'node:os';
console.log(circleArea(2).toFixed(2));
console.log(`Platform: ${os.platform()}`);12.57 Platform: win32
node app.js; в Windows будет win32, в macOS — darwin, в Linux — linux.| CommonJS | ES-модули | |
|---|---|---|
| Экспорт | module.exports = { circleArea } | export function circleArea() {} |
| Импорт | const { circleArea } = require('./math') | import { circleArea } from './math.js' |
| Папка файла | __dirname | import.meta.dirname |
await на верхнем уровне | нет | есть |
npm и package.json
npm (Node Package Manager) устанавливается вместе с Node.js и даёт доступ к реестру с миллионами пакетов. npm init -y создаёт package.json, npm install dayjs добавляет зависимость, а npm install -D vitest — зависимость только для разработки. Код пакетов попадает в папку node_modules, а package-lock.json фиксирует точные версии. npm run dev запускает команду из раздела scripts, а npx выполняет команду пакета без глобальной установки.
{
"name": "notes-cli",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node notes.js",
"test": "vitest"
},
"dependencies": {
"dayjs": "^1.11.10"
},
"devDependencies": {
"vitest": "^2.1.0"
}
}major.minor.patch: ^1.11.10 разрешает любую более новую версию ниже 2.0.0, ~1.11.10 — только исправления 1.11.x, а 1.11.10 — только эту версию.Файлы, пути и процесс
node:fs/promises даёт асинхронные функции для файлов: readFile, writeFile, mkdir, readdir. node:path правильно строит пути и в Windows (\), и в Linux и macOS (/). process.argv содержит аргументы командной строки, а process.env — переменные окружения. Маленькая программа ниже хранит заметки в JSON-файле.
// notes.js
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import path from 'node:path';
const dir = path.join(import.meta.dirname, 'data');
const file = path.join(dir, 'notes.json');
await mkdir(dir, { recursive: true });
let notes = [];
try {
notes = JSON.parse(await readFile(file, 'utf8'));
} catch (error) {
if (error.code !== 'ENOENT') throw error;
}
const text = process.argv.slice(2).join(' ') || 'Empty note';
notes.push({ id: notes.length + 1, text });
await writeFile(file, JSON.stringify(notes, null, 2));
console.log(`Saved note #${notes.length}: ${text}`);
console.log('File:', path.basename(file), '| notes:', notes.length);Saved note #1: Buy bread File: notes.json | notes: 1 Saved note #2: Call Leyla File: notes.json | notes: 2
node notes.js Buy bread, затем node notes.js Call Leyla. ENOENT означает «файл не найден» — при первом запуске это нормально.Чтобы сделать веб-сервер на Node.js, даже библиотека не нужна — хватит встроенного модуля node:http. В реальных проектах обычно используют фреймворки вроде Express или Fastify, но все они построены на этой основе.
// server.js
import http from 'node:http';
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Hello from Node', path: req.url }));
});
server.listen(3000, () => console.log('Server on http://localhost:3000'));Server on http://localhost:3000
http://localhost:3000/api/hello — ответ: {"message":"Hello from Node","path":"/api/hello"}. Чтобы остановить сервер, нажми в терминале Ctrl+C.Здесь process.argv имитирует переменная argv. Напиши parseArgs(args): пары --ключ значение превращаются в { ключ: 'значение' }, а флаг без значения после него (--verbose) получает true.
const argv = ['node', 'app.js', '--city', 'Baku', '--days', '3', '--verbose'];
function parseArgs(args) {
const options = {};
// walk through args; --key value → options[key] = value, lone --flag → true
return options;
}
console.log(parseArgs(argv.slice(2)));
console.log(parseArgs(['--help']));▸ Ожидаемый результат
{ city: 'Baku', days: '3', verbose: true }
{ help: true }Напиши satisfiesCaret(version, range): для диапазона вида ^1.4.0 версия должна иметь тот же номер major и быть не ниже версии из диапазона (особые правила для 0.x не учитывай).
function satisfiesCaret(version, range) {
// compare major, then minor, then patch
}
for (const version of ['1.5.2', '1.4.0', '2.0.0', '1.3.9']) {
console.log(version, satisfiesCaret(version, '^1.4.0'));
}▸ Ожидаемый результат
1.5.2 true 1.4.0 true 2.0.0 false 1.3.9 false
Главное
- Node.js = V8 + цикл событий (libuv) + встроенные модули: JavaScript без DOM, но с файлами, сетью и процессами.
- В новых проектах используй ES-модули (
"type": "module", префиксnode:);requireостаётся в старом коде. package.jsonописывает проект: скрипты,dependencies,devDependencies;package-lock.jsonфиксирует версии, аnode_modulesне коммитят.- Semver — это
major.minor.patch:^разрешает обновления minor и patch,~— только patch. fs/promises,pathиprocessотвечают за файлы, переносимые пути, аргументы и переменные окружения.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.