Imagemin plugin for Webpack
This is a simple plugin that uses Imagemin to compress all images in your project.
Install
npm install imagemin-webpack-plugin
Requires node >=4.0.0
Example Usage
var ImageminPlugin = require('imagemin-webpack-plugin').default
// Or if using ES2015:
// import ImageminPlugin from 'imagemin-webpack-plugin'
module.exports = {
plugins: [
// Make sure that the plugin is after any plugins that add images
new ImageminPlugin({
disable: process.env.NODE_ENV !== 'production', // Disable during development
pngquant: {
quality: '95-100'
}
})
]
}
Working with copy-webpack-plugin:
module.exports = {
plugins: [
// Copy the images folder and optimize all the images
new CopyWebpackPlugin([{
from: 'images/'
}]),
new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i })
]
}
API
new ImageminPlugin(options)
options.disable
type: Boolean
default: false
When set to true
it will disable the plugin entirely. This is useful for disabling the plugin during development, and only enabling it during production
options.test
type: RegExp
or String
or Array
default: /.*/
This plugin will only run on files that match this test. This is similar to the webpack loader test
option (but is not using the same implementation, so there might be major differences!). This can either be a RegExp object, or a minimatch glob (or an array of either or both).
This can allow you to only run the plugin on specific files, or even include the plugin multiple times for different sets of images and apply different imagemin settings to each.
Example:
import ImageminPlugin from 'imagemin-webpack-plugin'
module.exports = {
plugins: [
// Use the default settings for everything in /images/*
new ImageminPlugin({ test: 'images/**' }),
// bump up the optimization level for all the files in my `bigpngs` directory
new ImageminPlugin({
test: 'bigpngs/**',
optipng: {
optimizationLevel: 9
}
})
]
}
Note the order of the plugins matters. CopyWebpackPlugin
must be before ImageminWebpackPlugin
in the plugins
array.
options.maxConcurrency
type: Number
default: the number of logical CPUS on the system
Sets the maximum number of instances of Imagemin that can run at once. Set to Infinity
to run a seperate process per image all at the same time.
options.optipng
type: Object
or null
default: { optimizationLevel: 3 }
Passes the given object to imagemin-optipng
. Set to null
to disable optipng.
options.gifsicle
type: Object
or null
default: { optimizationLevel: 1 }
Passes the given object to imagemin-gifsicle
. Set to null
to disable gifsicle.
options.jpegtran
type: Object
or null
default: { progressive: false }
Passes the given object to imagemin-jpegtran
. Set to null
to disable jpegtran.
options.svgo
type: Object
or null
default: {}
Passes the given object to imagemin-svgo
. Set to null
to disable svgo.
options.pngquant
type: Object
or null
default: null
Passes the given object to imagemin-pngquant
. Disabled by default.
options.plugins
type: Array
default: []
Include any additional plugins that you want to work with imagemin here. By default the above are included, but if you want (or need to) you can disable them (by setting them to null
) and include them yourself here.
A list of possible imagemin plugins can be found here.
Example:
import ImageminPlugin from 'imagemin-webpack-plugin'
import imageminMozjpeg from 'imagemin-mozjpeg'
module.exports = {
plugins: [
new ImageminPlugin({
plugins: [
imageminMozjpeg({
quality: 100,
progressive: true
})
]
})
]
}
options.externalImages
type: Object
default: { sources: [], destination: null }
Include any external images (those not included in webpack's compilation assets) that you want to be parsed by imagemin. If a destination value is not supplied the files are optimized in place. You can optionally set either of these to a function which will be invoked at the last possible second before optimization to grab files that might not exist at the time of writing the config (see #37 for more info).
Example:
import ImageminPlugin from 'imagemin-webpack-plugin'
import glob from 'glob'
module.exports = {
plugins: [
new ImageminPlugin({
externalImages: {
sources: glob.sync('src/images/**/*.png'),
destination: 'src/public/images'
}
})
]
}
options.minFileSize
type: Integer
default: 0
Only apply to images that are larger than this value in bytes.
options.maxFileSize
type: Integer
default: Infinity
Only apply to images that are smaller than or equal-to this value in bytes.
This and minFileSize
together can be used to include WebpackImageminPlugin multiple times with multiple configs on different file sizes.
Example:
import ImageminPlugin from 'imagemin-webpack-plugin'
import glob from 'glob'
module.exports = {
plugins: [
new ImageminPlugin({
maxFileSize: 10000, // Only apply this one to files equal to or under 10kb
jpegtran: { progressive: false }
}),
new ImageminPlugin({
minFileSize: 10000, // Only apply this one to files over 10kb
jpegtran: { progressive: true }
})
]
}
Troubleshooting
If you get an error similar to Error in parsing SVG: Unquoted attribute value
while using SVGO, you most likely have un-quoted attributes in the SVG image. A workaround can be found here from @vzaidman. They also made an issue upstream which should fix it at the source here.
FAQ
Why?
I was suprised that there weren't any Imagemin plugins for webpack, so I made one!
Why not use image-webpack-loader
?
Because I had other things like the favicons-webpack-plugin
and responsive-loader
that were generating images that I couldn't have image-webpack-loader
optimize. This plugin will optimize ANY images regardless of how they were added to webpack. Plus image-webpack-loader
is currently using an older version of imagemin.
Can you add this new feature?
Maybe... I'm trying to keep this a small single-purpose plugin, but if you want a feature feel free to open an issue and I'll take a look.
Inspiration
- Big thanks to
image-webpack-loader
for the idea. - Used
compression-webpack-plugin
to learn how to write the plugin. It's source code is a better tutorial on how to write plugins than the webpack documentation is...
Contributing
The code is written in ES6 using Javascript Standard Style. Feel free to make PRs adding features you want, but please try to follow Standard. Also, codumentation/readme PRs are more then welcome!
License
MIT Copyright (c) Gregory Benner