Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move root div to an app wrapper #31596

Merged
merged 3 commits into from
Nov 19, 2021
Merged

Conversation

devknoll
Copy link
Contributor

@devknoll devknoll commented Nov 19, 2021

Extracted from #31223.

We need to move the root <div id="__next"> wrapper to be rendered as part of the page content, rather than theDocument, so that flush effects (like styles) are flushed before (or after) the div, rather than inside, where they would cause hydration mismatches.

@ijjk

This comment has been minimized.

@ijjk
Copy link
Member

ijjk commented Nov 19, 2021

Failing test suites

Commit: 3eb161c

test/development/basic-basepath/hmr.test.ts

  • basic HMR > Error Recovery > should show the error on all pages
  • basic HMR > Error Recovery > should detect runtime errors on the module scope
  • basic HMR > Error Recovery > should recover from errors in the render function
  • basic HMR > Error Recovery > should recover after exporting an invalid page
  • basic HMR > Error Recovery > should recover after a bad return from the render function
  • basic HMR > Error Recovery > should recover after undefined exported as default
  • basic HMR > Error Recovery > should recover from errors in getInitialProps in client
  • basic HMR > Error Recovery > should recover after an error reported via SSR
Expand output

● basic HMR › Error Recovery › should show the error on all pages

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  274 |           expect(editedHtml.includes('200px')).toBeTruthy()
  275 |           const $editedHtml = cheerio.load(editedHtml)
> 276 |           const editedServerClassName =
      |                                        ^
  277 |             $editedHtml('#dynamic-component').attr('class')
  278 |
  279 |           expect(editedClientClassName === editedServerClassName).toBe(true)

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:276:70)

● basic HMR › Error Recovery › should detect runtime errors on the module scope

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  301 |
  302 |       try {
> 303 |         browser = await webdriver(next.appPort, '/docs/hmr/new-page')
      |                                                                      ^
  304 |
  305 |         expect(await browser.elementByCss('body').text()).toMatch(
  306 |           /This page could not be found/

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:303:70)

● basic HMR › Error Recovery › should recover from errors in the render function

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  322 |         )
  323 |       } catch (err) {
> 324 |         await next.deleteFile(newPage)
      |                                       ^
  325 |         throw err
  326 |       } finally {
  327 |         if (browser) {

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:324:70)

● basic HMR › Error Recovery › should recover after exporting an invalid page

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  349 |       } catch (err) {
  350 |         await next.patchFile(aboutPage, aboutContent)
> 351 |         if (browser) {
      |                       ^
  352 |           await check(
  353 |             () => getBrowserBodyText(browser),
  354 |             /This is the about page/

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:351:70)

● basic HMR › Error Recovery › should recover after a bad return from the render function

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  383 |         await next.patchFile(aboutPage, aboutContent)
  384 |
> 385 |         await check(
      |                     ^
  386 |           () => getBrowserBodyText(browser),
  387 |           /This is the contact page/
  388 |         )

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:385:70)

● basic HMR › Error Recovery › should recover after undefined exported as default

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  411 |         browser = await webdriver(next.appPort, '/docs/hmr/about3')
  412 |         await check(() => getBrowserBodyText(browser), /This is the about page/)
> 413 |
      | ^
  414 |         await next.patchFile(
  415 |           aboutPage,
  416 |           aboutContent.replace('export', 'aa=20;\nexport')

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:413:70)

● basic HMR › Error Recovery › should recover from errors in getInitialProps in client

TIMED OUT: /an-expected-error-in-gip/

null

  479 |     if (!this.originalContent) {
  480 |       this.originalContent = content
> 481 |     }
      |      ^
  482 |     writeFileSync(this.path, content, 'utf8')
  483 |   }
  484 |

  at Object.check (lib/next-test-utils.js:481:15)
  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:457:17)

