Skip to content

Commit

Permalink
fix(gatsby-plugin-sharp): Fix defaults handling (#29564) (#29589)
Browse files Browse the repository at this point in the history
Co-authored-by: gatsbybot <mathews.kyle+gatsbybot@gmail.com>
(cherry picked from commit 107926a)
  • Loading branch information
ascorbic committed Feb 22, 2021
1 parent d1f303a commit be9d9f9
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 20 deletions.
16 changes: 14 additions & 2 deletions packages/gatsby-plugin-sharp/README.md
Expand Up @@ -30,18 +30,30 @@ plugins: [
{
resolve: `gatsby-plugin-sharp`,
options: {
// Available options and their defaults:
// Defaults used for gatsbyImageData and StaticImage
defaults: {},
// Set to false to allow builds to continue on image errors
failOnError: true,
// deprecated options and their defaults:
base64Width: 20,
forceBase64Format: ``, // valid formats: png,jpg,webp
useMozJpeg: process.env.GATSBY_JPEG_ENCODER === `MOZJPEG`,
stripMetadata: true,
defaultQuality: 50,
failOnError: true,
},
},
]
```

## Options

- `defaults`: default values used for `gatsbyImageData` and `StaticImage` from [gatsby-plugin-image](https://www.gatsbyjs.com/plugins/gatsby-plugin-image).
Available options are: `formats`,`placeholder`,`quality`,`breakpoints`,`backgroundColor`,`tracedSVGOptions`,`blurredOptions`,`jpgOptions`,`pngOptions`,`webpOptions`,`avifOptions`.
For details of these, see [the reference guide](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image).
- `failOnError`: default = `true`. By default builds will fail if there is a corrupted image. Set to false to continue the build on error. The image will return `undefined`.

Other options are deprecated, and should only be used for the legacy `fixed` and `fluid` functions.

## Methods

### resize
Expand Down
90 changes: 75 additions & 15 deletions packages/gatsby-plugin-sharp/src/__tests__/plugin-options.ts
@@ -1,5 +1,20 @@
import { testPluginOptionsSchema } from "gatsby-plugin-utils"
import { pluginOptionsSchema } from "../../gatsby-node"
import { doMergeDefaults } from "../plugin-options"

const defaults = {
formats: [`auto`, `webp`],
placeholder: `dominantColor`,
quality: 50,
breakpoints: [100, 200],
backgroundColor: `rebeccapurple`,
tracedSVGOptions: {},
blurredOptions: { quality: 20 },
jpgOptions: { quality: 20 },
pngOptions: { quality: 20 },
webpOptions: { quality: 20 },
avifOptions: { quality: 20 },
}

describe(`pluginOptionsSchema`, () => {
it(`should reject incorrect options`, async () => {
Expand Down Expand Up @@ -40,25 +55,70 @@ describe(`pluginOptionsSchema`, () => {
})

it(`should accept correct options`, async () => {
const options = {
defaults: {
formats: [`auto`, `webp`],
placeholder: `dominantColor`,
quality: 50,
breakpoints: [100, 200],
backgroundColor: `rebeccapurple`,
tracedSVGOptions: {},
blurredOptions: { quality: 20 },
jpgOptions: { quality: 20 },
pngOptions: { quality: 20 },
webpOptions: { quality: 20 },
avifOptions: { quality: 20 },
},
}
const options = { defaults }
const { isValid } = await testPluginOptionsSchema(
pluginOptionsSchema,
options
)
expect(isValid).toBe(true)
})
})

describe(`plugin defaults`, () => {
it(`uses defaults`, () => {
const output = doMergeDefaults({}, defaults)
expect(output).toMatchInlineSnapshot(`
Object {
"avifOptions": Object {
"quality": 20,
},
"backgroundColor": "rebeccapurple",
"blurredOptions": Object {
"quality": 20,
},
"breakpoints": Array [
100,
200,
],
"formats": Array [
"auto",
"webp",
],
"jpgOptions": Object {
"quality": 20,
},
"placeholder": "dominantColor",
"pngOptions": Object {
"quality": 20,
},
"quality": 50,
"tracedSVGOptions": Object {},
"webpOptions": Object {
"quality": 20,
},
}
`)
})

it(`allows overrides`, () => {
const output = doMergeDefaults({ backgroundColor: `papayawhip` }, defaults)
expect(output.backgroundColor).toEqual(`papayawhip`)
expect(output.quality).toEqual(50)
})

it(`allows overrides of arrays`, () => {
const output = doMergeDefaults({ formats: [`auto`, `avif`] }, defaults)
expect(output.formats).toEqual([`auto`, `avif`])
expect(output.breakpoints).toEqual([100, 200])
})

it(`allows override of deep objects`, () => {
const output = doMergeDefaults({ avifOptions: { quality: 50 } }, defaults)
expect(output.avifOptions).toEqual({ quality: 50 })
})

it(`allows extra keys in objects`, () => {
const output = doMergeDefaults({ avifOptions: { speed: 50 } }, defaults)
expect(output.avifOptions).toEqual({ quality: 20, speed: 50 })
})
})
12 changes: 9 additions & 3 deletions packages/gatsby-plugin-sharp/src/plugin-options.js
Expand Up @@ -74,14 +74,20 @@ exports.createTransformObject = args => {
/**
* Used for gatsbyImageData and StaticImage only
*/
exports.mergeDefaults = args => {
const { defaults } = pluginOptions
exports.mergeDefaults = args => doMergeDefaults(args, pluginOptions.defaults)

const customizer = (objValue, srcValue) =>
Array.isArray(objValue) ? srcValue : undefined

function doMergeDefaults(args, defaults) {
if (!defaults) {
return args
}
return _.defaultsDeep(args, defaults)
return _.mergeWith({}, defaults, args, customizer)
}

exports.doMergeDefaults = doMergeDefaults

exports.healOptions = (
{ defaultQuality: quality, base64Width },
args,
Expand Down

0 comments on commit be9d9f9

Please sign in to comment.