Работа с ZIP/архивами в TypeScript: обзор библиотек и практические примеры
В современной веб-разработке на TypeScript часто возникает необходимость работать с ZIP-архивами: упаковывать файлы на клиенте, распаковывать полученные с сервера данные или создавать сложные структуры архивов. В этой статье мы рассмотрим две самые популярные библиотеки — JSZip и adm-zip, их возможности, типизацию для TypeScript и приведем практические примеры использования.
1. JSZip — универсальная библиотека для браузера и Node.js
JSZip — это мощная библиотека для создания, чтения и редактирования ZIP-архивов, работающая как в браузере, так и в среде Node.js. Она имеет полную поддержку TypeScript.
Установка:
npm install jszip
npm install @types/jszip --save-dev
1.1 Создание ZIP-архива
import JSZip from 'jszip';
async function createArchive(): Promise<Blob> {
const zip = new JSZip();
// Добавляем текстовый файл
zip.file('hello.txt', 'Hello World!');
// Добавляем папку с файлом
const folder = zip.folder('images');
folder.file('logo.png', 'base64EncodedImageData...', {base64: true});
// Генерируем архив (Blob для браузера)
const blob = await zip.generateAsync({type: 'blob'});
return blob;
}
1.2 Чтение и распаковка архива
async function readArchive(file: File): Promise<void> {
const zip = new JSZip();
const content = await zip.loadAsync(file);
// Перебираем все файлы
content.forEach(async (relativePath, zipEntry) => {
if (!zipEntry.dir) {
const data = await zipEntry.async('string');
console.log(`Файл: ${relativePath}, содержимое: ${data}`);
}
});
}
1.3 Работа с метаданными
JSZip позволяет управлять датами, комментариями и правами доступа:
const zip = new JSZip();
zip.file('document.txt', 'Text content', {
date: new Date('2024-01-01'),
comment: 'Важный документ',
unixPermissions: '644'
});
2. adm-zip — легковесная альтернатива для Node.js
adm-zip — библиотека, оптимизированная для серверной части на Node.js. Она работает быстрее при больших объемах данных и имеет удобный API.
Установка:
npm install adm-zip
npm install @types/adm-zip --save-dev
2.1 Создание архива
import AdmZip from 'adm-zip';
function createServerArchive(): void {
const zip = new AdmZip();
// Добавление файла из буфера
zip.addFile('data.json', Buffer.from(JSON.stringify({key: 'value'})));
// Добавление локального файла
zip.addLocalFile('/path/to/file.txt');
// Добавление целой папки
zip.addLocalFolder('/path/to/folder', 'custom_folder_name');
// Запись на диск
zip.writeZip('archive.zip');
}
2.2 Распаковка и извлечение
function extractArchive(): void {
const zip = new AdmZip('./archive.zip');
// Извлечение всех файлов в папку
zip.extractAllTo('./extracted', true);
// Получение списка записей
const entries = zip.getEntries();
entries.forEach(entry => {
console.log(`Имя: ${entry.entryName}, Размер: ${entry.header.size}`);
// Получение содержимого
const content = entry.getData().toString('utf8');
});
}
3. Сравнение библиотек
- JSZip — универсальна, работает в браузере и Node.js, поддерживает потоковую генерацию, имеет богатый API для работы с метаданными.
- adm-zip — быстрее на больших объемах, проще API, но работает только в Node.js.
- Производительность: adm-zip выигрывает при работе с архивами >100 МБ.
- Типизация: обе имеют полную поддержку TypeScript из коробки.
4. Продвинутые сценарии использования
4.1 Шифрование архивов
Для защиты данных можно использовать шифрование AES-256 через обертку:
import JSZip from 'jszip';
import { encrypt } from './crypto-utils';
async function createEncryptedArchive(password: string): Promise<Blob> {
const zip = new JSZip();
zip.file('secret.txt', 'Секретные данные');