Awesome
<em>µ</em>compress
<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:
createFile
, a boolean property,false
by default, that will automatically pre-compress via brotli, gzip, and deflate, compatible files, plus it will create a.json
file with pre-processed headers details per each filemaxWidth
, an integer property, that if provided, it will reduce, if necessary, the destination image width when it comes to JPG or PNG filesmaxHeight
, an integer property, that if provided, it will reduce, if necessary, the destination image height when it comes to JPG or PNG filespreview
, a boolean parameter, false by default, that creates JPG counter.preview.jpg
files to be served instead of originals, enabling bandwidth saving, especially for very big pictures (example: with-preview)noImport
, a boolean parameter, false by default, that skips automatic ESMimport
resolution, in case the site provides imports maps by itselfnoMinify
, a boolean parameter, false by default, that keeps the.js
,.css
, and.html
source intact, still performing other changes, such as.js
imports
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:
- css files via csso
- gif files via gifsicle as optional dependency
- html files via html-minifier
- jpg or jpeg files via sharp
- js or mjs files via terser and html-minifier
- json files are simply parsed and stringified so that white spaces get removed
- md files are transformed into their
.md.preview.html
version, if the preview is enabled, through marked - png files via pngquant-bin
- svg files via svgo
- xml files via html-minifier
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.
- .css
- .html
- .js
- .mjs
- .map
- .json
- .md
- .svg
- .txt
- .woff2
- .xml
- .yml
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.