paulcpederson / imagemin-newer

Minify images with imagemin only if they need to be updated
MIT License
6 stars 1 forks source link

Doesn't work with latest version on Imagemin #1

Open djforth opened 8 years ago

djforth commented 8 years ago

The syntax for Imagemin looks to have changed quite a lot (currently on v5.2.2) and also looks like the plugin structure has changed - https://github.com/imagemin/imagemin

So when I plug imagemin-newer into it, it's throwing the following error:

TypeError: a.apply(...).then is not a function

Think it be worth upgrading as this is quite useful plugin

paulcpederson commented 8 years ago

@djforth thanks for pointing this out, I'll look into this

paulcpederson commented 8 years ago

@djforth ok, I looked into this today. So here's an update:

Unfortunately the way they now implement plugins is completely different and they've unintentionally removed the ability for a plugin like this to exist.

Previously, plugins were basically just something to pipe a file stream through. So they could alter the stream in any way they wanted. You actually had to explicitly push the file into the stream for the next plugins to get it. So it was really easy to just not do that, and filter out old files.

Now, plugins are a function that return a function that returns a promise resolving to a modified Buffer, meaning that plugins only receive the buffer representation of the contents of the file and don't actually know any information about the file its self (ie. only the blob, and nothing like a filename).

Since it can't be a plugin now, I think the API that would make most sense would be to just act on the glob of filePaths before imagemin even gets involved. So something like:

var imagemin = require('imagemin')
var imageminMozjpeg = require('imagemin-mozjpeg')
var imageminPngquant = require('imagemin-pngquant')
var newer = require('imagemin-newer')
var dest = 'build/images'

newer(['images/*.{jpg,png}'], dest)
.then(function (images) {
  imagemin(images, dest, {
    plugins: [
        imageminMozjpeg(),
        imageminPngquant({quality: '65-80'})
    ]
  }).then(files => {
      console.log(files);
      //=> [{data: <Buffer 89 50 4e …>, path: 'build/images/foo.jpg'}, …]
  });
})

But that honestly seems a bit silly as that plugin really has nothing to do with imagemin, and should probably just exist as its own module. This module would only stick around for the CLI, which would basically just run the above code from the command line.

ghost commented 8 years ago

@paulcpederson Thanks for take a look into this. I tried your code above but I get TypeError: newer(...).then is not a function. Looks like it didn't return a promise. Any idea?

paulcpederson commented 8 years ago

@dotmagic the code above it pseudo code, not actually implemented yet. sorry to confuse 😬

djforth commented 8 years ago

Hi @paulcpederson.

Thanks for taking a look at it, ok so basically your wrapping imagemin and feeding it the list of images to process, rather than being directly a plugin.

Would make sense to remove it from imagemin association as looking at your proposed api you can then pass the image array to any image processor you wanted right?

Anyway that would work well for me. 👍

paulcpederson commented 8 years ago

Yeah, I agree. I think creating a new package called newer or something would work best. I'll probably add a deprecation notice to this package once a new one is ready.