-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support next/image component in Next.js 12/13 properly
- Loading branch information
1 parent
4c4f502
commit 2d30461
Showing
9 changed files
with
307 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,67 @@ | ||
/* eslint-disable no-underscore-dangle, @typescript-eslint/no-non-null-assertion */ | ||
import * as React from 'react'; | ||
import type * as _NextImage from 'next/image'; | ||
import type * as _NextLegacyImage from 'next/legacy/image'; | ||
import semver from 'semver'; | ||
|
||
// next v9 (doesn't have next/image) | ||
if (semver.gt(process.env.__NEXT_VERSION!, '9.0.0')) { | ||
const NextImage = require('next/image') as typeof _NextImage; | ||
const defaultLoader = ({ src, width, quality }: _NextImage.ImageLoaderProps) => { | ||
const missingValues = []; | ||
if (!src) { | ||
missingValues.push('src'); | ||
} | ||
|
||
if (!width) { | ||
missingValues.push('width'); | ||
} | ||
|
||
if (missingValues.length > 0) { | ||
throw new Error( | ||
`Next Image Optimization requires ${missingValues.join( | ||
', ' | ||
)} to be provided. Make sure you pass them as props to the \`next/image\` component. Received: ${JSON.stringify( | ||
{ | ||
src, | ||
width, | ||
quality, | ||
} | ||
)}` | ||
); | ||
} | ||
|
||
return `${src}?w=${width}&q=${quality ?? 75}`; | ||
}; | ||
|
||
const NextImage = require('next/image') as typeof _NextImage; | ||
|
||
const OriginalNextImage = NextImage.default; | ||
const OriginalNextImage = NextImage.default; | ||
|
||
Object.defineProperty(NextImage, 'default', { | ||
Object.defineProperty(NextImage, 'default', { | ||
configurable: true, | ||
value: (props: _NextImage.ImageProps) => { | ||
return <OriginalNextImage {...props} loader={props.loader ?? defaultLoader} />; | ||
}, | ||
}); | ||
|
||
if (semver.satisfies(process.env.__NEXT_VERSION!, '^13.0.0')) { | ||
const LegacyNextImage = require('next/legacy/image') as typeof _NextLegacyImage; | ||
const OriginalNextLegacyImage = LegacyNextImage.default; | ||
|
||
Object.defineProperty(OriginalNextLegacyImage, 'default', { | ||
configurable: true, | ||
value: (props: _NextImage.ImageProps) => | ||
typeof props.src === 'string' ? ( | ||
<OriginalNextImage {...props} unoptimized blurDataURL={props.src} /> | ||
) : ( | ||
<OriginalNextImage {...props} unoptimized /> | ||
), | ||
value: (props: _NextLegacyImage.ImageProps) => ( | ||
<OriginalNextLegacyImage {...props} loader={props.loader ?? defaultLoader} /> | ||
), | ||
}); | ||
} | ||
|
||
// https://github.com/vercel/next.js/issues/36417#issuecomment-1117360509 | ||
if ( | ||
semver.gte(process.env.__NEXT_VERSION!, '12.1.5') && | ||
semver.lt(process.env.__NEXT_VERSION!, '12.2.0') | ||
) { | ||
Object.defineProperty(NextImage, '__esModule', { | ||
configurable: true, | ||
value: true, | ||
}); | ||
} | ||
if (semver.satisfies(process.env.__NEXT_VERSION!, '^12.0.0')) { | ||
const NextFutureImage = require('next/future/image') as typeof _NextImage; | ||
const OriginalNextFutureImage = NextFutureImage.default; | ||
|
||
Object.defineProperty(OriginalNextFutureImage, 'default', { | ||
configurable: true, | ||
value: (props: _NextImage.ImageProps) => ( | ||
<OriginalNextFutureImage {...props} loader={props.loader ?? defaultLoader} /> | ||
), | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { Configuration as WebpackConfig } from 'webpack'; | ||
import semver from 'semver'; | ||
import { IgnorePlugin } from 'webpack'; | ||
import { getNextjsVersion } from '../utils'; | ||
|
||
export function configureNextImport(baseConfig: WebpackConfig) { | ||
const nextJSVersion = getNextjsVersion(); | ||
|
||
const isNext12 = semver.satisfies(nextJSVersion, '~12'); | ||
const isNext13 = semver.satisfies(nextJSVersion, '~13'); | ||
|
||
baseConfig.plugins = baseConfig.plugins ?? []; | ||
|
||
if (!isNext13) { | ||
baseConfig.plugins.push( | ||
new IgnorePlugin({ | ||
resourceRegExp: /next\/legacy\/image$/, | ||
}) | ||
); | ||
} | ||
|
||
if (!isNext12) { | ||
baseConfig.plugins.push( | ||
new IgnorePlugin({ | ||
resourceRegExp: /next\/future\/image$/, | ||
}) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
code/frameworks/nextjs/template/stories_12-js/ImageFuture.stories.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import React from 'react'; | ||
import Image from 'next/future/image'; | ||
// eslint-disable-next-line import/extensions | ||
import StackAlt from '../../assets/colors.svg'; | ||
|
||
export default { | ||
component: Image, | ||
args: { | ||
src: StackAlt, | ||
alt: 'Stack Alt', | ||
}, | ||
}; | ||
|
||
export const Default = {}; | ||
|
||
export const BlurredPlaceholder = { | ||
args: { | ||
placeholder: 'blur', | ||
}, | ||
}; | ||
|
||
export const BlurredAbsolutePlaceholder = { | ||
args: { | ||
src: 'https://via.placeholder.com/100', | ||
width: 100, | ||
height: 100, | ||
blurDataURL: | ||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABP5JREFUWEeNlwtz2zgMhEGKsv/k9XFp82xe11763yOJVGcXC4m2czM3GYa0E2s/LACSTi+vv1czM/7CvPpqxY/ejPeS3khmFiPHOiVLHKaZi4ux4j18GpMlS6cALupEQBCKQM4BdnGzjIcJgs//QBxAPQAem55f3yL4PWJIdyCyhlMfPdYZot0cwj3Ayg/5JwHA13paen7pADphxr/n5VI8JQsHCCGQ3gVGLLsxQ3h/LYSn5383B05rwNOws3Z576LOTOduvwfrOd5FtVat4akx0uPTrw8BNuUz23vLsY7hmg7i4ipqM2saiAdruNuirh4ff0bNdb3Qy3vkvfAQwrkHoDxTTZtDCOKrC1bMEkdnsQh/PLyetOGHkXeRAgQAQ84efQcBdUhvFofoulpdm9WGGTA+AJEe7l+i37a2c371tCFKs5zzJjxQNBMi1im7OCudP2aNghJuzZaGdSMEZjpwf/t0UgNdg9DOyLGLnY0BUHlzwVtNDkgEQhBeKkb1tUDgQrq7frwAiIJi5BKAeIFgHk5mOpPzvgltOfcoK0Rrs7lWHwsgqtXarK3N0u23h5Ne8+3Cqxn5RYSMfHCAMgDAx4CBWlA9RAGw0GA/ol0gvFB4WjAvBAFUa83SzdUdAbYMqp28uHpxCRefxwAYhksAFBlthxCiXig+zT4TYqkC+Hq7OdAfJv8lPpZiZShWBBIuRP+jspDb2lwcDkzz7OLzbO/zvAHAoXTz5eYMQL0t2yHAiCFcfPY1QDwNFylA5bPoFpsV9fsEiMl8dhcc4PP1CYD3drYcBYdIKQrx0cbRxd2JHSDcQ297/vvoZ5smRC+AyV2AQ+nm03evge08Tyy4jGqXzWWEoIvTgXHU38pWiNgH4ixB/ukAcy/xycXfp4kwdAAAt399W+OCgMjxILQacxvRQ3gEwHgKUIr/rz53CuDFNyP/Eob4+/vEWkBq6AAA/HIi62n/Lk67Q7wDYQ0UpQB7hc54T4E6gACLTYxeAwB0YKZL6U4ATEGIBwCs7qPfQJCCHkCnoK50noJKcXcAojsEAJZZKXhgCoziGKxqWV8IMNp4kP2aC+oB0TMFvhGxDQHQfIPhDrilwKOm/YCZASAHfgBABQjr3f7CyAkA0cPB03AQULRhKd4xAIjzHymo2Gp7gN0FAMAVOoA2fPz03a9ssh/RM7Iz8QKIzYF9HyB0XEZ1xJ4DzNoDOAfAslhDDTyjDfv8A2AcBeCiu/jBHQEgxnYW6Kp6BlCVAkQM8VnieF2Xyr0ivXy+XvsCzKOihwNHCCryw8HrQXVB8dgFeRfAVQiXjMbIIgXINQYB2H7Kf5wF/2Ar7h0AgKKGuAP4zOjhzlkLbpcRXKRZhNUjxG6HIQDOjN47gCn4+fWW3xVS9urPESEEwwHMo9IhAGxS2ISiA1iEnQOoA4hXRAwItp7WzL9Ow18ESJaw/ar4NgeOR49cAHCAnaH8swBhv+6CBGjeBSxEOUAI7HyKHkD4O9xKb3/feQouAI4uLBciHRRHmgbfA7h/xFc9AngNBADthvii1sMOiPwDAFeyt6s7FSFS4PmnA1v0vQvqDqQKAAPE/weAUuEgsj8c+H11Twdw/AKANXA82EDr5cJBEEzB3oI4Mb0AdR3nNw8vQnegWuvqAABwJFJEBwDgNdA7IOs3gL0LhuJdwBY8c4BfNnDdVgooHiOqn/b7JoSW/QODjTHXhU7hMQAAAABJRU5ErkJggg==', | ||
placeholder: 'blur', | ||
}, | ||
}; | ||
|
||
export const FilledParent = { | ||
args: { | ||
fill: true, | ||
}, | ||
decorator: [ | ||
(Story) => <div style={{ width: 500, height: 500, position: 'relative' }}>{Story()}</div>, | ||
], | ||
}; | ||
|
||
export const Sized = { | ||
args: { | ||
fill: true, | ||
sizes: '(max-width: 600px) 100vw, 600px', | ||
decorator: [ | ||
(Story) => <div style={{ width: 800, height: 800, position: 'relative' }}>{Story()}</div>, | ||
], | ||
}, | ||
}; |
31 changes: 31 additions & 0 deletions
31
code/frameworks/nextjs/template/stories_default-js/ImageLegacy.stories.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from 'react'; | ||
import Image from 'next/legacy/image'; | ||
// eslint-disable-next-line import/extensions | ||
import StackAlt from '../../assets/colors.svg'; | ||
|
||
export default { | ||
component: Image, | ||
args: { | ||
src: StackAlt, | ||
alt: 'Stack Alt', | ||
}, | ||
}; | ||
|
||
export const Default = {}; | ||
|
||
export const BlurredPlaceholder = { | ||
args: { | ||
placeholder: 'blur', | ||
}, | ||
}; | ||
|
||
export const BlurredAbsolutePlaceholder = { | ||
args: { | ||
src: 'https://via.placeholder.com/100', | ||
width: 100, | ||
height: 100, | ||
blurDataURL: | ||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABP5JREFUWEeNlwtz2zgMhEGKsv/k9XFp82xe11763yOJVGcXC4m2czM3GYa0E2s/LACSTi+vv1czM/7CvPpqxY/ejPeS3khmFiPHOiVLHKaZi4ux4j18GpMlS6cALupEQBCKQM4BdnGzjIcJgs//QBxAPQAem55f3yL4PWJIdyCyhlMfPdYZot0cwj3Ayg/5JwHA13paen7pADphxr/n5VI8JQsHCCGQ3gVGLLsxQ3h/LYSn5383B05rwNOws3Z576LOTOduvwfrOd5FtVat4akx0uPTrw8BNuUz23vLsY7hmg7i4ipqM2saiAdruNuirh4ff0bNdb3Qy3vkvfAQwrkHoDxTTZtDCOKrC1bMEkdnsQh/PLyetOGHkXeRAgQAQ84efQcBdUhvFofoulpdm9WGGTA+AJEe7l+i37a2c371tCFKs5zzJjxQNBMi1im7OCudP2aNghJuzZaGdSMEZjpwf/t0UgNdg9DOyLGLnY0BUHlzwVtNDkgEQhBeKkb1tUDgQrq7frwAiIJi5BKAeIFgHk5mOpPzvgltOfcoK0Rrs7lWHwsgqtXarK3N0u23h5Ne8+3Cqxn5RYSMfHCAMgDAx4CBWlA9RAGw0GA/ol0gvFB4WjAvBAFUa83SzdUdAbYMqp28uHpxCRefxwAYhksAFBlthxCiXig+zT4TYqkC+Hq7OdAfJv8lPpZiZShWBBIuRP+jspDb2lwcDkzz7OLzbO/zvAHAoXTz5eYMQL0t2yHAiCFcfPY1QDwNFylA5bPoFpsV9fsEiMl8dhcc4PP1CYD3drYcBYdIKQrx0cbRxd2JHSDcQ297/vvoZ5smRC+AyV2AQ+nm03evge08Tyy4jGqXzWWEoIvTgXHU38pWiNgH4ixB/ukAcy/xycXfp4kwdAAAt399W+OCgMjxILQacxvRQ3gEwHgKUIr/rz53CuDFNyP/Eob4+/vEWkBq6AAA/HIi62n/Lk67Q7wDYQ0UpQB7hc54T4E6gACLTYxeAwB0YKZL6U4ATEGIBwCs7qPfQJCCHkCnoK50noJKcXcAojsEAJZZKXhgCoziGKxqWV8IMNp4kP2aC+oB0TMFvhGxDQHQfIPhDrilwKOm/YCZASAHfgBABQjr3f7CyAkA0cPB03AQULRhKd4xAIjzHymo2Gp7gN0FAMAVOoA2fPz03a9ssh/RM7Iz8QKIzYF9HyB0XEZ1xJ4DzNoDOAfAslhDDTyjDfv8A2AcBeCiu/jBHQEgxnYW6Kp6BlCVAkQM8VnieF2Xyr0ivXy+XvsCzKOihwNHCCryw8HrQXVB8dgFeRfAVQiXjMbIIgXINQYB2H7Kf5wF/2Ar7h0AgKKGuAP4zOjhzlkLbpcRXKRZhNUjxG6HIQDOjN47gCn4+fWW3xVS9urPESEEwwHMo9IhAGxS2ISiA1iEnQOoA4hXRAwItp7WzL9Ow18ESJaw/ar4NgeOR49cAHCAnaH8swBhv+6CBGjeBSxEOUAI7HyKHkD4O9xKb3/feQouAI4uLBciHRRHmgbfA7h/xFc9AngNBADthvii1sMOiPwDAFeyt6s7FSFS4PmnA1v0vQvqDqQKAAPE/weAUuEgsj8c+H11Twdw/AKANXA82EDr5cJBEEzB3oI4Mb0AdR3nNw8vQnegWuvqAABwJFJEBwDgNdA7IOs3gL0LhuJdwBY8c4BfNnDdVgooHiOqn/b7JoSW/QODjTHXhU7hMQAAAABJRU5ErkJggg==', | ||
placeholder: 'blur', | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.