From 0fb39e23473df06164b7fe89244da13775b22865 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 20 Oct 2020 12:43:24 -0400 Subject: [PATCH] Add `width` and `height` props to Image component (#18031) Co-authored-by: Tim Neutkens --- packages/next/build/webpack-config.ts | 14 ++- packages/next/client/image.tsx | 36 +++++-- packages/next/next-server/server/config.ts | 8 ++ .../basic/pages/client-side.js | 36 ++++++- .../image-component/basic/pages/errors.js | 8 +- .../image-component/basic/pages/index.js | 32 ++++++- .../image-component/basic/pages/lazy.js | 16 +--- .../image-component/basic/test/index.test.js | 20 ++-- .../image-component/default/pages/index.js | 14 +++ .../image-component/default/public/test.bmp | Bin 0 -> 80858 bytes .../image-component/default/public/test.gif | Bin 0 -> 2301 bytes .../image-component/default/public/test.jpg | Bin 0 -> 6765 bytes .../image-component/default/public/test.png | Bin 0 -> 1545 bytes .../image-component/default/public/test.svg | 13 +++ .../image-component/default/public/test.tiff | Bin 0 -> 2260 bytes .../default/test/index.test.js | 89 ++++++++++++++++++ 16 files changed, 240 insertions(+), 46 deletions(-) create mode 100644 test/integration/image-component/default/pages/index.js create mode 100644 test/integration/image-component/default/public/test.bmp create mode 100644 test/integration/image-component/default/public/test.gif create mode 100644 test/integration/image-component/default/public/test.jpg create mode 100644 test/integration/image-component/default/public/test.png create mode 100644 test/integration/image-component/default/public/test.svg create mode 100644 test/integration/image-component/default/public/test.tiff create mode 100644 test/integration/image-component/default/test/index.test.js diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 437d73e3cc..2a496da5a0 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -229,13 +229,6 @@ export default async function getBaseWebpackConfig( } } - // Normalize defined image host to end in slash - if (config.images?.path) { - if (config.images.path[config.images.path.length - 1] !== '/') { - config.images.path += '/' - } - } - const reactVersion = await getPackageVersion({ cwd: dir, name: 'react' }) const hasReactRefresh: boolean = dev && !isServer const hasJsxRuntime: boolean = @@ -997,7 +990,12 @@ export default async function getBaseWebpackConfig( 'process.env.__NEXT_SCROLL_RESTORATION': JSON.stringify( config.experimental.scrollRestoration ), - 'process.env.__NEXT_IMAGE_OPTS': JSON.stringify(config.images), + 'process.env.__NEXT_IMAGE_OPTS': JSON.stringify({ + sizes: config.images.sizes, + path: config.images.path, + loader: config.images.loader, + autoOptimize: config.images.autoOptimize, + }), 'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath), 'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites), 'process.env.__NEXT_I18N_SUPPORT': JSON.stringify( diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 1c68d75785..dd35cbbfdb 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -9,6 +9,9 @@ const loaders: { [key: string]: (props: LoaderProps) => string } = { type ImageData = { sizes?: number[] + loader?: string + path?: string + autoOptimize?: boolean } type ImageProps = Omit< @@ -16,13 +19,15 @@ type ImageProps = Omit< 'src' | 'srcSet' | 'ref' > & { src: string + width: number + height: number quality?: string priority?: boolean lazy?: boolean unoptimized?: boolean } -let imageData: any = process.env.__NEXT_IMAGE_OPTS +const imageData: ImageData = process.env.__NEXT_IMAGE_OPTS as any const breakpoints = imageData.sizes || [640, 1024, 1600] // Auto optimize defaults to on if not specified if (imageData.autoOptimize === undefined) { @@ -83,7 +88,7 @@ type CallLoaderProps = { function callLoader(loaderProps: CallLoaderProps) { let loader = loaders[imageData.loader || 'default'] - return loader({ root: imageData.path, ...loaderProps }) + return loader({ root: imageData.path || '/_next/image', ...loaderProps }) } type SrcSetData = { @@ -136,6 +141,8 @@ function generatePreload({ export default function Image({ src, sizes, + width, + height, unoptimized = false, priority = false, lazy = false, @@ -156,11 +163,6 @@ export default function Image({ lazy = false } - // Normalize provided src - if (src[0] === '/') { - src = src.slice(1) - } - useEffect(() => { const target = thisEl.current @@ -217,8 +219,11 @@ export default function Image({ // it's too late for preloads const shouldPreload = priority && typeof window === 'undefined' + const ratio = (height / width) * 100 + const paddingBottom = `${isNaN(ratio) ? 1 : ratio}%` + return ( -
+
{shouldPreload ? generatePreload({ src, @@ -233,6 +238,13 @@ export default function Image({ className={className} sizes={sizes} ref={thisEl} + style={{ + height: '100%', + left: '0', + position: 'absolute', + top: '0', + width: '100%', + }} />
) @@ -242,6 +254,10 @@ export default function Image({ type LoaderProps = CallLoaderProps & { root: string } +function normalizeSrc(src: string) { + return src[0] === '/' ? src.slice(1) : src +} + function imgixLoader({ root, src, width, quality }: LoaderProps): string { const params = [] let paramsString = '' @@ -257,7 +273,7 @@ function imgixLoader({ root, src, width, quality }: LoaderProps): string { if (params.length) { paramsString = '?' + params.join('&') } - return `${root}${src}${paramsString}` + return `${root}${normalizeSrc(src)}${paramsString}` } function cloudinaryLoader({ root, src, width, quality }: LoaderProps): string { @@ -275,7 +291,7 @@ function cloudinaryLoader({ root, src, width, quality }: LoaderProps): string { if (params.length) { paramsString = params.join(',') + '/' } - return `${root}${paramsString}${src}` + return `${root}${paramsString}${normalizeSrc(src)}` } function defaultLoader({ root, src, width, quality }: LoaderProps): string { diff --git a/packages/next/next-server/server/config.ts b/packages/next/next-server/server/config.ts index 753b0ea024..c65065db61 100644 --- a/packages/next/next-server/server/config.ts +++ b/packages/next/next-server/server/config.ts @@ -215,6 +215,14 @@ function assignDefaults(userConfig: { [key: string]: any }) { if (result?.images) { const { images } = result + + // Normalize defined image host to end in slash + if (images?.path) { + if (images.path[images.path.length - 1] !== '/') { + images.path += '/' + } + } + if (typeof images !== 'object') { throw new Error( `Specified images should be an object received ${typeof images}` diff --git a/test/integration/image-component/basic/pages/client-side.js b/test/integration/image-component/basic/pages/client-side.js index b4f7f9da18..3b6f3ac879 100644 --- a/test/integration/image-component/basic/pages/client-side.js +++ b/test/integration/image-component/basic/pages/client-side.js @@ -6,21 +6,49 @@ const ClientSide = () => { return (

This is a client side page

- - + + + + - - Errors diff --git a/test/integration/image-component/basic/pages/errors.js b/test/integration/image-component/basic/pages/errors.js index 20d70cfb4b..552a516828 100644 --- a/test/integration/image-component/basic/pages/errors.js +++ b/test/integration/image-component/basic/pages/errors.js @@ -5,7 +5,13 @@ const Errors = () => { return (

This is a page with errors

- +
) } diff --git a/test/integration/image-component/basic/pages/index.js b/test/integration/image-component/basic/pages/index.js index 6c9f777ca4..de450b29ce 100644 --- a/test/integration/image-component/basic/pages/index.js +++ b/test/integration/image-component/basic/pages/index.js @@ -6,18 +6,34 @@ const Page = () => { return (

Hello World

- - + + { priority host="secondary" src="withpriority2.png" + width={300} + height={400} /> + - Client Side diff --git a/test/integration/image-component/basic/pages/lazy.js b/test/integration/image-component/basic/pages/lazy.js index f352e6bdce..4d9c223ab3 100644 --- a/test/integration/image-component/basic/pages/lazy.js +++ b/test/integration/image-component/basic/pages/lazy.js @@ -5,28 +5,22 @@ const Lazy = () => { return (

This is a page with lazy-loaded images

- +
diff --git a/test/integration/image-component/basic/test/index.test.js b/test/integration/image-component/basic/test/index.test.js index c47a17bfaf..a358202ee2 100644 --- a/test/integration/image-component/basic/test/index.test.js +++ b/test/integration/image-component/basic/test/index.test.js @@ -7,6 +7,7 @@ import { nextStart, nextBuild, waitFor, + check, } from 'next-test-utils' import webdriver from 'next-webdriver' @@ -91,19 +92,20 @@ function lazyLoadingTests() { it('should load the second image after scrolling down', async () => { let viewportHeight = await browser.eval(`window.innerHeight`) let topOfMidImage = await browser.eval( - `document.getElementById('lazy-mid').offsetTop` + `document.getElementById('lazy-mid').parentElement.offsetTop` ) let buffer = 150 await browser.eval( `window.scrollTo(0, ${topOfMidImage - (viewportHeight + buffer)})` ) - await waitFor(200) - expect(await browser.elementById('lazy-mid').getAttribute('src')).toBe( - 'https://example.com/myaccount/foo2.jpg' - ) - expect(await browser.elementById('lazy-mid').getAttribute('srcset')).toBe( - 'https://example.com/myaccount/foo2.jpg?w=480 480w, https://example.com/myaccount/foo2.jpg?w=1024 1024w, https://example.com/myaccount/foo2.jpg?w=1600 1600w' - ) + + await check(() => { + return browser.elementById('lazy-mid').getAttribute('src') + }, 'https://example.com/myaccount/foo2.jpg') + + await check(() => { + return browser.elementById('lazy-mid').getAttribute('srcset') + }, 'https://example.com/myaccount/foo2.jpg?w=480 480w, https://example.com/myaccount/foo2.jpg?w=1024 1024w, https://example.com/myaccount/foo2.jpg?w=1600 1600w') }) it('should not have loaded the third image after scrolling down', async () => { expect( @@ -116,7 +118,7 @@ function lazyLoadingTests() { it('should load the third image, which is unoptimized, after scrolling further down', async () => { let viewportHeight = await browser.eval(`window.innerHeight`) let topOfBottomImage = await browser.eval( - `document.getElementById('lazy-bottom').offsetTop` + `document.getElementById('lazy-bottom').parentElement.offsetTop` ) let buffer = 150 await browser.eval( diff --git a/test/integration/image-component/default/pages/index.js b/test/integration/image-component/default/pages/index.js new file mode 100644 index 0000000000..be82b9c08b --- /dev/null +++ b/test/integration/image-component/default/pages/index.js @@ -0,0 +1,14 @@ +import React from 'react' +import Image from 'next/image' + +const Page = () => { + return ( +
+

Hello World

+ +

This is the index page

+
+ ) +} + +export default Page diff --git a/test/integration/image-component/default/public/test.bmp b/test/integration/image-component/default/public/test.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f33feda8616b735b81ededeb14244f820342f24b GIT binary patch literal 80858 zcmeI5!D}3K6vtnZ-PG1f-Dx8pL^5kE#kSD2mx?{?Mx`KaX=??mg(jP3TOnyfk|Lsq zf`~_R=%tEOtm1#5o-6x<00w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4ea zAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd& z00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY z0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHdbBrxgwekG^Ht9UyH7<%ZX8kO8+ zRH|NOcWCedZj5+2oeUnv_q_uH3_bKxqt$ADC&cqYV-Iwr&R0WTi@$52p@&|qoZlP7 z_fLj~9_U6Xztd6iY6A^D{9=>&32`>-ilRnt?{nYTtSdV5n|a;Mx}t;R13mLO;fvF& zwuf`}tDZ}0;(4CKSy$kd<&!w`M+hfZ4rg7_k;}}>*OgzB(Ht(5UJg^Q?>n7!1z)3* zhYokSuDJw8a(I9EUd36iYjjXGhk4iatSe%sa?s&VY+!NLC})48`&GxYuD~m0|1RZK zYR*nW_k|}je-8Rjbw_j8n#ruA`k1@uyRSTwJuPuR>$05DQ(1*nX}XKWU8|l|hvQt= zkSlY#n)*E=$10e0MN7%g@R`nEJ-nJB;&{!~hScYS(=+F}uEE#f@1<$qBYa&stuPo3 zvL4~$Y+4-^&vAtzAY}AZhWe=QO$UZ@+pK3f9ZF_hAy`gdYw#;dW?j)y%JBK&yuu&? z%#yy&t7p~~E$MS!Perb4&PRrvS4FOCba1sHYP{6tScP3&YNm+UDw@w z4U|%;;Ow%tc_hc%lPSJ~@S93au50i$#F5bF;#b|?O*63v*J2x3d_=hatX2q7L0$REs2RW zcjuHugL7;n=!ixlKd;;~S6E>P%1P$ub??^=#vIj7H1qOxrLw{h6qLx%tH{F;j6K*+ z`*njcN3|2xd6iZeLV6O^c|Gm3t_Vut=k+xBbwltYHWK)GRrqxyLJxH%@bl{M z>xQC^*s#}mb@+87LJxJ>y$w42x}l&WHtgO8<+<*E~7C*ER9Rt$X@;HTiYp1ekuVHpG7?EI_VnboBD`YVzxvc;nVR{k)3&x^eNF{+@nb zO@3VyaNN3wpI3c_A*iW`pI4P%HyCqNyN93GQ(s{S3W~4u>hkLbV~%Ra=e)Z7x>2zQ z`+DTO>YQW2xF2Z8`gxW4bsq?PQ%7vhTaaAW$cgjwYV+%wc;nX5eqPQVYjH;??T_;F zYV_;c@J0D~HTrdJI-=^l8vVL99Z`N>m402DkSK41M!&92N2H%up-S|sNUlugw7b$e-$ePKVZUcatQ$0k3oUcatQNXXBt*sp8T5%%-y_3PSn zg#5gk{kk?GK|e3or&T-0dT9yyc@_J0dufn;L06e(zphP3$j__UuWJ($%y~8Yb!|EV zeqPmnU7Lj26^&g#uWrAt?R<1+-ePzdV)eBByan*<#tK;9(ed-@ z_v_kpbo{*f{kk?CGV@BRTd2EfQKH&@-U4|TqBKZf+s|77ziwRoroUZnD1u+t1RS^K zzl|(}UpFp()6ah1Lilw}ym4#x^A^Id8yCOnFUcRw*UVON*V706V)%7!h#P(}{JJ(B zBb9>Zy6XbjRYub`u|?QlFPMiRj%m4ochjP@lxk7E=mP-|009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X_#Y7%UY(y^SS}qPTDZKjbo%Jj_^W4M8{cx5N;F1WX@d65%q}n1 zPo6v$FZ!RKX-M||v|q-Ge_rIChcC=6&k_wi#Cs3VE-tNbyT}s#dzIU}W-rZL z;Pz+S-nYa7a{EW=Z*)qq8TxXnraQ|wzZ{lO39q$r-`AxU4@j1~~%=q!& z7H5`b+OIRhzlWPmqCdYNdgLt8PG-IB^{o3lym@RHpKjeDI`cNsu^)(Td`PsLUvI~` F{{U@jL16#@ literal 0 HcmV?d00001 diff --git a/test/integration/image-component/default/public/test.gif b/test/integration/image-component/default/public/test.gif new file mode 100644 index 0000000000000000000000000000000000000000..6bbbd315e9fe876cbdbd61261aceabd359efb49f GIT binary patch literal 2301 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 literal 0 HcmV?d00001 diff --git a/test/integration/image-component/default/public/test.svg b/test/integration/image-component/default/public/test.svg new file mode 100644 index 0000000000..025d874f92 --- /dev/null +++ b/test/integration/image-component/default/public/test.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/test/integration/image-component/default/public/test.tiff b/test/integration/image-component/default/public/test.tiff new file mode 100644 index 0000000000000000000000000000000000000000..c2cc3e203bb3fdb5d828597623a630e6b0e59bfb GIT binary patch literal 2260 zcmYk8X*|?h9LE2H$(405mTgq;xLX1{585!sB> zlHk2xXGw4(o7xY>&t4og@!=H#quZ z+dP}zUTJm?u+yVVeF|@Py<*q4yz^h&Q};l7eHmfy#9oge`*tsFiF?m+!4CQ*cFI|U zULg+c@5A8*qnEEb!ez3oN?-bhI(B%`Tx$NshdIGZru}Je0>Yg--tWeAz6*?SM#u`M z_AdoTIzRE&&Kp_1N^n7x+Eq=jhef$OSqbl$+l+{IHIU63TKP(daqaY`z1`T0j&(CA zo&L1@JvPp*b7lAY&!>D`V9?VvC2rO(K1(RLD-AEf-p!YClA}AVQkk=dZ%~uFCv6?h z+Y8|`f%K*;Sqbz(EHTi&bi9l3Gf0Z3XpQt9fP9ubPzHe0UsS6S0ia9#+>2~1I>Gxn zzy^REDx}NV_MTpsJPGTOQvf;S000BYBV@+t&XN^a7;KKF*ERH(NP)jT7YBi(ySR>u zD5;2YCmJn4M2Ob%&^soJknEQMIuiHJE%A#A-j#a^?V6JU^eN3s85ZvaM2W*bnz>dh z{33$V&;8ic98lgaRh&^DI^XzQoC9pLfoDG_lYo@6(qUB%vQeOZpw{!0u% zQjhn%zmh<%n>@-F$e)MXB zdPSeP7zSpGVIdAs+39M?mmjTQ6x(eR$6QIlx-{Pr%~0Pe#pEhACp#amEQ69&eTu8S zk6=6nX)~GRc^uhF)$YK$JW9^Fej>Q2V#0*tFAc%OxmyY)(1HL+`32+hKuw9DH^zH) zrA`BN$e%7@Z+Tw0aC+E=x{_T|BV=lpLu0W6Z^Gl~>jxEq??M~sW`hIWvm_^&ryoXz zt!(T+t)!zhccdyxcZ4n=&DW}yamz0iz@{o6K5OJy*{bjqkA-T5 zBV_#obhmV03GUikH-CIM?V~~bkEEz&T6lVPW;-u>j?h4*o)Y2luI^`SvGoDpruumk z{CP?$mG^ljMO%?!L0oDPuFE`)D*5#V8|8PmMZLHtf@%Yi=+$9ZBrk;R-ys=rKjO8b zMM7|(EsYlN93el5sQ1=x1H>*M*5Thel}JzWG-kSk!egzb+U@EuUH#ILTX^Kv;9Y)J zh6_D)bc3G1Hom9)UV?8MrP#HkGl}IMQ%NV}Eq?n1rGoE2YdS=sZ-;}~|>WE+Q-zQXaTM}+f@LsKSe;}cPcV3rY+2!CYFM^koHVq$baNP5oz6JKA z6l{C5|3kfmOZ)-psVmzb+3!k30p%^MA16K3JRNGeNJi($C~VOieLoN3KK?SAdslxP z%Dn$L$qi33j7bdO*b-jOZ~wG`VIJ>dp{jdXonG#A^z!12 zQQT-e?9?7eYJjM2{Ke1&G6lPr%~-l!2S1{CGj_hXj>RnfheAf_yv%^umht)v6u&9H z5|ycwp#C7GenvmSkDa#u2qGm};q7jGxoK=hQoFs0LY|V1fT3SqA0G*T1 zrralYP85D#={z!1+Qcepb6i#+2U$vRw6JGCi%J;{<)y1q)|eg%C#i~S^G@tl@fOfZ1=At zeW6BWB%vZSA>GCoV?iZpm7@0x(Y_?xauT)zL#W02PC8YP!fG)4UG{#^OO+&YJ(e)$ z=!fyEA~n&l`}59zq>yUTRGS^)i>u#cR1ImT)9wJ|j)&fOOcv^~kAisMF?VXoTK)D1 z|KRYX%sMib?hvKsg`do=Cx?wV9Gt!E4=rjSlP4UbP`>_{ibitNwBx}=yg#YFi9Ge% zDJm$yf3l56-kEbcxE>e)?P<;uT6B&|4-UZ4Te7rj)A;xR0K^J_002m1PM|-SEo literal 0 HcmV?d00001 diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js new file mode 100644 index 0000000000..e09e9808ff --- /dev/null +++ b/test/integration/image-component/default/test/index.test.js @@ -0,0 +1,89 @@ +/* eslint-env jest */ + +import { join } from 'path' +import { + killApp, + findPort, + launchApp, + nextStart, + nextBuild, + check, +} from 'next-test-utils' +import webdriver from 'next-webdriver' +import fs from 'fs-extra' + +jest.setTimeout(1000 * 30) + +const appDir = join(__dirname, '../') +const nextConfig = join(appDir, 'next.config.js') + +let appPort +let app + +function runTests() { + it('should load the image', async () => { + let browser + try { + browser = await webdriver(appPort, '/') + await check(async () => { + const result = await browser.eval( + `document.getElementById('basic-image').naturalWidth` + ) + if (result === 0) { + throw new Error('Incorrectly loaded image') + } + + return 'result-correct' + }, /result-correct/) + } finally { + if (browser) { + await browser.close() + } + } + }) +} + +describe('Image Component Tests', () => { + describe('dev mode', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests('dev') + }) + + describe('server mode', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests('server') + }) + + describe('serverless mode', () => { + beforeAll(async () => { + await fs.writeFile( + nextConfig, + ` + module.exports = { + target: 'serverless' + } + ` + ) + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(async () => { + await fs.unlink(nextConfig) + await killApp(app) + }) + + runTests('serverless') + }) +}) -- GitLab