● basic HMR › Error Recovery › should recover after an error reported via SSR

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  479 |
  480 |         await next.patchFile(
> 481 |           aboutPage,
      |                     ^
  482 |           aboutContent.replace(
  483 |             'export default',
  484 |             'export default {};\nexport const fn ='

  at Object.<anonymous> (development/basic-basepath/hmr.test.ts:481:70)

test/integration/getserversideprops/test/index.test.js

  • getServerSideProps > dev mode > should show error for invalid JSON returned from getStaticProps on CST
Expand output

● getServerSideProps › dev mode › should show error for invalid JSON returned from getStaticProps on CST

TIMED OUT: /Error serializing `.time` returned from `getServerSideProps`/

null

  479 |     if (!this.originalContent) {
  480 |       this.originalContent = content
> 481 |     }
      |      ^
  482 |     writeFileSync(this.path, content, 'utf8')
  483 |   }
  484 |

  at Object.check (lib/next-test-utils.js:481:15)
  at Object.<anonymous> (integration/getserversideprops/test/index.test.js:571:13)

test/integration/image-component/default/test/index.test.js

  • Image Component Tests > dev mode > should show missing src error
  • Image Component Tests > dev mode > should show invalid src error
  • Image Component Tests > dev mode > should show invalid src error when protocol-relative
  • Image Component Tests > dev mode > should show error when string src and placeholder=blur and blurDataURL is missing
  • Image Component Tests > dev mode > should show error when not numeric string width or height
  • Image Component Tests > dev mode > should show error when static import and placeholder=blur and blurDataUrl is missing
Expand output

● Image Component Tests › dev mode › should show missing src error

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  410 |       )
  411 |       expect(await browser.elementById(id).getAttribute('srcset')).toBe(
> 412 |         '/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
      |                                                                  ^
  413 |       )
  414 |       expect(await browser.elementById(id).getAttribute('sizes')).toBe('100vw')
  415 |       await browser.setDimensions({

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:412:66)

● Image Component Tests › dev mode › should show invalid src error

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  415 |       await browser.setDimensions({
  416 |         width: width + delta,
> 417 |         height: height + delta,
      |                                ^
  418 |       })
  419 |       expect(await getComputed(browser, id, 'width')).toBe(width)
  420 |       expect(await getComputed(browser, id, 'height')).toBe(height)

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:417:66)

● Image Component Tests › dev mode › should show invalid src error when protocol-relative

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  420 |       expect(await getComputed(browser, id, 'height')).toBe(height)
  421 |       await browser.setDimensions({
> 422 |         width: width - delta,
      |                              ^
  423 |         height: height - delta,
  424 |       })
  425 |       const newWidth = await getComputed(browser, id, 'width')

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:422:66)

● Image Component Tests › dev mode › should show error when string src and placeholder=blur and blurDataURL is missing

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  425 |       const newWidth = await getComputed(browser, id, 'width')
  426 |       const newHeight = await getComputed(browser, id, 'height')
> 427 |       expect(newWidth).toBe(width)
      |                                   ^
  428 |       expect(newHeight).toBe(height)
  429 |       expect(getRatio(newWidth, newHeight)).toBeCloseTo(
  430 |         getRatio(width, height),

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:427:66)

● Image Component Tests › dev mode › should show error when not numeric string width or height

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  430 |         getRatio(width, height),
  431 |         1
> 432 |       )
      |        ^
  433 |     } finally {
  434 |       if (browser) {
  435 |         await browser.close()

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:432:66)

● Image Component Tests › dev mode › should show error when static import and placeholder=blur and blurDataUrl is missing

expect(received).toBe(expected) // Object.is equality

Expected: true
Received: false

  435 |         await browser.close()
  436 |       }
