0

I am trying to write a simple node script to resize large files (intended to be as a solution to an issue with large portrait oriented files). The main part of the code comes directly from gatsby docs.

module.exports = optimizeImages = () => {
  const sharp = require(`sharp`)
  const glob = require(`glob`)
  const matches = glob.sync(`src/images/**/*!(optimized).{png,jpg,jpeg}`) // <-- There is the problem
  console.log('matches:', matches)
  const MAX_WIDTH = 1800
  const QUALITY = 70
  Promise.all(
    matches.map(async match => {
      const stream = sharp(match)
      const info = await stream.metadata()
      if (info.width < MAX_WIDTH) {
        return
      }
      const optimizedName = match.replace(
        /(\..+)$/,
        (match, ext) => `-optimized${ext}`
      )
      await stream
        .resize(MAX_WIDTH)
        .jpeg({ quality: QUALITY })
        .toFile(optimizedName)
        .then(newFile => console.log(newFile))
        .catch(error => console.log(error))
      return true
    })
  )
}

The code seems to be working as intended, BUT I can't figure out how to unmatch the filenames which are allready optimized. Their names should end with '-optimized' suffix.

  • src/images/foo.jpg should be proccessed
  • src/images/bar-optimized.jpg should be ignored

I've tried to use the pattern src/images/**/*!(optimized).{png,jpg,jpeg}, but this does not work. I've tried using {ignore: 'src/images/**/*!(optimized)'}, but that does not work either.

Any help would be greatly appreciated.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
HynekS
  • 2,738
  • 1
  • 19
  • 34

2 Answers2

2

It turns out that this works as intended:

const matches = glob.sync(`src/images/**/*.{png,jpg,jpeg}`, {
  ignore: ['src/images/**/*-optimized.*']
})

Important clues were found in answers to this question.

HynekS
  • 2,738
  • 1
  • 19
  • 34
0

Ran across this answer when I had a sync glob issue and realized you could take it a step further with D.R.Y. and build it as a re-usable glob with something like:

import path from 'path'
import glob from 'glob'

export const globFiles = (dirPath, match, exclusion = []) => {
  const arr = exclusion.map(e => path.join(dirPath, e))
  return glob.sync(path.join(dirPath, match), {
    ignore: arr,
  })
}

From the code above it would be called as:

const fileArray = globFiles('src/images/**/','*.{png,jpg,jpeg}', ['*-optimized.*'])
DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127