From 78e071aedcb190ec04e64cff9a0be039cc4e959e Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 23 Dec 2022 16:08:44 -0500 Subject: [PATCH 1/2] Fix next/image failures when `basePath` and `trailingSlash` defined --- packages/next/server/config.ts | 8 +-- .../next.config.js | 7 +++ .../pages/index.js | 22 +++++++ .../public/test.jpg | Bin 0 -> 6765 bytes .../test/index.test.ts | 58 ++++++++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 test/integration/next-image-new/both-basepath-trailingslash/next.config.js create mode 100644 test/integration/next-image-new/both-basepath-trailingslash/pages/index.js create mode 100644 test/integration/next-image-new/both-basepath-trailingslash/public/test.jpg create mode 100644 test/integration/next-image-new/both-basepath-trailingslash/test/index.test.ts diff --git a/packages/next/server/config.ts b/packages/next/server/config.ts index 8ff3d3c6c96cb6e..53d63bad6a17a4b 100644 --- a/packages/next/server/config.ts +++ b/packages/next/server/config.ts @@ -447,6 +447,10 @@ function assignDefaults(dir: string, userConfig: { [key: string]: any }) { ) } + if (images.path === imageConfigDefault.path && result.basePath) { + images.path = `${result.basePath}${images.path}` + } + // Append trailing slash for non-default loaders and when trailingSlash is set if (images.path) { if ( @@ -458,10 +462,6 @@ function assignDefaults(dir: string, userConfig: { [key: string]: any }) { } } - if (images.path === imageConfigDefault.path && result.basePath) { - images.path = `${result.basePath}${images.path}` - } - if (images.loaderFile) { if (images.loader !== 'default' && images.loader !== 'custom') { throw new Error( diff --git a/test/integration/next-image-new/both-basepath-trailingslash/next.config.js b/test/integration/next-image-new/both-basepath-trailingslash/next.config.js new file mode 100644 index 000000000000000..32b285f258ecd8f --- /dev/null +++ b/test/integration/next-image-new/both-basepath-trailingslash/next.config.js @@ -0,0 +1,7 @@ +module.exports = { + basePath: '/prefix', + trailingSlash: true, + images: { + deviceSizes: [640, 828], + }, +} diff --git a/test/integration/next-image-new/both-basepath-trailingslash/pages/index.js b/test/integration/next-image-new/both-basepath-trailingslash/pages/index.js new file mode 100644 index 000000000000000..40aeb172afe0d83 --- /dev/null +++ b/test/integration/next-image-new/both-basepath-trailingslash/pages/index.js @@ -0,0 +1,22 @@ +import React from 'react' +import Image from 'next/image' +import img from '../public/test.jpg' + +const Page = () => { + return ( +
+

Trailing Slash

+ import-img +
+ string-img +
+ ) +} + +export default Page diff --git a/test/integration/next-image-new/both-basepath-trailingslash/public/test.jpg b/test/integration/next-image-new/both-basepath-trailingslash/public/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d536c882412ed3df0dc162823ca5146bcc033499 GIT binary patch literal 6765 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 { + it('should correctly load image src from import', async () => { + expect.assertions(1) + const browser = await webdriver(appPort, '/prefix/') + const img = await browser.elementById('import-img') + const src = await img.getAttribute('src') + expect(src).toBe( + '/prefix/_next/image/?url=%2Fprefix%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' + ) + }) + it('should correctly load image src from string', async () => { + expect.assertions(1) + const browser = await webdriver(appPort, '/prefix/') + const img = await browser.elementById('string-img') + const src = await img.getAttribute('src') + expect(src).toBe('/prefix/_next/image/?url=%2Fprefix%2Ftest.jpg&w=640&q=75') + }) +} + +describe('Image Component basePath + trailingSlash Tests', () => { + describe('dev mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) + + describe('server mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) +}) From ab7ef0d428e501257e0050be0db8316935f340fb Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 23 Dec 2022 17:15:54 -0500 Subject: [PATCH 2/2] Add test for response status & headers --- .../both-basepath-trailingslash/test/index.test.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/integration/next-image-new/both-basepath-trailingslash/test/index.test.ts b/test/integration/next-image-new/both-basepath-trailingslash/test/index.test.ts index 8e570248faf9b87..f3c0ed6b8fd1516 100644 --- a/test/integration/next-image-new/both-basepath-trailingslash/test/index.test.ts +++ b/test/integration/next-image-new/both-basepath-trailingslash/test/index.test.ts @@ -1,6 +1,7 @@ /* eslint-env jest */ import { + fetchViaHTTP, findPort, killApp, launchApp, @@ -17,20 +18,26 @@ let app const runTests = () => { it('should correctly load image src from import', async () => { - expect.assertions(1) + expect.assertions(3) const browser = await webdriver(appPort, '/prefix/') const img = await browser.elementById('import-img') const src = await img.getAttribute('src') expect(src).toBe( '/prefix/_next/image/?url=%2Fprefix%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' ) + const res = await fetchViaHTTP(appPort, src) + expect(res.status).toBe(200) + expect(res.headers.get('content-type')).toBe('image/jpeg') }) it('should correctly load image src from string', async () => { - expect.assertions(1) + expect.assertions(3) const browser = await webdriver(appPort, '/prefix/') const img = await browser.elementById('string-img') const src = await img.getAttribute('src') expect(src).toBe('/prefix/_next/image/?url=%2Fprefix%2Ftest.jpg&w=640&q=75') + const res = await fetchViaHTTP(appPort, src) + expect(res.status).toBe(200) + expect(res.headers.get('content-type')).toBe('image/jpeg') }) }