-
Notifications
You must be signed in to change notification settings - Fork 62
/
cli.js
executable file
·137 lines (116 loc) · 3.06 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env node
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';
import {isUint8Array} from 'uint8array-extras';
const cli = meow(`
Usage
$ imagemin <path|glob> ... --out-dir=build [--plugin=<name> ...]
$ imagemin <file> > <output>
$ cat <file> | imagemin > <output>
Options
--plugin, -p Override the default plugins
--out-dir, -o Output directory
Examples
$ imagemin images/* --out-dir=build
$ 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 --plugin.pngquant.quality=0.2 > foo-optimized.png
# Non-Windows platforms may support the short CLI syntax for array arguments
$ 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',
shortFlag: 'p',
isMultiple: true,
default: [
'gifsicle',
'jpegtran',
'optipng',
'svgo',
],
},
outDir: {
type: 'string',
shortFlag: 'o',
},
},
});
const requirePlugins = plugins => Promise.all(plugins.map(async ([plugin, options]) => {
try {
const {default: _plugin} = await import(`imagemin-${plugin}`);
return _plugin(options);
} catch {
console.error(stripIndent(`
Unknown plugin: ${plugin}
Did you forget to install the plugin?
You can install it with:
$ npm install -g imagemin-${plugin}
`).trim());
process.exit(1);
}
}));
const normalizePluginOptions = plugin => {
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 = await requirePlugins(pluginOptions);
const spinner = ora('Minifying images');
if (isUint8Array(input)) {
process.stdout.write(await imagemin.buffer(input, {plugins}));
return;
}
if (outDir) {
spinner.start();
}
let files;
try {
files = await imagemin(input, {destination: outDir, plugins});
} catch (error) {
spinner.stop();
throw error;
}
if (!outDir && files.length === 0) {
return;
}
if (!outDir && files.length > 1) {
console.error('Cannot write multiple files to stdout, specify `--out-dir`');
process.exit(1);
}
if (!outDir) {
process.stdout.write(files[0].data);
return;
}
spinner.stop();
console.log(`${files.length} ${plur('image', files.length)} minified`);
};
if (cli.input.length === 0 && process.stdin.isTTY) {
console.error('Specify at least one file path');
process.exit(1);
}
await run(
cli.input.length > 0
? cli.input
: await getStdin.buffer(),
cli.flags,
);