Skip to content

Commit

Permalink
Require Node.js 12.20 and move to ESM (#29)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
antongolub and sindresorhus committed Aug 6, 2021
1 parent 10e154d commit bcb0b34
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 66 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI
on:
- push
- pull_request
jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
5 changes: 0 additions & 5 deletions .travis.yml

This file was deleted.

69 changes: 39 additions & 30 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env node
'use strict';
const arrify = require('arrify');
const meow = require('meow');
const getStdin = require('get-stdin');
const imagemin = require('imagemin');
const ora = require('ora');
const plur = require('plur');
const stripIndent = require('strip-indent');
const pairs = require('lodash.pairs');
import {Buffer} from 'node:buffer';
import process from 'node:process';
import arrify from 'arrify';
import meow from 'meow';
import getStdin from 'get-stdin';
import imagemin from 'imagemin';
import ora from 'ora';
import plur from 'plur';
import stripIndent from 'strip-indent';
import pairs from 'lodash.pairs';

const cli = meow(`
Usage
Expand All @@ -27,6 +28,7 @@ const cli = meow(`
$ imagemin foo.png --plugin.pngquant.quality={0.1,0.2} > foo-optimized.png
$ imagemin foo.png --plugin.webp.quality=95 --plugin.webp.preset=icon > foo-icon.webp
`, {
importMeta: import.meta,
flags: {
plugin: {
type: 'string',
Expand All @@ -36,20 +38,21 @@ const cli = meow(`
'gifsicle',
'jpegtran',
'optipng',
'svgo'
]
'svgo',
],
},
outDir: {
type: 'string',
alias: 'o'
}
}
alias: 'o',
},
},
});

