Skip to content

Commit b6017fa

Browse files
timneutkensztanner
andauthored
Handle edge runtime in places that import node:stream (#92354)
## What? The codepath would cause checks to fail during deployment because it tries to import `node:stream` even when not used. This adds a specific path for edge runtime to avoid that. --------- Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
1 parent 15d9b4d commit b6017fa

File tree

4 files changed

+96
-54
lines changed

4 files changed

+96
-54
lines changed

packages/next/errors.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,5 +1145,8 @@
11451145
"1144": "Prefetch inlining is enabled but no hints were found for route \"%s\". This is a bug in the Next.js build pipeline — prefetch-hints.json should contain an entry for every route that produces segment data.",
11461146
"1145": "Internal Next.js Error: Prefetch inlining is enabled but no hints were found for route \"%s\". prefetch-hints.json should contain an entry for every route that produces segment data. This is a bug in Next.js.",
11471147
"1146": "Internal Next.js Error: Prefetch inlining is enabled but no hint tree was provided during incremental static revalidation. The prefetch-hints.json manifest should contain an entry for this route. This is a bug in Next.js.",
1148-
"1147": "Turbopack database compaction is not supported on this platform"
1148+
"1147": "Turbopack database compaction is not supported on this platform",
1149+
"1148": "webToReadable cannot be used in the edge runtime",
1150+
"1149": "Node.js Readable cannot be teed in the edge runtime",
1151+
"1150": "Node.js Readable cannot be converted to a web stream in the edge runtime"
11491152
}

packages/next/src/server/app-render/app-render-prerender-utils.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,29 @@ export class ReactServerResult {
3030
return tee[1]
3131
}
3232

33-
let Readable: typeof import('node:stream').Readable
34-
if (process.env.TURBOPACK) {
35-
Readable = (require('node:stream') as typeof import('node:stream'))
36-
.Readable
33+
if (process.env.NEXT_RUNTIME === 'edge') {
34+
throw new InvariantError(
35+
'Node.js Readable cannot be teed in the edge runtime'
36+
)
3737
} else {
38-
Readable = (
39-
__non_webpack_require__('node:stream') as typeof import('node:stream')
40-
).Readable
38+
let Readable: typeof import('node:stream').Readable
39+
if (process.env.TURBOPACK) {
40+
Readable = (require('node:stream') as typeof import('node:stream'))
41+
.Readable
42+
} else {
43+
Readable = (
44+
__non_webpack_require__('node:stream') as typeof import('node:stream')
45+
).Readable
46+
}
47+
const webStream = Readable.toWeb(
48+
this._stream
49+
) as ReadableStream<Uint8Array>
50+
const tee = webStream.tee()
51+
this._stream = Readable.fromWeb(
52+
tee[0] as import('stream/web').ReadableStream
53+
)
54+
return Readable.fromWeb(tee[1] as import('stream/web').ReadableStream)
4155
}
42-
const webStream = Readable.toWeb(this._stream) as ReadableStream<Uint8Array>
43-
const tee = webStream.tee()
44-
this._stream = Readable.fromWeb(
45-
tee[0] as import('stream/web').ReadableStream
46-
)
47-
return Readable.fromWeb(tee[1] as import('stream/web').ReadableStream)
4856
}
4957

5058
consume(): AnyStream {

packages/next/src/server/render-result.ts

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,24 @@ export default class RenderResult<
248248
}
249249

