Работа с ZIP/архивами в TypeScript: полное руководство по JSZip и adm-zip

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

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

Начать курс

Работа с 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', 'Секретные данные');                    

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