Работа с ZIP-архивами в Node.js: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с ZIP-архивами в Node.js: библиотеки adm-zip и archiver

В современной веб-разработке на Node.js часто возникает необходимость работать с архивами: упаковывать логи, передавать файлы группами, распаковывать загруженные пользователем данные. В этом материале мы рассмотрим две основные библиотеки для работы с ZIP-форматом — adm-zip и archiver. Они решают практически все задачи, связанные с архивацией, и отлично подходят как для простых скриптов, так и для продакшн-приложений.

Библиотека adm-zip: универсальный инструмент для чтения и записи ZIP

adm-zip — это чисто JavaScript-реализация работы с ZIP-архивами без внешних зависимостей. Она позволяет как создавать новые архивы, так и читать/модифицировать существующие. Библиотека проста в использовании и не требует установки дополнительных системных утилит.

Установка

npm install adm-zip

Создание ZIP-архива

const AdmZip = require('adm-zip');
const fs = require('fs');

// Создаем новый экземпляр архива
const zip = new AdmZip();

// Добавляем файлы из буфера или строки
zip.addFile('hello.txt', Buffer.from('Hello, World!', 'utf8'));

// Добавляем локальный файл
zip.addLocalFile('/path/to/image.png');

// Добавляем целую папку
zip.addLocalFolder('/path/to/documents', 'docs');

// Записываем архив на диск
zip.writeZip('./output/archive.zip');

console.log('Архив создан успешно!');

Чтение и распаковка существующего архива

const AdmZip = require('adm-zip');

// Загружаем существующий архив
const zip = new AdmZip('./input/archive.zip');

// Получаем список файлов
const zipEntries = zip.getEntries();
zipEntries.forEach((entry) => {
    console.log(`Файл: ${entry.entryName}, размер: ${entry.header.size} байт`);
});

// Извлекаем все файлы в указанную папку
zip.extractAllTo('./extracted', true); // true — перезаписывать существующие файлы

// Или получаем содержимое конкретного файла
const content = zip.readAsText('data.json');
console.log('Содержимое data.json:', content);

Работа с буферами (без записи на диск)

const AdmZip = require('adm-zip');
const zip = new AdmZip();

zip.addFile('report.csv', 'id,name,age\n1,John,30');

// Получаем архив как Buffer для отправки через HTTP
const archiveBuffer = zip.toBuffer();

// Теперь archiveBuffer можно отправить как ответ сервера
// или передать в другую функцию

Библиотека archiver: продвинутое потоковое архивирование

archiver — это более мощная библиотека, оптимизированная для работы с большими объёмами данных. Она использует потоки (streams) Node.js, что позволяет архивировать файлы «на лету» без загрузки всего содержимого в память. Это идеальный выбор для серверных приложений с ограниченными ресурсами.

Установка

npm install archiver

Создание архива с потоковым выводом

const archiver = require('archiver');
const fs = require('fs');
const path = require('path');

// Создаём поток записи
const output = fs.createWriteStream('./backup.zip');
const archive = archiver('zip', {
    zlib: { level: 9 } // Максимальная степень сжатия
});

// Обработка событий
output.on('close', () => {
    console.log(`Архив создан: ${archive.pointer()} байт`);
});

archive.on('error', (err) => {
    throw err;
});

// Подключаем поток архива к выходному файлу
archive.pipe(output);

// Добавляем файлы
archive.file('/var/log/app.log', { name: 'logs/app.log' });

// Добавляем директорию рекурсивно
archive.directory('uploads/', 'user_files');

// Добавляем строку как файл
archive.append('Это содержимое файла', { name: 'readme.txt' });

// Завершаем архивацию
archive.finalize();

Отправка архива через HTTP-ответ

const express = require('express');
const archiver = require('archiver');
const app = express();

app.get('/download', (req, res) => {
    // Устанавливаем заголовки для скачивания ZIP
    res.attachment('documents.zip');
    
    const archive = archiver('zip', { zlib: { level: 6 } });
    
    archive.on('error', (err) => {
        res.status(500).send('Ошибка создания архива');
    });
    
    archive.pipe(res);
    
    // Добавляем файлы прямо из базы данных или виртуальные
    archive.append('{"user":"admin"}', { name: 'config.json' });
    archive.file('./public/style.css', { name: 'assets/style.css' });
    
    archive.finalize();
});

app.listen(3000);

Рекомендаций