Home

Awesome

<em>µ</em>compress

Build Status Coverage Status

compressed umbrellas

<sup>Social Media Photo by Kevin Borrill on Unsplash</sup>

A <em>micro</em>, all-in-one, compressor for common Web files, resolving automatically JavaScript imports, when these are static.

📣 Community Announcement

Please ask questions in the dedicated forum to help the community around this project grow ♥


As CLI

Due amount of dependencies, it's recommended to install this module via npm i -g ucompress. However you can try it via npx too.

# either npm i -g ucompress once, or ...
npx ucompress --help

If --source and --dest parameter are passed, it will do everything automatically.

ucompress --source ./src --dest ./public

Check other flags for extra optimizations, such as .json headers files and/or .br, .gzip, and .deflate versions, which you can serve via NodeJS or Express, using µcdn-utils.

As module

import ucompress from 'ucompress';
// const ucompress = require('ucompress');

// define or retrieve `source` and `dest as you like

// automatic extension => compression
ucompress(source, dest).then(dest => console.log(dest));

// explicit compression
ucompress.html(source, dest).then(dest => console.log(dest));

// handy fallback
ucompress.copy(source, dest).then(dest => console.log(dest));

Options

The optional third options object parameter can contain any of the following properties:

As Micro CDN

If you'd like to use this module to serve files CDN like, check µcdn out, it includes ucompress already, as explained in this post.

Compressions

Following the list of tools ued to optimized various files:

About Automatic Modules Resolution

If your modules are published as dual-module, or if you have a module field in your package.json, and it points at an ESM compatible file, as it should, or if you have a type field equal to module and a main that points at an ESM compatible, or if you have an exports field which import resolves to an ESM compatible module, µcompress will resolve that entry point automatically.

In every other case, the import will be left untouched, eventually warning in console when such import failed.

Dynamic imports are resolved in a very similar way, but composed imports will likely fail:

// these work if the module is found in the source path
// as example, inside source/node_modules
import 'module-a';
import('module-b').then(...);

// these work *only* if the file is in the source path
// but not within a module, as resolved modules are not
// copied over, only known imports, eventually, are
import(`/js/${strategy}.js`);

// these will *not* work
import(condition ? 'condition-thing' : 'another-thing');
import('a' + thing + '.js');

About ucompress.createHeaders(path[, headers])

This method creates headers for a specific file, or all files within a folder, excluding files that starts with a . dot, an _ underscore, or files within a node_modules folder (you know, that hole that should never fully land in production).

ucompress.createHeaders(
  // a folder with already optimized files
  '/path/static',
  // optional headers to set per folder
  {'Access-Control-Allow-Origin': '*'}
);

Brotli, Deflate, GZip, and Headers

If the third, optional object, contains a {createFile: true} flag, each file will automatically generate its own related .json file which includes a RFC-7232 compliant ETag, among other details such as last-modified, content-type, and content-length.

The following file extensions, available via the ucompress.encoded Set, will also create their .br, .deflate, and .gzip version in the destination folder, plus their own .json file, per each different compression, but only when {createFile: true} is passed.

Incompatible files will fallback as regular copy source into dest when the module is used as callback, without creating any optimized version, still providing headers when the flag is used.