Работа с ZIP-архивами в TypeScript: библиотека JSZip и практические примеры
В современной веб-разработке часто возникает необходимость упаковывать несколько файлов в один архив для удобной загрузки или передачи данных. В экосистеме TypeScript (и JavaScript) наиболее популярным решением для работы с ZIP-архивами является библиотека JSZip. Она позволяет создавать, читать и модифицировать ZIP-файлы как в браузере, так и в среде Node.js.
В этой статье мы подробно разберём установку, настройку и основные сценарии использования JSZip в TypeScript-проектах. Вы научитесь создавать архивы из строк, бинарных данных и целых папок, а также извлекать содержимое существующих ZIP-файлов.
Установка и подключение JSZip
Для начала работы установите библиотеку и её типы через npm или yarn:
npm install jszip
npm install --save-dev @types/jszip
После установки импортируйте JSZip в ваш TypeScript-файл:
import JSZip from 'jszip';
Если вы используете модульную систему (ES modules), импорт будет работать как показано выше. Для CommonJS (require) синтаксис может отличаться, но в TypeScript-проектах рекомендуется использовать ES-импорты.
Создание нового ZIP-архива
Самый простой сценарий — создать архив и добавить в него несколько текстовых файлов. Рассмотрим пример:
const zip = new JSZip();
// Добавляем текстовые файлы
zip.file("hello.txt", "Hello, World!");
zip.file("readme.md", "# Документация\n\nЭто пример Markdown-файла.");
// Добавляем папку и файл внутри неё
const folder = zip.folder("images");
folder.file("logo.png", "base64encodedstring...", {base64: true});
// Генерируем ZIP-файл как Blob
zip.generateAsync({type: "blob"}).then((content) => {
// Создаём ссылку для скачивания
const link = document.createElement("a");
link.href = URL.createObjectURL(content);
link.download = "my-archive.zip";
link.click();
});
В этом примере мы:
- Создали экземпляр
JSZip - Добавили два текстовых файла методом
.file() - Создали вложенную папку
imagesи поместили в неё файл с base64-данными - Сгенерировали архив в формате Blob и инициировали скачивание
Чтение и извлечение существующего ZIP-архива
JSZip позволяет не только создавать, но и читать архивы. Для этого используется метод loadAsync():
async function readZipFile(zipBlob: Blob): Promise<void> {
try {
const zip = await JSZip.loadAsync(zipBlob);
// Получаем список всех файлов
const fileNames = Object.keys(zip.files);
console.log("Файлы в архиве:", fileNames);
// Извлекаем содержимое конкретного файла
const helloFile = zip.file("hello.txt");
if (helloFile) {
const content = await helloFile.async("string");
console.log("Содержимое hello.txt:", content);
}
// Итерация по всем файлам
zip.forEach((relativePath, zipEntry) => {
console.log(`Найден файл: ${relativePath}, размер: ${zipEntry._data.uncompressedSize} байт`);
});
} catch (error) {
console.error("Ошибка при чтении ZIP:", error);
}
}
Обратите внимание на типизацию: JSZip.loadAsync() возвращает промис, который разрешается в объект JSZip. Метод .file() возвращает JSZipObject | null, поэтому перед вызовом .async() нужно проверить существование файла.
Работа с бинарными данными и изображениями
Часто требуется упаковать в архив изображения или другие бинарные файлы. JSZip поддерживает работу с ArrayBuffer, Blob, Uint8Array и base64:
// Добавление файла из ArrayBuffer
const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);
view.set([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello" в UTF-8
zip.file("binary.dat", buffer);
// Добавление файла из Blob (например, с сервера)
const response = await fetch("https://example.com/image.png");
const imageBlob = await response.blob();
zip.file("photo.png", imageBlob);
// Чтение файла как ArrayBuffer
const file = zip.file("photo.png");
if (file) {
const arrayBuffer = await file.async("arraybuffer");
console.log("Размер изображения:", arrayBuffer.byteLength);
}