Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Last active October 30, 2020 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kentcdodds/0edaef72e6fd9d52ab9f3ec9da3c0b51 to your computer and use it in GitHub Desktop.
Save kentcdodds/0edaef72e6fd9d52ab9f3ec9da3c0b51 to your computer and use it in GitHub Desktop.
imagemin-in-place

imagemin-in-place

Problem: You want to use imagemin-cli but it requires you provide an output directory. But you just want to override the existing file with the optimized version.

Solution: This uses imagemin with the plugins to support compressing png, jpg, gif, svg, and webp files and it overrides the existing file.

npx https://gist.github.com/kentcdodds/0edaef72e6fd9d52ab9f3ec9da3c0b51 ./glob/to/files/**/*.png

Or if you just want to optimize all the files in your project you can run it with arguments:

npx https://gist.github.com/kentcdodds/0edaef72e6fd9d52ab9f3ec9da3c0b51

This will automatically ignore any files in your .gitignore if you have one (otherwise it'll fallback to a good default).

Warning: This does not save a backup of your files, so make sure you've got a backup in case you need to revert the changes.

#!/usr/bin/env node
const path = require('path')
const imagemin = require('imagemin')
const glob = require('glob')
const gitIgnoreGlob = require('gitignore-to-glob')
const util = require('util')
const fs = require('fs/promises')
let [, , ...files] = process.argv
;(async () => {
if (!files.length) {
let ignore = ['node_modules', 'dist', 'build']
try {
ignore = gitIgnoreGlob()
// get rid of "force include" things 🤷‍♂️
.filter((i) => i.startsWith('!'))
// swap from "exclude" to "include" because
// we want them included in the ignore
.map((i) => `!${i}`)
} catch {
// ignore the error
}
const globPattern = path.join(
process.cwd(),
'static/**/*.+(png|jpg|jpeg|gif|svg|webp)',
)
files = await util.promisify(glob)(globPattern, {ignore})
}
await Promise.all(
files.map(async (file) => {
const [result] = await imagemin([file], {
glob: false,
plugins: [
require('imagemin-jpegtran')(),
require('imagemin-pngquant')(),
require('imagemin-webp')(),
require('imagemin-svgo')(),
require('imagemin-gifsicle')(),
],
})
await fs.writeFile(result.sourcePath, result.data)
}),
)
console.log(`Finished processing ${files.length} files`)
})()
{
"name": "imagemin-in-place",
"version": "1.0.0",
"description": "This allows you to optimize images in place using imagemin",
"bin": "./bin.js",
"dependencies": {
"gitignore-to-glob": "^0.3.0",
"glob": "^7.1.6",
"imagemin": "^7.0.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-pngquant": "^9.0.1",
"imagemin-svgo": "^8.0.0",
"imagemin-webp": "^6.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment