Skip to content

Commit 2eeb0c7

Browse files
authored
Add missing module.hot.accept call to server CSS modules (#47913)
Since we compile global server CSS imports into a special module with a checksum of the original content, it should always accept HMR updates. This fixes `Fast Refresh had to perform a full reload` errors.
1 parent a3acbf4 commit 2eeb0c7

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

packages/next/src/build/webpack/loaders/next-flight-css-loader.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,20 @@ const NextServerCSSLoader = function (this: any, content: string) {
3434
.substring(0, 12)
3535

3636
if (isCSSModule) {
37-
return (
38-
content + '\nmodule.exports.__checksum = ' + JSON.stringify(checksum)
39-
)
37+
return `\
38+
${content}
39+
module.exports.__checksum = ${JSON.stringify(checksum)}
40+
`
4041
}
4142

42-
return `export default ${JSON.stringify(checksum)}`
43+
// Server CSS imports are always available for HMR, so we attach
44+
// `module.hot.accept()` to the generated module.
45+
const hmrCode = 'if (module.hot) { module.hot.accept() }'
46+
47+
return `\
48+
export default ${JSON.stringify(checksum)}
49+
${hmrCode}
50+
`
4351
}
4452

4553
return content
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background: gray;
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import './global.css'
2+
3+
export default function Page() {
4+
return <div>hello!</div>
5+
}

test/e2e/app-dir/app-css/index.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,26 @@ createNextDescribe(
496496
await next.patchFile(filePath, origContent)
497497
}
498498
})
499+
500+
it('should not break HMR when CSS is imported in a server component', async () => {
501+
const filePath = 'app/hmr/page.js'
502+
const origContent = await next.readFile(filePath)
503+
504+
const browser = await next.browser('/hmr')
505+
await browser.eval(`window.__v = 1`)
506+
try {
507+
await next.patchFile(
508+
filePath,
509+
origContent.replace('hello!', 'hmr!')
510+
)
511+
await check(() => browser.elementByCss('body').text(), 'hmr!')
512+
513+
// Make sure it doesn't reload the page
514+
expect(await browser.eval(`window.__v`)).toBe(1)
515+
} finally {
516+
await next.patchFile(filePath, origContent)
517+
}
518+
})
499519
}
500520
})
501521

0 commit comments

Comments
 (0)