Skip to content

Commit

Permalink
Bump imagemin version (#166)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevva authored and sindresorhus committed May 6, 2016
1 parent b1af3cc commit 623d6b6
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 135 deletions.
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@ insert_final_newline = true
[{package.json,*.yml}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* text=auto
*.js text eol=lf
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
sudo: false
language: node_js
node_js:
- '5'
- '6'
- '4'
- '0.12'
116 changes: 61 additions & 55 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
'use strict';
var path = require('path');
var gutil = require('gulp-util');
var through = require('through2-concurrent');
var assign = require('object-assign');
var prettyBytes = require('pretty-bytes');
var chalk = require('chalk');
var Imagemin = require('imagemin');
var plur = require('plur');

module.exports = function (opts) {
opts = assign({
const path = require('path');
const gutil = require('gulp-util');
const through = require('through2-concurrent');
const prettyBytes = require('pretty-bytes');
const chalk = require('chalk');
const imagemin = require('imagemin');
const imageminGifsicle = require('imagemin-gifsicle');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminOptipng = require('imagemin-optipng');
const imageminSvgo = require('imagemin-svgo');
const plur = require('plur');

module.exports = (plugins, opts) => {
if (typeof plugins === 'object' && !Array.isArray(plugins)) {
opts = plugins;
plugins = null;
}

opts = Object.assign({
// TODO: remove this when gulp get's a real logger with levels
verbose: process.argv.indexOf('--verbose') !== -1
}, opts);

var totalBytes = 0;
var totalSavedBytes = 0;
var totalFiles = 0;
var validExts = ['.jpg', '.jpeg', '.png', '.gif', '.svg'];
const validExts = ['.jpg', '.jpeg', '.png', '.gif', '.svg'];

let totalBytes = 0;
let totalSavedBytes = 0;
let totalFiles = 0;

return through.obj(function (file, enc, cb) {
return through.obj((file, enc, cb) => {
if (file.isNull()) {
cb(null, file);
return;
Expand All @@ -32,60 +41,57 @@ module.exports = function (opts) {

if (validExts.indexOf(path.extname(file.path).toLowerCase()) === -1) {
if (opts.verbose) {
gutil.log('gulp-imagemin: Skipping unsupported image ' + chalk.blue(file.relative));
gutil.log(`gulp-imagemin: Skipping unsupported image ${chalk.blue(file.relative)}`);
}

cb(null, file);
return;
}

var imagemin = new Imagemin()
.src(file.contents)
.use(Imagemin.gifsicle({interlaced: opts.interlaced}))
.use(Imagemin.jpegtran({progressive: opts.progressive}))
.use(Imagemin.optipng({optimizationLevel: opts.optimizationLevel}))
.use(Imagemin.svgo({
plugins: opts.svgoPlugins || [],
multipass: opts.multipass
}));

if (opts.use) {
opts.use.forEach(imagemin.use.bind(imagemin));
}

imagemin.run(function (err, files) {
if (err) {
cb(new gutil.PluginError('gulp-imagemin:', err, {fileName: file.path}));
return;
}
const use = plugins || [
imageminGifsicle(),
imageminMozjpeg(),
imageminOptipng({optimizationLevel: 3}),
imageminSvgo({multipass: true})
];

var originalSize = file.contents.length;
var optimizedSize = files[0].contents.length;
var saved = originalSize - optimizedSize;
var percent = originalSize > 0 ? (saved / originalSize) * 100 : 0;
var savedMsg = 'saved ' + prettyBytes(saved) + ' - ' + percent.toFixed(1).replace(/\.0$/, '') + '%';
var msg = saved > 0 ? savedMsg : 'already optimized';
imagemin.buffer(file.contents, {use})
.then(data => {
const originalSize = file.contents.length;
const optimizedSize = data.length;
const saved = originalSize - optimizedSize;
const percent = originalSize > 0 ? (saved / originalSize) * 100 : 0;
const savedMsg = `saved ${prettyBytes(saved)} - ${percent.toFixed(1).replace(/\.0$/, '')}%`;
const msg = saved > 0 ? savedMsg : 'already optimized';

totalBytes += originalSize;
totalSavedBytes += saved;
totalFiles++;
totalBytes += originalSize;
totalSavedBytes += saved;
totalFiles++;

if (opts.verbose) {
gutil.log('gulp-imagemin:', chalk.green('✔ ') + file.relative + chalk.gray(' (' + msg + ')'));
}
if (opts.verbose) {
gutil.log('gulp-imagemin:', chalk.green('✔ ') + file.relative + chalk.gray(` (${msg})`));
}

file.contents = files[0].contents;
cb(null, file);
});
}, function (cb) {
var percent = totalBytes > 0 ? (totalSavedBytes / totalBytes) * 100 : 0;
var msg = 'Minified ' + totalFiles + ' ' + plur('image', totalFiles);
file.contents = data;
cb(null, file);
})
.catch(err => {
cb(new gutil.PluginError('gulp-imagemin:', err, {fileName: file.path}));
});
}, cb => {
const percent = totalBytes > 0 ? (totalSavedBytes / totalBytes) * 100 : 0;
let msg = `Minified ${totalFiles} ${plur('image', totalFiles)}`;

if (totalFiles > 0) {
msg += chalk.gray(' (saved ' + prettyBytes(totalSavedBytes) + ' - ' + percent.toFixed(1).replace(/\.0$/, '') + '%)');
msg += chalk.gray(` (saved ${prettyBytes(totalSavedBytes)} - ${percent.toFixed(1).replace(/\.0$/, '')}%)`);
}

gutil.log('gulp-imagemin:', msg);
cb();
});
};

module.exports.gifsicle = imageminGifsicle;
module.exports.mozjpeg = imageminMozjpeg;
module.exports.optipng = imageminOptipng;
module.exports.svgo = imageminSvgo;
16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"url": "sindresorhus.com"
},
"engines": {
"node": ">=0.10.0"
"node": ">=4"
},
"scripts": {
"test": "xo && ava"
Expand All @@ -37,17 +37,25 @@
"dependencies": {
"chalk": "^1.0.0",
"gulp-util": "^3.0.0",
"imagemin": "^4.0.0",
"object-assign": "^4.0.1",
"imagemin": "^5.0.0",
"plur": "^2.0.0",
"pretty-bytes": "^2.0.1",
"through2-concurrent": "^1.1.0"
},
"devDependencies": {
"ava": "*",
"get-stream": "^2.1.0",
"imagemin-pngquant": "^4.1.0",
"imagemin-pngquant": "^5.0.0",
"pify": "^2.3.0",
"xo": "*"
},
"optionalDependencies": {
"imagemin-gifsicle": "^5.0.0",
"imagemin-mozjpeg": "^6.0.0",
"imagemin-optipng": "^5.0.0",
"imagemin-svgo": "^5.0.1"
},
"xo": {
"esnext": true
}
}
84 changes: 17 additions & 67 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# gulp-imagemin [![Build Status](https://travis-ci.org/sindresorhus/gulp-imagemin.svg?branch=master)](https://travis-ci.org/sindresorhus/gulp-imagemin)

> Minify PNG, JPEG, GIF and SVG images with [imagemin](https://github.com/kevva/imagemin)
> Minify PNG, JPEG, GIF and SVG images with [imagemin](https://github.com/imagemin/imagemin)
*Issues with the output should be reported on the imagemin [issue tracker](https://github.com/kevva/imagemin/issues).*
*Issues with the output should be reported on the imagemin [issue tracker](https://github.com/imagemin/imagemin/issues).*


## Install
Expand All @@ -17,18 +17,10 @@ $ npm install --save-dev gulp-imagemin
```js
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const pngquant = require('imagemin-pngquant'); // $ npm i -D imagemin-pngquant

gulp.task('default', () => {
return gulp.src('src/images/*')
.pipe(imagemin({
progressive: true,
svgoPlugins: [
{removeViewBox: false},
{cleanupIDs: false}
],
use: [pngquant()]
}))
.pipe(imagemin())
.pipe(gulp.dest('dist/images'));
});
```
Expand All @@ -38,74 +30,32 @@ gulp.task('default', () => {

Comes bundled with the following **lossless** optimizers:

- [gifsicle](https://github.com/kevva/imagemin-gifsicle)*Compress GIF images*
- [jpegtran](https://github.com/kevva/imagemin-jpegtran)*Compress JPEG images*
- [optipng](https://github.com/kevva/imagemin-optipng)*Compress PNG images*
- [svgo](https://github.com/kevva/imagemin-svgo)*Compress SVG images*
- [gifsicle](https://github.com/imagemin/imagemin-gifsicle)*Compress GIF images*
- [mozjpeg](https://github.com/imagemin/imagemin-mozjpeg)*Compress JPEG images*
- [optipng](https://github.com/imagemin/imagemin-optipng)*Compress PNG images*
- [svgo](https://github.com/imagemin/imagemin-svgo)*Compress SVG images*

### imagemin([options])
### imagemin([plugins], [options])

Unsupported files are ignored.

#### options

Options are applied to the correct files.

##### optimizationLevel *(png)*

Type: `number`
Default: `3`

Select an optimization level between `0` and `7`.

> The optimization level 0 enables a set of optimization operations that require minimal effort. There will be no changes to image attributes like bit depth or color type, and no recompression of existing IDAT datastreams. The optimization level 1 enables a single IDAT compression trial. The trial chosen is what. OptiPNG thinks it’s probably the most effective. The optimization levels 2 and higher enable multiple IDAT compression trials; the higher the level, the more trials.
Level and trials:

1. 1 trial
2. 8 trials
3. 16 trials
4. 24 trials
5. 48 trials
6. 120 trials
7. 240 trials

##### progressive *(jpg)*

Type: `boolean`
Default: `false`

Lossless conversion to progressive.
#### plugins

##### interlaced *(gif)*
Type: `array`<br>
Default: `[imagemin.gifsicle(), imagemin.mozjpeg(), imagemin.optipng({optimizationLevel: 3}), imagemin.svgo({multipass: true})]`

Type: `boolean`
Default: `false`
[Plugins](https://www.npmjs.com/browse/keyword/imageminplugin) to use with imagemin. This will overwrite the default plugins. Note that the default plugins comes with good default options and should be sufficient in most cases.

Interlace gif for progressive rendering.
#### options

##### multipass *(svg)*
##### verbose

Type: `boolean`
Type: `boolean`<br>
Default: `false`

Optimize svg multiple times until it's fully optimized.

##### svgoPlugins *(svg)*

Type: `array`
Default: `[]`

Customize which SVGO plugins to use. [More here](https://github.com/sindresorhus/grunt-svgmin#available-optionsplugins).

##### use

Type: `array`
Default: `null`

Additional [plugins](https://www.npmjs.com/browse/keyword/imageminplugin) to use with imagemin.
Output more detailed information.


## License

MIT © [Sindre Sorhus](http://sindresorhus.com)
MIT © [Sindre Sorhus](https://sindresorhus.com)
8 changes: 4 additions & 4 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import m from './';

const fsP = pify(fs);

const createFixture = async opts => {
const createFixture = async plugins => {
const buf = await fsP.readFile('fixture.png');
const stream = m(opts);
const stream = m(plugins);

stream.end(new gutil.File({
path: path.join(__dirname, 'fixture.png'),
Expand All @@ -22,14 +22,14 @@ const createFixture = async opts => {
};

test('minify images', async t => {
const {buf, stream} = await createFixture({optimizationLevel: 0});
const {buf, stream} = await createFixture();
const file = await getStream.array(stream);

t.true(file[0].contents.length < buf.length);
});

test('use custom plugins', async t => {
const {stream} = await createFixture({use: [imageminPngquant()]});
const {stream} = await createFixture([imageminPngquant()]);
const compareStream = (await createFixture()).stream;
const file = await getStream.array(stream);
const compareFile = await getStream.array(compareStream);
Expand Down

0 comments on commit 623d6b6

Please sign in to comment.