rsnext/test/development/pages-dir/custom-app-hmr/index.test.ts
Jiachi Liu ba0472c507
Fix unexpected full hmr reload when editing _app (#54690)
### What
When you only have `pages/` folder and custom `_app.js`, editing the
`_app.js` file when unexpectedly lead to full page reload. This is
because the `pages/_app` chunk is included into `pages/_document` chunk
as they all pass through the `next-route-loader` which forms the router
module and other userland modules including `/_app` and `/_document`.
That leads to a change: whenever you modify `_app.js`, chunk hash of
`/_document` will always be updated as it's built as a new chunk.

Found this difference by looking at the document chunk with nextjs in
early 13.4.x releases.

### How

We'll check at the entries creation point to filter out `/_app` and
`/_document` so that we won't have them both bundled for `_document`
chunk. Then when we won't trigger the hmr path to reload the page since
_document chunk hash is updated.

Closes NEXT-1568
Fixes #53614
2023-08-30 12:44:08 +02:00

46 lines
1.5 KiB
TypeScript

import { createNextDescribe } from 'e2e-utils'
import { check } from 'next-test-utils'
createNextDescribe(
'custom-app-hmr',
{
files: __dirname,
},
({ next }) => {
it('should not do full reload when simply editing _app.js', async () => {
const customAppFilePath = 'pages/_app.js'
const browser = await next.browser('/')
await browser.eval('window.hmrConstantValue = "should-not-change"')
const customAppContent = await next.readFile(customAppFilePath)
const newCustomAppContent = customAppContent.replace(
'hmr text origin',
'hmr text changed'
)
await next.patchFile(customAppFilePath, newCustomAppContent)
await check(async () => {
const pText = await browser.elementByCss('h1').text()
expect(pText).toBe('hmr text changed')
// Should keep the value on window, which indicates there's no full reload
const hmrConstantValue = await browser.eval('window.hmrConstantValue')
expect(hmrConstantValue).toBe('should-not-change')
return 'success'
}, 'success')
await next.patchFile(customAppFilePath, customAppContent)
await check(async () => {
const pText = await browser.elementByCss('h1').text()
expect(pText).toBe('hmr text origin')
// Should keep the value on window, which indicates there's no full reload
const hmrConstantValue = await browser.eval('window.hmrConstantValue')
expect(hmrConstantValue).toBe('should-not-change')
return 'success'
}, 'success')
})
}
)