← 返回
未分类

Archiver — Streaming Archive Packaging

Use the Archiver library for streaming archive packaging in Node.js. Supports creating ZIP/TAR archives, appending content from streams, strings, buffers, fi...
使用 Archiver 库在 Node.js 中进行流式归档打包,支持创建 ZIP/TAR 压缩包,可向其中追加流、字符串、缓冲区、文件等内容。
openlark openlark 来源
未分类 clawhub v1.0.1 2 版本 99736.8 Key: 无需
★ 0
Stars
📥 379
下载
💾 1
安装
2
版本
#latest

概述

Archiver — Streaming Archive Packaging

A Node.js streaming archive library that supports ZIP and TAR, capable of appending content from multiple data sources.

Use Cases

Use when users need to compress and package, create zip/tar archives, package directories, or programmatically generate compressed files.

Trigger Words

Compress, package, archive, zip, tar, archive, archiver.

Installation

npm install archiver

Quick Start: ZIP Packaging

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

const output = fs.createWriteStream('output.zip');
const archive = archiver('zip', { zlib: { level: 9 } });

output.on('close', () => {
  console.log(`${archive.pointer()} bytes written`);
});

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

archive.pipe(output);

// Append — multiple data sources
archive.append(fs.createReadStream('file.txt'), { name: 'file.txt' });  // Stream
archive.append('string content', { name: 'readme.txt' });               // String
archive.append(Buffer.from('data'), { name: 'data.bin' });              // Buffer
archive.file('local-file.txt', { name: 'renamed.txt' });                // Local file
archive.directory('src/', 'src');                                        // Directory → subdirectory in archive
archive.directory('dist/', false);                                       // Directory contents → archive root
archive.glob('*.js', { cwd: __dirname });                                // Glob match

// ⚠️ `archive.directory()` does NOT support ignore/filter patterns.
//    To exclude node_modules, use glob() instead (see Excluding node_modules below).

archive.finalize();

Data Source Overview

MethodData Sourcename Parameter
-------------------------------------
archive.append(stream, { name })ReadStreamRequired
archive.append(string, { name })StringRequired
archive.append(buffer, { name })BufferRequired
archive.file(path, { name })File pathOptional, can rename
archive.directory(path, dest)Directoryfalse = contents to root; string = subdirectory name
archive.glob(pattern, { cwd })Glob matchAuto-uses matched filenames

TAR Packaging

const archive = archiver('tar', {
  gzip: true,
  gzipOptions: { level: 6 }
});

TAR-specific options:

OptionDescriptionDefault
------------------------------
gzipEnable gzip compressionfalse
gzipOptions.levelCompression level 0-96

Events

archive.on('warning', (err) => {
  if (err.code === 'ENOENT') console.warn('File not found:', err);
  else throw err;
});

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

// Events on the piped destination stream (from Node.js Stream API)
output.on('close', () => { /* File descriptor closed */ });
output.on('end', () => { /* Data drained */ });
output.on('finish', () => { /* All data written */ });
  • warning — Non-fatal errors (e.g., file not found, stat failure, etc.); ENOENT can be ignored, others should be thrown
  • error — Fatal errors; must be handled
  • close (output) — Emitted after the file descriptor is closed; archive.pointer() can be used to get the total byte count at this point
  • end (output) — Data drained; emitted regardless of the data source
  • progress — Progress tracking, see below

Progress Tracking

archive.on('progress', (progress) => {
  console.log(`${progress.entries.processed} / ${progress.entries.total} entries`);
  console.log(`${progress.fs.processedBytes} / ${progress.fs.totalBytes} bytes`);
});

progress object structure:

{
  entries: { total: number, processed: number },
  fs: { totalBytes: number, processedBytes: number }
}

Common Patterns

Pattern 1: Responsive Archiving — HTTP Streaming Output

app.get('/download', (req, res) => {
  res.attachment('archive.zip');
  const archive = archiver('zip', { zlib: { level: 1 } }); // Low compression = faster

  archive.on('error', (err) => { res.status(500).end(); });

  archive.pipe(res);
  archive.directory('user-files/', false);
  archive.finalize();
});

Pattern 2: Conditional Append — On-Demand Packaging

const archive = archiver('zip');

// Dynamically append based on conditions
if (includeSource) {
  archive.directory('src/', 'source');
}
if (includeDocs) {
  archive.glob('docs/**/*.md', { cwd: __dirname });
}

