next.js
next.js copied to clipboard
appDir + async server component + css-modules causes syntax error
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103
Binaries:
Node: 18.11.0
npm: 8.19.2
Yarn: 1.22.10
pnpm: N/A
Relevant packages:
next: 13.0.2
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
Chrome, Safari
How are you deploying your application? (if relevant)
next dev
Describe the Bug
When using the experimental /app mode with the following setup, RSC seems to stream in a malformed script tag, causing a crash:
- Uses /app directory
- Root page has both a
layout.tsxand aloading.tsx page.tsxexports an async server componentpage.tsxuses a class name from a CSS module,styles.module.css
Unexpected string literal ",". Parse error.
See minimal repro in code here: https://github.com/mxmul/next13-async-component-css-modules-repro/commit/c562d4dcf3745c365eae6f9515e8680980245d79
Expected Behavior
Page should render the loading state immediately, then the loaded content.
e.g.

Link to reproduction
https://github.com/mxmul/next13-async-component-css-modules-repro
To Reproduce
Clone the repo, and run yarn dev.
The first time you load the page, it seems to render properly. You see a loading state, then the rendered page:
After refreshing the page, you should see next crash with a syntax error:
I do not seem to be able to reproduce this. Can you try next@canary? Can you see any more information in the terminal?
After refreshing the page
Is this a hard refresh (eg. F5) or hot reload (eg. editing and saving a file, in that case which one?)
It still reproduces with next@canary. No errors or warnings in the terminal. By "refresh", I mean a Cmd+R.
Something I just discovered is that it reproduces in Node.js 18 but not Node.js 17
I see this breaking change in the Node.js 18 release notes. I wonder if it could be related?:
(SEMVER-MAJOR) stream: remove thenable support (Robert Nagy) #40773
Getting this same error Node v18.7.0, [email protected].
Ok I investigated a bit, so I can confirm that this happens with Node 18 and not Node 16.
It does not reproduce on the first hit to the page but on all of them afterwards (refresh or not). What causes the error is that on subsequent page loads, we seem to miss a part of the script payload.
what we are suppose to inject
<script>
$RC = function (b, c, e) {
c = document.getElementById(c)
c.parentNode.removeChild(c)
var a = document.getElementById(b)
if (a) {
b = a.previousSibling
if (e) (b.data = '$!'), a.setAttribute('data-dgst', e)
else {
e = b.parentNode
a = b.nextSibling
var f = 0
do {
if (a && 8 === a.nodeType) {
var d = a.data
if ('/$' === d)
if (0 === f) break
else f--
else ('$' !== d && '$?' !== d && '$!' !== d) || f++
}
d = a.nextSibling
e.removeChild(a)
a = d
} while (a)
for (; c.firstChild; ) e.insertBefore(c.firstChild, a)
b.data = '$'
}
b._reactRetry && b._reactRetry()
}
}
$RM = new Map()
$RR = function (p, q, v) {
function r(l) {
this.s = l
}
for (
var t = $RC,
u = $RM,
m = new Map(),
n = document,
g,
e,
f = n.querySelectorAll(
'link[data-precedence],style[data-precedence]'
),
d = 0;
(e = f[d++]);
)
m.set(e.dataset.precedence, (g = e))
e = 0
f = []
for (var c, h, b, a; (c = v[e++]); ) {
var k = 0
h = c[k++]
if ((b = u.get(h))) 'l' !== b.s && f.push(b)
else {
a = n.createElement('link')
a.href = h
a.rel = 'stylesheet'
for (a.dataset.precedence = d = c[k++]; (b = c[k++]); )
a.setAttribute(b, c[k++])
b = a._p = new Promise(function (l, w) {
a.onload = l
a.onerror = w
})
b.then(r.bind(b, 'l'), r.bind(b, 'e'))
u.set(h, b)
f.push(b)
c = m.get(d) || g
c === g && (g = a)
m.set(d, a)
c
? c.parentNode.insertBefore(a, c.nextSibling)
: ((d = n.head), d.insertBefore(a, d.firstChild))
}
}
Promise.all(f).then(
t.bind(null, p, q, ''),
t.bind(null, p, q, 'Resource failed to load')
)
}
$RR('B:0', 'S:0', [
[
'/_next/static/css/app_styles_module_css.css?ts=1667831282087',
'high',
],
])
</script>
what we end up receiving, hence the unexpected string
<script>
B:0","S:0",[["/_next/static/css/app_styles_module_css.css?ts=1667830880867","high"]])
</script>
we seem to be missing some part of the payload🤔
Will investigate further.
https://github.com/vercel/next.js/blob/70e7e58c379a68ac3b73628bae8abb6cf54aacb1/packages/next/compiled/react-dom/cjs/react-dom-server.browser.development.js#L4630
this particular buffer seems to get cleared out at some point, which causes the error
Found the bug, let's hope I can get https://github.com/facebook/react/pull/25645 merged fast!
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.