> 437 |     }
      |      ^
  438 |   })
  439 |
  440 |   it('should work with layout-fill to fill the parent and stretch with viewport', async () => {

  at Object.<anonymous> (integration/image-component/default/test/index.test.js:437:66)

@ijjk
Copy link
Member

ijjk commented Nov 19, 2021

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-move-root-div Change
buildDuration 24.6s 23.4s -1.2s
buildDurationCached 4.5s 4.5s -22ms
nodeModulesSize 339 MB 339 MB ⚠️ +381 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary azukaru/next.js x-move-root-div Change
/ failed reqs 0 0
/ total time (seconds) 4.095 4.056 -0.04
/ avg req/sec 610.56 616.32 +5.76
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 2.095 2.117 ⚠️ +0.02
/error-in-render avg req/sec 1193.39 1181.1 ⚠️ -12.29
Client Bundles (main, webpack, commons)
vercel/next.js canary azukaru/next.js x-move-root-div Change
450.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42.2 kB 42.2 kB
main-HASH.js gzip 28.3 kB 28.3 kB
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.2 kB 72.2 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary azukaru/next.js x-move-root-div Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary azukaru/next.js x-move-root-div Change
_app-HASH.js gzip 1.37 kB 1.37 kB
_error-HASH.js gzip 194 B 194 B
amp-HASH.js gzip 312 B 312 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.38 kB 2.38 kB
head-HASH.js gzip 350 B 350 B
hooks-HASH.js gzip 635 B 635 B
image-HASH.js gzip 4.45 kB 4.45 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 1.87 kB 1.87 kB
routerDirect..HASH.js gzip 321 B 321 B
script-HASH.js gzip 383 B 383 B
withRouter-HASH.js gzip 318 B 318 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 13.3 kB 13.3 kB
Client Build Manifests
vercel/next.js canary azukaru/next.js x-move-root-div Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-move-root-div Change
index.html gzip 523 B 532 B ⚠️ +9 B
link.html gzip 535 B 545 B ⚠️ +10 B
withRouter.html gzip 516 B 526 B ⚠️ +10 B
Overall change 1.57 kB 1.6 kB ⚠️ +29 B

Diffs

Diff for index.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next">Hello world 👋</div>
+    <div id="__next" data-reactroot="">Hello world 👋</div>
     <script id="__NEXT_DATA__" type="application/json">
       {
         "props": { "pageProps": {}, "__N_SSP": true },
Diff for link.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next">
+    <div id="__next" data-reactroot="">
       <div>
         <h3>A Link page!</h3>
         <a href="/">Go to /</a>
Diff for withRouter.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next"><div>I use withRouter</div></div>
+    <div id="__next" data-reactroot=""><div>I use withRouter</div></div>
     <script id="__NEXT_DATA__" type="application/json">
       {
         "props": { "pageProps": {}, "__N_SSP": true },

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-move-root-div Change
buildDuration 24.8s 23.8s -984ms
buildDurationCached 4.5s 4.5s -53ms
nodeModulesSize 339 MB 339 MB ⚠️ +381 B
Page Load Tests Overall increase ✓
vercel/next.js canary azukaru/next.js x-move-root-div Change
/ failed reqs 0 0
/ total time (seconds) 3.916 3.772 -0.14
/ avg req/sec 638.36 662.73 +24.37
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 2.006 1.94 -0.07
/error-in-render avg req/sec 1246.43 1288.86 +42.43
Client Bundles (main, webpack, commons)
vercel/next.js canary azukaru/next.js x-move-root-div Change
450.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.6 kB 28.6 kB
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 72.5 kB 72.5 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary azukaru/next.js x-move-root-div Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary azukaru/next.js x-move-root-div Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 180 B 180 B
amp-HASH.js gzip 305 B 305 B
css-HASH.js gzip 321 B 321 B
dynamic-HASH.js gzip 2.38 kB 2.38 kB
head-HASH.js gzip 342 B 342 B
hooks-HASH.js gzip 622 B 622 B
image-HASH.js gzip 4.47 kB 4.47 kB
index-HASH.js gzip 256 B 256 B
link-HASH.js gzip 1.91 kB 1.91 kB
routerDirect..HASH.js gzip 314 B 314 B
script-HASH.js gzip 375 B 375 B
withRouter-HASH.js gzip 309 B 309 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 13.2 kB 13.2 kB
Client Build Manifests
vercel/next.js canary azukaru/next.js x-move-root-div Change
_buildManifest.js gzip 459 B 459 B
Overall change 459 B 459 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-move-root-div Change
index.html gzip 524 B 532 B ⚠️ +8 B
link.html gzip 535 B 545 B ⚠️ +10 B
withRouter.html gzip 517 B 526 B ⚠️ +9 B
Overall change 1.58 kB 1.6 kB ⚠️ +27 B

Diffs

Diff for index.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next">Hello world 👋</div>
+    <div id="__next" data-reactroot="">Hello world 👋</div>
     <script id="__NEXT_DATA__" type="application/json">
       {
         "props": { "pageProps": {}, "__N_SSP": true },
Diff for link.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next">
+    <div id="__next" data-reactroot="">
       <div>
         <h3>A Link page!</h3>
         <a href="/">Go to /</a>
Diff for withRouter.html
@@ -38,7 +38,7 @@
     ></script>
   </head>
   <body>
-    <div id="__next"><div>I use withRouter</div></div>
+    <div id="__next" data-reactroot=""><div>I use withRouter</div></div>
     <script id="__NEXT_DATA__" type="application/json">
       {
         "props": { "pageProps": {}, "__N_SSP": true },
Commit: 9009946

@kodiakhq kodiakhq bot merged commit ab712ef into vercel:canary Nov 19, 2021
@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants