Compress Commons Archive Utilities
compress-commons is a Node.js library that provides a common, low-level interface for defining and working with various archive formats, particularly ZIP, within a Node.js environment. Inspired by the established Java library Apache Commons Compress, it aims to offer foundational building blocks and structures (like file headers and entry definitions) for handling archive data. The current stable version is 7.0.0, which transitioned to being an ESM-only package and requires Node.js v18 or newer. While its release cadence is regular, it does not follow a strict schedule. This library differentiates itself by focusing on the underlying components and specifications of archive formats, rather than providing a high-level API for creating or extracting archives directly, making it suitable for developers who need granular control over archive manipulation.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module ... from ... not supported.
cause Attempting to use `require()` to import `compress-commons` or its submodules, which are now ES Modules.fixChange `const { Symbol } = require('compress-commons/zip');` to `import { Symbol } from 'compress-commons/zip';` and ensure your project is configured for ESM (e.g., `"type": "module"` in package.json or using `.mjs` file extensions). -
Error: The "path" argument must be of type string. Received undefined
cause An `Entry` or `Headers` object was likely constructed without a required `path` property in its configuration.fixEnsure that the `path` property is explicitly provided as a string when creating `Headers` or `Entry` instances, e.g., `new Headers({ path: 'my-file.txt', ... })`. -
TypeError: Class constructor Headers cannot be invoked without 'new'
cause Attempting to call `Headers` (or `Entry`) as a function instead of a constructor.fixAlways instantiate `Headers` and `Entry` using the `new` keyword: `const header = new Headers({...});`.
Warnings
- breaking Version 7.0.0 of `compress-commons` is an ES Modules (ESM) only package. Projects using CommonJS `require()` will encounter `ERR_REQUIRE_ESM` errors.
- breaking `compress-commons` v7.0.0 and above explicitly require Node.js v18 or higher. Running with older Node.js versions will result in errors.
- breaking Version 6.0.0 dropped official support for Node.js v12. While it might still function, compatibility is not guaranteed, and potential issues may arise.
- breaking Version 5.0.0 dropped support for Node.js v10. Using v5.0.0+ with Node.js v10 will lead to compatibility problems and errors.
- gotcha This library provides low-level interfaces for archive formats, such as defining ZIP entry headers. It is not a complete archiving solution like `archiver` itself. You will likely need to integrate it with another library to write complete archive files.
Install
-
npm install compress-commons -
yarn add compress-commons -
pnpm add compress-commons
Imports
- Entry
const { Entry } = require('compress-commons/zip');import { Entry } from 'compress-commons/zip'; - Headers
const { Headers } = require('compress-commons/zip');import { Headers } from 'compress-commons/zip'; - constants
const constants = require('compress-commons/lib/constants');import * as constants from 'compress-commons/lib/constants';
Quickstart
import { Entry, Headers } from 'compress-commons/zip';
import { pipeline } from 'stream/promises';
import { createReadStream, createWriteStream, promises as fsPromises } from 'fs';
import path from 'path';
async function createSimpleZipEntryDefinition() {
const filePath = path.join(process.cwd(), 'temp_file.txt');
const outputZipPath = path.join(process.cwd(), 'output.zip');
const fileContent = 'This is a test file for compress-commons quickstart.';
// Create a dummy file to simulate content
await fsPromises.writeFile(filePath, fileContent);
// Define the header for the ZIP entry
const header = new Headers({
path: 'my-entry.txt', // Name of the file inside the archive
comment: 'A sample entry.',
size: Buffer.byteLength(fileContent), // Uncompressed size
crc32: 0, // Placeholder, actual CRC32 calculated by archiver
});
// Create an Entry object. In a real scenario, this would be fed into an archiver stream.
const entry = new Entry(header, {
type: 'file',
source: createReadStream(filePath), // Source can be a stream or Buffer
});
console.log(`Defined ZIP entry: ${entry.header.path}`);
console.log(`Entry size: ${entry.header.size} bytes`);
// This library provides common interfaces, not a full archiver.
// To actually create a .zip file, you'd typically use a library like 'archiver'
// that consumes these 'Entry' objects.
// For demonstration, we'll just show the entry definition.
// A full archiver would look something like this (conceptual):
// import archiver from 'archiver';
// const archive = archiver('zip', { zlib: { level: 9 } });
// archive.pipe(createWriteStream(outputZipPath));
// archive.append(entry.source, { name: entry.header.path });
// await archive.finalize();
// console.log(`
Conceptually, 'my-entry.txt' would be added to a ZIP archive.`);
await fsPromises.unlink(filePath);
}
createSimpleZipEntryDefinition().catch(console.error);