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

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

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

Начать курс

Работа с ZIP/архивами в TypeScript

В современной веб-разработке часто возникает необходимость работать с архивами: загружать несколько файлов одним пакетом, распаковывать конфигурации или создавать резервные копии данных. TypeScript, как статически типизированная надстройка над JavaScript, предоставляет удобные инструменты для этой задачи. В статье мы рассмотрим две популярные библиотеки: JSZip и adm-zip, а также научимся создавать, читать и модифицировать ZIP-архивы.

Почему TypeScript?

TypeScript добавляет строгую типизацию, что особенно полезно при работе с бинарными данными и сложными структурами архивов. Вы получаете автодополнение в IDE, раннее обнаружение ошибок и понятный код. Для работы с ZIP вам понадобится установить одну из библиотек через npm:

npm install jszip
npm install @types/jszip  // для поддержки TypeScript

или

npm install adm-zip
npm install @types/adm-zip

Библиотека JSZip: создание архива

JSZip — наиболее популярная библиотека для работы с ZIP в браузере и Node.js. Она работает асинхронно и поддерживает добавление файлов, папок и даже генерацию архива в формате Blob.

Создание простого архива

Рассмотрим пример, где мы создаём архив, содержащий текстовый файл и папку с изображением:

import JSZip from 'jszip';

async function createArchive(): Promise<Blob> {
  const zip = new JSZip();

  // Добавляем текстовый файл
  zip.file('hello.txt', 'Привет, мир!');

  // Создаём папку и добавляем файл
  const imgFolder = zip.folder('images');
  if (imgFolder) {
    imgFolder.file('logo.png', 'base64EncodedString...', { base64: true });
  }

  // Генерируем архив как Blob
  const blob = await zip.generateAsync({ type: 'blob' });
  return blob;
}

// Использование
createArchive().then(blob => {
  // Скачиваем архив
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = 'archive.zip';
  link.click();
});

В этом примере мы создали архив с двумя файлами. Обратите внимание на опцию { base64: true } — она позволяет добавлять бинарные данные, закодированные в base64.

Чтение и распаковка архива с помощью JSZip

Часто требуется прочитать существующий ZIP-файл, полученный от пользователя или с сервера. JSZip умеет загружать архив из Blob, ArrayBuffer или строки base64.

async function readArchive(file: Blob): Promise<void> {
  try {
    const zip = await JSZip.loadAsync(file);

    // Получаем список файлов
    const fileList: string[] = [];
    zip.forEach((relativePath, zipEntry) => {
      fileList.push(relativePath);
    });
    console.log('Файлы в архиве:', fileList);

    // Извлекаем содержимое конкретного файла
    const content = await zip.file('hello.txt')?.async('string');
    console.log('Содержимое hello.txt:', content);
  } catch (error) {
    console.error('Ошибка при чтении архива:', error);
  }
}

// Пример с загрузкой файла через input
document.getElementById('fileInput')?.addEventListener('change', (event) => {
  const input = event.target as HTMLInputElement;
  if (input.files && input.files[0]) {
    readArchive(input.files[0]);
  }
});

Метод async('string') возвращает содержимое файла как строку. Для бинарных данных используйте 'arraybuffer' или 'uint8array'.

Библиотека adm-zip: работа в Node.js

Если вы разрабатываете серверное приложение на Node.js, adm-zip может быть более удобным выбором. Эта библиотека синхронная (но есть и асинхронные методы) и поддерживает запись архива сразу в файловую систему.

Создание архива с adm-zip

import AdmZip from 'adm-zip';
import * as path from 'path';

function createArchiveToDisk(): void {
  const zip = new AdmZip();

  // Добавляем файл из строки
  zip.addFile('readme.txt', Buffer.from('Документация к проекту', 'utf-8'));

  // Добавляем файл из диска
  zip.addLocalFile(path.join(__dirname, 'config.json'));

  // Добавляем целую папку
  zip.addLocalFolder(path.join(__dirname, 'assets'), 'resources');

  // Сохраняем архив
  zip.writeZip('project.zip');
  console.log('Архив project.zip создан');
}

createArchiveToDisk();

Метод addLocalFolder позволяет добавить все файлы из указанной директории, сохраняя структуру папок.

Распаковка архива с adm-zip

<                    

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