250250
if (isNodeReadable(this.response)) {
251-
let Readable: typeof import('node:stream').Readable
252-
if (process.env.TURBOPACK) {
253-
Readable = (require('node:stream') as typeof import('node:stream'))
254-
.Readable
251+
if (process.env.NEXT_RUNTIME === 'edge') {
252+
throw new InvariantError(
253+
'Node.js Readable cannot be converted to a web stream in the edge runtime'
254+
)
255255
} else {
256-
Readable = (
257-
__non_webpack_require__('node:stream') as typeof import('node:stream')
258-
).Readable
256+
let Readable: typeof import('node:stream').Readable
257+
if (process.env.TURBOPACK) {
258+
Readable = (require('node:stream') as typeof import('node:stream'))
259+
.Readable
260+
} else {
261+
Readable = (
262+
__non_webpack_require__(
263+
'node:stream'
264+
) as typeof import('node:stream')
265+
).Readable
266+
}
267+
return Readable.toWeb(this.response) as ReadableStream<Uint8Array>
259268
}
260-
return Readable.toWeb(this.response) as ReadableStream<Uint8Array>
261269
}
262270

263271
return this.response
@@ -283,16 +291,24 @@ export default class RenderResult<
283291
} else if (Buffer.isBuffer(this.response)) {
284292
return [streamFromBuffer(this.response)]
285293
} else if (isNodeReadable(this.response)) {
286-
let Readable: typeof import('node:stream').Readable
287-
if (process.env.TURBOPACK) {
288-
Readable = (require('node:stream') as typeof import('node:stream'))
289-
.Readable
294+
if (process.env.NEXT_RUNTIME === 'edge') {
295+
throw new InvariantError(
296+
'Node.js Readable cannot be converted to a web stream in the edge runtime'
297+
)
290298
} else {
291-
Readable = (
292-
__non_webpack_require__('node:stream') as typeof import('node:stream')
293-
).Readable
299+
let Readable: typeof import('node:stream').Readable
300+
if (process.env.TURBOPACK) {
301+
Readable = (require('node:stream') as typeof import('node:stream'))
302+
.Readable
303+
} else {
304+
Readable = (
305+
__non_webpack_require__(
306+
'node:stream'
307+
) as typeof import('node:stream')
308+
).Readable
309+
}
310+
return [Readable.toWeb(this.response) as ReadableStream<Uint8Array>]
294311
}
295-
return [Readable.toWeb(this.response) as ReadableStream<Uint8Array>]
296312
} else {
297313
return [this.response]
298314
}

packages/next/src/server/stream-utils/node-web-streams-helper.ts

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,26 @@ export async function webstreamToUint8Array(
135135
function webToReadable(
136136
stream: ReadableStream<Uint8Array> | import('node:stream').Readable
137137
): import('node:stream').Readable {
138-
let Readable: typeof import('node:stream').Readable
139-
if (process.env.TURBOPACK) {
140-
Readable = (require('node:stream') as typeof import('node:stream')).Readable
141-
} else if (process.env.__NEXT_BUNDLER === 'Webpack') {
142-
Readable = (
143-
__non_webpack_require__('node:stream') as typeof import('node:stream')
144-
).Readable
138+
if (process.env.NEXT_RUNTIME === 'edge') {
139+
throw new Error('webToReadable cannot be used in the edge runtime')
145140
} else {
146-
Readable = (require('node:stream') as typeof import('node:stream')).Readable
147-
}
148-
if (stream instanceof Readable) {
149-
return stream
141+
let Readable: typeof import('node:stream').Readable
142+
if (process.env.TURBOPACK) {
143+
Readable = (require('node:stream') as typeof import('node:stream'))
144+
.Readable
145+
} else if (process.env.__NEXT_BUNDLER === 'Webpack') {
146+
Readable = (
147+
__non_webpack_require__('node:stream') as typeof import('node:stream')
148+
).Readable
149+
} else {
150+
Readable = (require('node:stream') as typeof import('node:stream'))
151+
.Readable
152+
}
153+
if (stream instanceof Readable) {
154+
return stream
155+
}
156+
return Readable.fromWeb(stream as import('stream/web').ReadableStream)
150157
}
151-
return Readable.fromWeb(stream as import('stream/web').ReadableStream)
152158
}
153159

154160
export async function nodestreamToUint8Array(
@@ -162,20 +168,29 @@ export async function nodestreamToUint8Array(
162168
}
163169

164170
export async function streamToUint8Array(stream: AnyStream) {
165-
let Readable: typeof import('node:stream').Readable
166-
if (process.env.TURBOPACK) {
167-
Readable = (require('node:stream') as typeof import('node:stream')).Readable
168-
} else if (process.env.__NEXT_BUNDLER === 'Webpack') {
169-
Readable = (
170-
__non_webpack_require__('node:stream') as typeof import('node:stream')
171-
).Readable
171+
if (process.env.NEXT_RUNTIME === 'edge') {
172+
// Edge runtime always uses web streams
173+
return webstreamToUint8Array(stream as ReadableStream<Uint8Array>)
172174
} else {
173-
Readable = (require('node:stream') as typeof import('node:stream')).Readable
174-
}
175-
if (stream instanceof Readable) {
176-
return nodestreamToUint8Array(stream)
175+
let Readable: typeof import('node:stream').Readable
176+
if (process.env.TURBOPACK) {
177+
Readable = (require('node:stream') as typeof import('node:stream'))
178+
.Readable
179+
} else if (process.env.__NEXT_BUNDLER === 'Webpack') {
180+
Readable = (
181+
__non_webpack_require__('node:stream') as typeof import('node:stream')
182+
).Readable
183+
} else {
184+
Readable = (require('node:stream') as typeof import('node:stream'))
185+
.Readable
186+
}
187+
188+
if (stream instanceof Readable) {
189+
return nodestreamToUint8Array(stream)
190+
}
191+
192+
return webstreamToUint8Array(stream)
177193
}
178-
return webstreamToUint8Array(stream)
179194
}
180195

181196
export async function streamToBuffer(

0 commit comments

Comments
 (0)