diff --git a/packages/gatsby-plugin-sharp/README.md b/packages/gatsby-plugin-sharp/README.md index 71c2ee80513fe..572430ff20311 100644 --- a/packages/gatsby-plugin-sharp/README.md +++ b/packages/gatsby-plugin-sharp/README.md @@ -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 diff --git a/packages/gatsby-plugin-sharp/src/__tests__/plugin-options.ts b/packages/gatsby-plugin-sharp/src/__tests__/plugin-options.ts index 39826017dec26..e9d74afa5fcf5 100644 --- a/packages/gatsby-plugin-sharp/src/__tests__/plugin-options.ts +++ b/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 () => { @@ -40,21 +55,7 @@ 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 @@ -62,3 +63,62 @@ describe(`pluginOptionsSchema`, () => { 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 }) + }) +}) diff --git a/packages/gatsby-plugin-sharp/src/plugin-options.js b/packages/gatsby-plugin-sharp/src/plugin-options.js index 92195c779d8a4..7e4c6c8f36db2 100644 --- a/packages/gatsby-plugin-sharp/src/plugin-options.js +++ b/packages/gatsby-plugin-sharp/src/plugin-options.js @@ -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,