Skip to content

Commit ce7ba8a

Browse files
ehrencronaAndreas Ehrencronawardpeet
authored
fix(gatsby-image): add required check for one of fluid or fixed (#25371)
* Do not crash the page if the image component is invoked without parameters * added a warning if missing fluid and fixed props * had swapped a condition * doing destructuring in function parameter list * now with functioning tree-shaking * updating function doc: returns undefined, not null * switching to proptypes for validation * Update packages/gatsby-image/src/index.js Co-authored-by: Andreas Ehrencrona <andreas@scholarsapp.com> Co-authored-by: Ward Peeters <ward@coding-tech.com>
1 parent a94e657 commit ce7ba8a

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

packages/gatsby-image/src/__tests__/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,18 @@ describe(`<Image />`, () => {
220220
expect(console.warn).toBeCalled()
221221
})
222222

223+
it(`should warn if missing both fixed and fluid props`, () => {
224+
jest.spyOn(global.console, `error`)
225+
226+
render(<Image fixed={null} />)
227+
228+
expect(console.error).toBeCalledWith(
229+
expect.stringContaining(
230+
`The prop \`fluid\` or \`fixed\` is marked as required`
231+
)
232+
)
233+
})
234+
223235
it(`should select the correct mocked image of fluid variants provided.`, () => {
224236
const tripleFluidImageShapeMock = fluidImagesShapeMock.concat({
225237
aspectRatio: 5,

packages/gatsby-image/src/index.js

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ const matchesMedia = ({ media }) =>
7171
* Find the source of an image to use as a key in the image cache.
7272
* Use `the first image in either `fixed` or `fluid`
7373
* @param {{fluid: {src: string, media?: string}[], fixed: {src: string, media?: string}[]}} args
74-
* @return {string}
74+
* @return {string?} Returns image src or undefined it not given.
7575
*/
76-
const getImageSrcKey = ({ fluid, fixed }) => {
77-
const data = fluid ? getCurrentSrcData(fluid) : getCurrentSrcData(fixed)
76+
const getImageCacheKey = ({ fluid, fixed }) => {
77+
const srcData = getCurrentSrcData(fluid || fixed || [])
7878

79-
return data.src
79+
return srcData && srcData.src
8080
}
8181

8282
/**
@@ -109,16 +109,20 @@ const getCurrentSrcData = currentData => {
109109
const imageCache = Object.create({})
110110
const inImageCache = props => {
111111
const convertedProps = convertProps(props)
112-
// Find src
113-
const src = getImageSrcKey(convertedProps)
114-
return imageCache[src] || false
112+
113+
const cacheKey = getImageCacheKey(convertedProps)
114+
115+
return imageCache[cacheKey] || false
115116
}
116117

117118
const activateCacheForImage = props => {
118119
const convertedProps = convertProps(props)
119-
// Find src
120-
const src = getImageSrcKey(convertedProps)
121-
imageCache[src] = true
120+
121+
const cacheKey = getImageCacheKey(convertedProps)
122+
123+
if (cacheKey) {
124+
imageCache[cacheKey] = true
125+
}
122126
}
123127

124128
// Native lazy-loading support: https://addyosmani.com/blog/lazy-loading/
@@ -723,15 +727,36 @@ const fluidObject = PropTypes.shape({
723727
maxHeight: PropTypes.number,
724728
})
725729

730+
function requireFixedOrFluid(originalPropTypes) {
731+
return (props, propName, componentName) => {
732+
if (!props.fixed && !props.fluid) {
733+
throw new Error(
734+
`The prop \`fluid\` or \`fixed\` is marked as required in \`${componentName}\`, but their values are both \`undefined\`.`
735+
)
736+
}
737+
738+
PropTypes.checkPropTypes(
739+
{ [propName]: originalPropTypes },
740+
props,
741+
`prop`,
742+
componentName
743+
)
744+
}
745+
}
746+
726747
// If you modify these propTypes, please don't forget to update following files as well:
727748
// https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-image/index.d.ts
728749
// https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-image/README.md#gatsby-image-props
729750
// https://github.com/gatsbyjs/gatsby/blob/master/docs/docs/gatsby-image.md#gatsby-image-props
730751
Image.propTypes = {
731752
resolutions: fixedObject,
732753
sizes: fluidObject,
733-
fixed: PropTypes.oneOfType([fixedObject, PropTypes.arrayOf(fixedObject)]),
734-
fluid: PropTypes.oneOfType([fluidObject, PropTypes.arrayOf(fluidObject)]),
754+
fixed: requireFixedOrFluid(
755+
PropTypes.oneOfType([fixedObject, PropTypes.arrayOf(fixedObject)])
756+
),
757+
fluid: requireFixedOrFluid(
758+
PropTypes.oneOfType([fluidObject, PropTypes.arrayOf(fluidObject)])
759+
),
735760
fadeIn: PropTypes.bool,
736761
durationFadeIn: PropTypes.number,
737762
title: PropTypes.string,

0 commit comments

Comments
 (0)