Skip to content

Commit

Permalink
fix: next.config.js with unstable_getImgProps() (#52153)
Browse files Browse the repository at this point in the history
- Fixes #52116
  • Loading branch information
styfle committed Jul 3, 2023
1 parent b4b98e8 commit e17218f
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 34 deletions.
1 change: 1 addition & 0 deletions packages/next/src/client/image-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { warnOnce } from '../shared/lib/utils/warn-once'
// @ts-ignore - This is replaced by webpack alias
import defaultLoader from 'next/dist/shared/lib/image-loader'

// This is replaced by webpack define plugin
const configEnv = process.env.__NEXT_IMAGE_OPTS as any as ImageConfigComplete

if (typeof window === 'undefined') {
Expand Down
5 changes: 2 additions & 3 deletions packages/next/src/shared/lib/get-img-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ type ImageConfig = ImageConfigComplete & {
allSizes: number[]
output?: 'standalone' | 'export'
}
const configEnv = process.env.__NEXT_IMAGE_OPTS as any as ImageConfigComplete

export type ImageLoader = (p: ImageLoaderProps) => string

Expand Down Expand Up @@ -256,7 +255,7 @@ export function getImgProps(
}: ImageProps,
_state: {
defaultLoader: ImageLoaderWithConfig
imgConf?: ImageConfig
imgConf: ImageConfigComplete
showAltText?: boolean
blurComplete?: boolean
}
Expand All @@ -271,7 +270,7 @@ export function getImgProps(
} {
const { imgConf, showAltText, blurComplete, defaultLoader } = _state
let config: ImageConfig
let c = imgConf || configEnv || imageConfigDefault
let c = imgConf || imageConfigDefault
if ('allSizes' in c) {
config = c as ImageConfig
} else {
Expand Down
9 changes: 7 additions & 2 deletions packages/next/src/shared/lib/image-external.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ImageLoaderProps } from './image-config'
import type { ImageConfigComplete, ImageLoaderProps } from './image-config'
import type { ImageProps, ImageLoader, StaticImageData } from './get-img-props'

import { getImgProps } from './get-img-props'
Expand All @@ -7,11 +7,16 @@ import { Image } from '../../client/image-component'

// @ts-ignore - This is replaced by webpack alias
import defaultLoader from 'next/dist/shared/lib/image-loader'

const unstable_getImgProps = (imgProps: ImageProps) => {
warnOnce(
'Warning: unstable_getImgProps() is experimental and may change or be removed at any time. Use at your own risk.'
)
const { props } = getImgProps(imgProps, { defaultLoader })
const { props } = getImgProps(imgProps, {
defaultLoader,
// This is replaced by webpack define plugin
imgConf: process.env.__NEXT_IMAGE_OPTS as any as ImageConfigComplete,
})
for (const [key, value] of Object.entries(props)) {
if (value === undefined) {
delete props[key as keyof typeof props]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { unstable_getImgProps as getImgProps } from 'next/image'

function loader({ src, width, quality }) {
return `${src}?wid=${width}&qual=${quality || 35}`
}

export default function Page() {
const { props: img1 } = getImgProps({
id: 'img1',
alt: 'img1',
src: '/logo.png',
width: '400',
height: '400',
priority: true,
})
const { props: img2 } = getImgProps({
id: 'img2',
alt: 'img2',
src: '/logo.png',
width: '200',
height: '200',
loader,
})
return (
<div>
<h1>Loader Config</h1>
<img {...img1} />
<p>Scroll down...</p>
<div style={{ height: '100vh' }} />
<h2>Loader Prop</h2>
<img {...img2} />
</div>
)
}
53 changes: 31 additions & 22 deletions test/integration/next-image-new/loader-config/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,72 @@ const appDir = join(__dirname, '../')

let appPort
let app
let browser

function runTests() {
it('should add "src" to img1 based on the loader config', async () => {
function runTests(url: string) {
it('should work with loaderFile config', async () => {
const browser = await webdriver(appPort, url)
expect(await browser.elementById('img1').getAttribute('src')).toBe(
'/logo.png#w:828,q:50'
)
})

it('should add "srcset" to img1 based on the loader config', async () => {
expect(await browser.elementById('img1').getAttribute('srcset')).toBe(
'/logo.png#w:640,q:50 1x, /logo.png#w:828,q:50 2x'
)
})

it('should add "src" to img2 based on the loader prop', async () => {
it('should work with loader prop', async () => {
const browser = await webdriver(appPort, url)
expect(await browser.elementById('img2').getAttribute('src')).toBe(
'/logo.png?wid=640&qual=35'
)
})

it('should add "srcset" to img2 based on the loader prop', async () => {
expect(await browser.elementById('img2').getAttribute('srcset')).toBe(
'/logo.png?wid=256&qual=35 1x, /logo.png?wid=640&qual=35 2x'
)
})
}

describe('Image Loader Config', () => {
describe('dev mode', () => {
describe('dev mode - component', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(() => {
killApp(app)
})
runTests('/')
})

describe('server mode - component', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(() => {
killApp(app)
})
runTests('/')
})
describe('dev mode - getImgProps', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
browser = await webdriver(appPort, '/')
})
afterAll(() => {
killApp(app)
if (browser) {
browser.close()
}
})
runTests()
runTests('/get-img-props')
})

describe('server mode', () => {
describe('server mode - getImgProps', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
browser = await webdriver(appPort, '/')
})
afterAll(() => {
killApp(app)
if (browser) {
browser.close()
}
})
runTests()
runTests('/get-img-props')
})
})
47 changes: 47 additions & 0 deletions test/integration/next-image-new/unoptimized/pages/get-img-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'
import { unstable_getImgProps as getImgProps } from 'next/image'
import testJpg from '../public/test.jpg'

const Page = () => {
const { props: img1 } = getImgProps({
id: 'internal-image',
src: '/test.png',
width: 400,
height: 400,
})
const { props: img2 } = getImgProps({
id: 'static-image',
src: testJpg,
width: 400,
height: 400,
})
const { props: img3 } = getImgProps({
id: 'external-image',
src: 'https://image-optimization-test.vercel.app/test.jpg',
width: 400,
height: 400,
})
const { props: img4 } = getImgProps({
id: 'eager-image',
src: '/test.webp',
width: 400,
height: 400,
loading: 'eager',
})
return (
<div>
<h1>Unoptimized Config</h1>
<p>Scroll down...</p>
<div style={{ height: '1000vh' }} />
<img {...img1} />
<br />
<img {...img2} />
<br />
<img {...img3} />
<div style={{ height: '1000vh' }} />
<img {...img4} />
</div>
)
}

export default Page
35 changes: 28 additions & 7 deletions test/integration/next-image-new/unoptimized/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ const appDir = join(__dirname, '../')
let appPort
let app

function runTests() {
function runTests(url: string) {
it('should not optimize any image', async () => {
const browser = await webdriver(appPort, '/')

const browser = await webdriver(appPort, url)
expect(
await browser.elementById('internal-image').getAttribute('src')
).toBe('/test.png')
Expand Down Expand Up @@ -93,7 +92,7 @@ function runTests() {
}

describe('Unoptimized Image Tests', () => {
describe('dev mode', () => {
describe('dev mode - component', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
Expand All @@ -102,10 +101,32 @@ describe('Unoptimized Image Tests', () => {
await killApp(app)
})

runTests()
runTests('/')
})
describe('server mode - component', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
})

describe('server mode', () => {
runTests('/')
})
describe('dev mode - getImgProps', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
})

runTests('/get-img-props')
})
describe('server mode - getImgProps', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
Expand All @@ -115,6 +136,6 @@ describe('Unoptimized Image Tests', () => {
await killApp(app)
})

runTests()
runTests('/get-img-props')
})
})

0 comments on commit e17218f

Please sign in to comment.