archive.finalize();

Pattern 3: In-Memory Archiving — No File Output

const { Writable } = require('stream');

const chunks = [];
const memoryStream = new Writable({
  write(chunk, enc, cb) { chunks.push(chunk); cb(); }
});

const archive = archiver('zip');
archive.pipe(memoryStream);

archive.append('hello', { name: 'hello.txt' });
archive.finalize();

memoryStream.on('finish', () => {
  const buffer = Buffer.concat(chunks);
  console.log(`Archive in memory: ${buffer.length} bytes`);
  // Can be used for uploading, sending, etc.
});

Pattern 4: Excluding node_modules When Packaging a Project

> archive.directory() has no built-in ignore — it adds everything recursively.

> To skip node_modules, use one of these approaches:

Option A — glob() with ignore (recommended):

const archive = archiver('zip', { zlib: { level: 9 } });
archive.pipe(fs.createWriteStream('project.zip'));

// glob picks up files but lets you set ignore patterns
archive.glob('**/*', {
  cwd: '/path/to/project',
  ignore: ['node_modules/**', '.git/**', 'dist/**'],
  dot: true,             // include dotfiles
});

archive.finalize();

Option B — Manual directory walk (custom filtering):

const klaw = require('klaw');       // or fs.walk / @nodelib/fs.walk

archive.glob('**/*', {
  cwd: rootDir,
  ignore: ['node_modules/**'],
  dot: true,
});
archive.finalize();

> Why not archive.directory()? directory() is a one-shot bulk append with no filter callback. For any kind of exclusion, always switch to glob() — it's the same code walking underneath, just with pattern support.

Option C — Pre-build a file list:

const klaw = require('klaw');  // npm install klaw

async function zipWithFilter(srcDir, outPath) {
  const archive = archiver('zip', { zlib: { level: 9 } });
  archive.pipe(fs.createWriteStream(outPath));

  for await (const file of klaw(srcDir)) {
    if (file.stats.isFile() && !file.path.includes('node_modules')) {
      archive.file(file.path, { name: path.relative(srcDir, file.path) });
    }
  }

  await archive.finalize();
}

Pattern 5: Batch Packaging — Multiple Archives in Series

async function createBatchedArchives(fileGroups, outputDir) {
  for (const [i, files] of fileGroups.entries()) {
    await new Promise((resolve, reject) => {
      const output = fs.createWriteStream(`${outputDir}/batch-${i}.zip`);
      const archive = archiver('zip');

      archive.on('error', reject);
      output.on('close', resolve);

      archive.pipe(output);
      files.forEach(f => archive.file(f, { name: path.basename(f) }));
      archive.finalize();
    });
    console.log(`Batch ${i} complete`);
  }
}

Custom Format Registration

archiver.registerFormat('myformat', module);
const archive = archiver('myformat');

Check if a format is registered:

if (archiver.isRegisteredFormat('zip')) {
  // ZIP is available
}

Symlink Handling

archive.symlink('target', { name: 'link-name' });

Common Options Reference — archiver(format, options)

const archive = archiver('zip', {
  zlib: { level: 9 },          // Compression level 0-9
  comment: 'my comment',       // ZIP comment
  forceLocalTime: true,        // Use local time instead of UTC
  forceZip64: false,           // Whether to force Zip64
  namePrependSlash: false,     // Prepend / to filenames
  statConcurrency: 4           // Stat concurrency
});

For the full API reference, see references/api-reference.md.

版本历史

共 2 个版本

  • v1.0.1 当前
    2026-06-01 21:09
  • v1.0.0
    2026-05-08 13:37 安全 安全

安全检测

腾讯云安全 (Keen)

队列中

腾讯云安全 (Sanbu)

队列中

🔗 相关推荐

content-creation

Toutiao Graphic Publisher

openlark
通过浏览器自动化在头条发布图文内容,支持智能排版、自动生成热门标签等功能。
★ 2 📥 970
data-analysis

Chartjs

openlark
Chart.js 图表技能,用于生成折线图、柱状图、饼图、雷达图、散点图等可视化图表。
★ 0 📥 691
dev-programming

Sqlite Client

openlark
SQLite 数据库操作技能。当用户需要创建、读取、查询或修改 SQLite 数据库(.db 文件)时使用。
★ 0 📥 713