const requirePlugins = plugins => plugins.map(([plugin, options]) => {
const requirePlugins = plugins => Promise.all(plugins.map(async ([plugin, options]) => {
try {
return require(`imagemin-${plugin}`)(options);
} catch (_) {
const {default: _plugin} = await import(`imagemin-${plugin}`); // eslint-disable-line node/no-unsupported-features/es-syntax
return _plugin(options);
} catch {
console.error(stripIndent(`
Unknown plugin: ${plugin}
Expand All @@ -61,19 +64,26 @@ const requirePlugins = plugins => plugins.map(([plugin, options]) => {

process.exit(1);
}
});
}));

const normalizePluginOptions = plugin => {
return pairs(arrify(plugin).reduce((m, v) => {
return typeof v === 'object' ?
{...m, ...v} :
{[v]: {}, ...m};
}, {}));
const pluginOptionsMap = {};

for (const v of arrify(plugin)) {
Object.assign(
pluginOptionsMap,
typeof v === 'object'
? v
: {[v]: {}},
);
}

return pairs(pluginOptionsMap);
};

const run = async (input, {outDir, plugin} = {}) => {
const pluginOptions = normalizePluginOptions(plugin);
const plugins = requirePlugins(pluginOptions);
const plugins = await requirePlugins(pluginOptions);
const spinner = ora('Minifying images');

if (Buffer.isBuffer(input)) {
Expand Down Expand Up @@ -118,10 +128,9 @@ if (cli.input.length === 0 && process.stdin.isTTY) {
}

(async () => {
if (cli.input.length > 0) {
await run(cli.input, cli.flags);
} else {
await run(await getStdin.buffer(), cli.flags);
}
await run(
cli.input.length > 0
? cli.input
: await getStdin.buffer(),
cli.flags);
})();

33 changes: 18 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
"license": "MIT",
"repository": "imagemin/imagemin-cli",
"funding": "https://github.com/imagemin/imagemin-cli?sponsor=1",
"type": "module",
"bin": {
"imagemin": "cli.js"
},
"engines": {
"node": ">=10"
"node": ">=12.20"
},
"scripts": {
"test": "xo && ava"
Expand All @@ -31,30 +32,32 @@
"svg"
],
"dependencies": {
"arrify": "^2.0.1",
"get-stdin": "^8.0.0",
"imagemin": "^7.0.0",
"arrify": "^3.0.0",
"get-stdin": "^9.0.0",
"imagemin": "^8.0.0",
"lodash.pairs": "^3.0.1",
"meow": "^7.0.1",
"ora": "^4.0.3",
"meow": "^10.1.1",
"ora": "^5.4.1",
"plur": "^4.0.0",
"strip-indent": "^3.0.0"
"strip-indent": "^4.0.0"
},
"devDependencies": {
"ava": "^3.8.0",
"execa": "^4.0.0",
"imagemin-pngquant": "^8.0.0",
"xo": "^0.30.0"
"ava": "^3.15.0",
"execa": "^5.1.1",
"imagemin-pngquant": "^9.0.2",
"typescript": "^4.3.5",
"xo": "^0.43.0"
},
"optionalDependencies": {
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^6.0.0",
"imagemin-optipng": "^7.0.0",
"imagemin-svgo": "^7.0.0"
"imagemin-jpegtran": "^7.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-svgo": "^9.0.0"
},
"xo": {
"rules": {
"node/process-exit-as-throw": 2
"node/process-exit-as-throw": 2,
"node/no-unsupported-features": "off"
}
}
}
6 changes: 5 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ $ imagemin --help
$ imagemin foo.png > foo-optimized.png
$ cat foo.png | imagemin > foo-optimized.png
$ imagemin foo.png --plugin=pngquant > foo-optimized.png
$ imagemin foo.png --plugin.pngquant.quality={0.1,0.2} > foo-optimized.png
$ imagemin foo.png --plugin.pngquant.quality=0.5 --plugin.pngquant.quality=1 > foo-optimized.png
$ imagemin foo.png --plugin.webp.quality=95 --plugin.webp.preset=icon > foo-icon.webp
```

**non-Windows** users can also use the short CLI syntax for array arguments:
`--plugin.pngquant.quality={0.5,1}` equals
`--plugin.pngquant.quality=0.5 --plugin.pngquant.quality=1`

## Related

- [imagemin](https://github.com/imagemin/imagemin) - API for this module
36 changes: 21 additions & 15 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
const {promisify} = require('util');
const fs = require('fs');
const execa = require('execa');
const test = require('ava');
import {promisify} from 'node:util';
import fs from 'node:fs';
import {dirname} from 'node:path';
import {fileURLToPath} from 'node:url';
import process from 'node:process';

import execa from 'execa';
import test from 'ava';

const __dirname = dirname(fileURLToPath(import.meta.url));

process.chdir(__dirname);

const readFile = promisify(fs.readFile);

test('show version', async t => {
const {stdout} = await execa('./cli.js', ['--version']);
t.is(stdout, require('./package.json').version);
t.is(stdout, JSON.parse(await readFile('./package.json')).version);
});

test('optimize a GIF', async t => {
const input = await readFile('fixtures/test.gif');

const {stdout} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(stdout.length < input.length);
Expand All @@ -28,7 +34,7 @@ test('optimize a JPG', async t => {

const {stdout} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(stdout.length < input.length);
Expand All @@ -39,7 +45,7 @@ test('optimize a PNG', async t => {

const {stdout} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(stdout.length < input.length);
Expand All @@ -50,7 +56,7 @@ test('optimize a SVG', async t => {

const {stdout} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(stdout.length < input.length);
Expand All @@ -65,12 +71,12 @@ test('support plugins', async t => {

const {stdout: data} = await execa('./cli.js', ['--plugin=pngquant'], {
input,
encoding: 'buffer'
encoding: 'buffer',
});

const {stdout: compareData} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(data.length < compareData.length);
Expand All @@ -85,7 +91,7 @@ test('throw on missing plugins', async t => {
const input = await readFile('fixtures/test.png');
const error = await t.throwsAsync(execa('./cli.js', ['--plugin=unicorn'], {
input,
encoding: 'buffer'
encoding: 'buffer',
}));

t.regex(error.stderr.toString(), /Unknown plugin: unicorn/);
Expand All @@ -94,14 +100,14 @@ test('throw on missing plugins', async t => {
test('support plugin options', async t => {
const input = await readFile('fixtures/test.png');

const {stdout: data} = await execa('./cli.js', ['--plugin.pngquant.dithering=1'], {
const {stdout: data} = await execa('./cli.js', ['--plugin.pngquant.dithering=1', '--plugin.pngquant.quality=0.1', '--plugin.pngquant.quality=0.4'], {
input,
encoding: 'buffer'
encoding: 'buffer',
});

const {stdout: compareData} = await execa('./cli.js', {
input,
encoding: 'buffer'
encoding: 'buffer',
});

t.true(data.length < compareData.length);
Expand Down

0 comments on commit bcb0b34

Please sign in to comment.