Skip to content

Commit ffade8d

Browse files
arunodarauchg
authored andcommitted
Fix client error modal not showing in dev (HMR) (vercel#1448)
* Fix HMR not working issue. Our hot-reload code on the server has custom webpack error dectection logic. Is supports only multi-modules entries. So, we need to all entries as multi-module entries even if there's just a single entry. * Add a test case for showing errors over HMR.
1 parent 3837b75 commit ffade8d

File tree

5 files changed

+53
-4
lines changed

5 files changed

+53
-4
lines changed

server/build/webpack.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,18 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
5252
// managing pages.
5353
if (dev) {
5454
for (const p of devPages) {
55-
entries[join('bundles', p)] = `./${p}?entry`
55+
entries[join('bundles', p)] = [`./${p}?entry`]
5656
}
5757
} else {
5858
for (const p of pages) {
59-
entries[join('bundles', p)] = `./${p}?entry`
59+
entries[join('bundles', p)] = [`./${p}?entry`]
6060
}
6161
}
6262

6363
for (const p of defaultPages) {
6464
const entryName = join('bundles', 'pages', p)
6565
if (!entries[entryName]) {
66-
entries[entryName] = [...defaultEntries, join(nextPagesDir, p) + '?entry']
66+
entries[entryName] = [join(nextPagesDir, p) + '?entry']
6767
}
6868
}
6969

server/on-demand-entry-handler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export default function onDemandEntryHandler (devMiddleware, compiler, {
7171
const pathname = await resolvePath(pagePath)
7272
const name = join('bundles', pathname.substring(dir.length))
7373

74-
const entry = `${pathname}?entry`
74+
const entry = [`${pathname}?entry`]
7575

7676
await new Promise((resolve, reject) => {
7777
const entryInfo = entries[page]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default () => (
2+
<div className='hmr-about-page'>
3+
<p>
4+
This is the about page.
5+
</p>
6+
</div>
7+
)

test/integration/basic/test/hmr.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* global describe, it, expect */
2+
import webdriver from 'next-webdriver'
3+
import { readFileSync, writeFileSync } from 'fs'
4+
import { join } from 'path'
5+
6+
export default (context, render) => {
7+
describe('Hot Module Reloading', () => {
8+
describe('syntax error', () => {
9+
it('should detect the error and recover', async () => {
10+
const browser = await webdriver(context.appPort, '/hmr/about')
11+
const text = await browser
12+
.elementByCss('p').text()
13+
expect(text).toBe('This is the about page.')
14+
15+
const aboutPagePath = join(__dirname, '../', 'pages', 'hmr', 'about.js')
16+
17+
const originalContent = readFileSync(aboutPagePath, 'utf8')
18+
const erroredContent = originalContent.replace('</div>', 'div')
19+
20+
// change the content
21+
writeFileSync(aboutPagePath, erroredContent, 'utf8')
22+
23+
const errorMessage = await browser
24+
.waitForElementByCss('pre')
25+
.elementByCss('pre').text()
26+
expect(errorMessage.includes('SyntaxError: Unterminated JSX contents')).toBeTruthy()
27+
28+
// add the original content
29+
writeFileSync(aboutPagePath, originalContent, 'utf8')
30+
31+
const newContent = await browser
32+
.waitForElementByCss('.hmr-about-page')
33+
.elementByCss('p').text()
34+
expect(newContent).toBe('This is the about page.')
35+
36+
browser.close()
37+
})
38+
})
39+
})
40+
}

test/integration/basic/test/index.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import xPoweredBy from './xpowered-by'
1414
import rendering from './rendering'
1515
import misc from './misc'
1616
import clientNavigation from './client-navigation'
17+
import hmr from './hmr'
1718

1819
const context = {}
1920
context.app = nextServer({
@@ -57,4 +58,5 @@ describe('Basic Features', () => {
5758
xPoweredBy(context)
5859
misc(context)
5960
clientNavigation(context, (p, q) => renderViaHTTP(context.appPort, p, q))
61+
hmr(context, (p, q) => renderViaHTTP(context.appPort, p, q))
6062
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy