Skip to content

Commit 41849f6

Browse files
authored
feat: support styled-component in streaming ssr (#6734)
1 parent fa20ea7 commit 41849f6

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

.changeset/strange-donuts-bake.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modern-js/runtime': patch
3+
---
4+
5+
feat: support styled-component in streaming ssr
6+
feat: 在流式渲染中支持 styled-component

packages/runtime/plugin-runtime/src/core/server/stream/createReadableStream.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Transform } from 'stream';
1+
import { PassThrough, Transform } from 'stream';
22
import { createReadableStreamFromReadable } from '@modern-js/runtime-utils/node';
33
import checkIsBot from 'isbot';
44
import { ServerStyleSheet } from 'styled-components';
@@ -30,12 +30,10 @@ export const createReadableStreamFromElement: CreateReadableStreamFromElement =
3030

3131
const chunkVec: string[] = [];
3232

33-
const root = forceStream2String
34-
? sheet.collectStyles(rootElement)
35-
: rootElement;
33+
const root = sheet.collectStyles(rootElement);
3634

3735
return new Promise(resolve => {
38-
const { pipe } = renderToPipeableStream(root, {
36+
const { pipe: reactStreamingPipe } = renderToPipeableStream(root, {
3937
nonce: config.nonce,
4038
[onReady]() {
4139
const styledComponentsStyleTags = forceStream2String
@@ -87,11 +85,21 @@ export const createReadableStreamFromElement: CreateReadableStreamFromElement =
8785
},
8886
});
8987

88+
// Transform the Node.js readable stream to a Web ReadableStream
89+
// For modern.js depend on hono.js, and we use Web standard
9090
const stream = createReadableStreamFromReadable(body);
91-
9291
resolve(stream);
9392

94-
pipe(body);
93+
// Transform the react pipe to a readable stream
94+
// Actually it's for type check, we even can execute `sheet.interleaveWithNodeStream({ pipe })`
95+
// Source code https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/ServerStyleSheet.tsx#L80
96+
const passThrough = new PassThrough();
97+
const styledStream = sheet.interleaveWithNodeStream(passThrough);
98+
reactStreamingPipe(passThrough);
99+
100+
// pipe the styled stream to the body stream
101+
// now only use styled stream, if there is multiple stream, we can abstract it to a function
102+
styledStream.pipe(body);
95103
});
96104
},
97105

0 commit comments

Comments
 (0)