From eb525b0f16de32daf35b5e6be250a0634c8cb829 Mon Sep 17 00:00:00 2001 From: zhangxiang Date: Wed, 30 Jul 2025 21:59:32 +0800 Subject: [PATCH] feat: remove ssr styled --- packages/runtime/plugin-runtime/package.json | 12 +-- .../server/stream/createReadableStream.ts | 24 +----- .../src/core/server/string/index.ts | 2 - .../src/core/server/string/styledComponent.ts | 23 ----- .../plugin-runtime/src/exports/styled.ts | 5 -- .../__snapshots__/renderString.test.ts.snap | 28 ------ .../tests/ssr/fixtures/string-ssr/App.tsx | 14 --- .../tests/ssr/renderString.test.ts | 85 ------------------- pnpm-lock.yaml | 23 ----- 9 files changed, 5 insertions(+), 211 deletions(-) delete mode 100644 packages/runtime/plugin-runtime/src/core/server/string/styledComponent.ts delete mode 100644 packages/runtime/plugin-runtime/src/exports/styled.ts delete mode 100644 packages/runtime/plugin-runtime/tests/ssr/__snapshots__/renderString.test.ts.snap delete mode 100644 packages/runtime/plugin-runtime/tests/ssr/fixtures/string-ssr/App.tsx delete mode 100644 packages/runtime/plugin-runtime/tests/ssr/renderString.test.ts diff --git a/packages/runtime/plugin-runtime/package.json b/packages/runtime/plugin-runtime/package.json index 6078c71813bc..beb8f3f600dc 100644 --- a/packages/runtime/plugin-runtime/package.json +++ b/packages/runtime/plugin-runtime/package.json @@ -64,11 +64,6 @@ "jsnext:source": "./src/exports/head.ts", "default": "./dist/esm/exports/head.js" }, - "./styled": { - "types": "./dist/types/exports/styled.d.ts", - "jsnext:source": "./src/exports/styled.ts", - "default": "./dist/esm/exports/styled.js" - }, "./server": { "types": "./dist/types/exports/server.d.ts", "jsnext:source": "./src/exports/server.ts", @@ -167,9 +162,6 @@ "head": [ "./dist/types/exports/head.d.ts" ], - "styled": [ - "./dist/types/exports/styled.d.ts" - ], "server": [ "./dist/types/exports/server.d.ts" ], @@ -231,7 +223,6 @@ "@swc/helpers": "^0.5.17", "@types/loadable__component": "^5.13.10", "@types/react-helmet": "^6.1.11", - "@types/styled-components": "^5.1.34", "cookie": "0.7.2", "es-module-lexer": "^1.1.0", "esbuild": "0.25.5", @@ -239,8 +230,7 @@ "isbot": "3.7.1", "react-helmet": "^6.1.0", "react-is": "^18", - "react-side-effect": "^2.1.2", - "styled-components": "^5.3.1" + "react-side-effect": "^2.1.2" }, "peerDependencies": { "react": ">=17", diff --git a/packages/runtime/plugin-runtime/src/core/server/stream/createReadableStream.ts b/packages/runtime/plugin-runtime/src/core/server/stream/createReadableStream.ts index ffc6d26b9e6e..fdf6343adf82 100644 --- a/packages/runtime/plugin-runtime/src/core/server/stream/createReadableStream.ts +++ b/packages/runtime/plugin-runtime/src/core/server/stream/createReadableStream.ts @@ -1,7 +1,6 @@ -import { PassThrough, Transform } from 'stream'; +import { Transform } from 'stream'; import { createReadableStreamFromReadable } from '@modern-js/runtime-utils/node'; import checkIsBot from 'isbot'; -import { ServerStyleSheet } from 'styled-components'; import { ESCAPED_SHELL_STREAM_END_MARK } from '../../../common'; import { RenderLevel } from '../../constants'; import { @@ -26,19 +25,13 @@ export const createReadableStreamFromElement: CreateReadableStreamFromElement = const isbot = checkIsBot(request.headers.get('user-agent')); const onReady = isbot || forceStream2String ? 'onAllReady' : 'onShellReady'; - const sheet = new ServerStyleSheet(); - const chunkVec: string[] = []; - const root = sheet.collectStyles(rootElement); - return new Promise(resolve => { - const { pipe: reactStreamingPipe } = renderToPipeableStream(root, { + const { pipe: reactStreamingPipe } = renderToPipeableStream(rootElement, { nonce: config.nonce, [onReady]() { - const styledComponentsStyleTags = forceStream2String - ? sheet.getStyleTags() - : ''; + const styledComponentsStyleTags = ''; options[onReady]?.(); getTemplates(htmlTemplate, { @@ -90,16 +83,7 @@ export const createReadableStreamFromElement: CreateReadableStreamFromElement = const stream = createReadableStreamFromReadable(body); resolve(stream); - // Transform the react pipe to a readable stream - // Actually it's for type check, we even can execute `sheet.interleaveWithNodeStream({ pipe })` - // Source code https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/ServerStyleSheet.tsx#L80 - const passThrough = new PassThrough(); - const styledStream = sheet.interleaveWithNodeStream(passThrough); - reactStreamingPipe(passThrough); - - // pipe the styled stream to the body stream - // now only use styled stream, if there is multiple stream, we can abstract it to a function - styledStream.pipe(body); + reactStreamingPipe(body); }); }, diff --git a/packages/runtime/plugin-runtime/src/core/server/string/index.ts b/packages/runtime/plugin-runtime/src/core/server/string/index.ts index 4f6a44b7ab06..9a223f6f1a2c 100644 --- a/packages/runtime/plugin-runtime/src/core/server/string/index.ts +++ b/packages/runtime/plugin-runtime/src/core/server/string/index.ts @@ -18,7 +18,6 @@ import { getSSRConfigByEntry, safeReplace } from '../utils'; import { LoadableCollector } from './loadable'; import { prefetch } from './prefetch'; import { SSRDataCollector } from './ssrData'; -import { StyledCollector } from './styledComponent'; import type { ChunkSet, Collector } from './types'; export const renderString: RenderString = async ( @@ -64,7 +63,6 @@ export const renderString: RenderString = async ( } const collectors = [ - new StyledCollector(chunkSet), new LoadableCollector({ stats: loadableStats, nonce: config.nonce, diff --git a/packages/runtime/plugin-runtime/src/core/server/string/styledComponent.ts b/packages/runtime/plugin-runtime/src/core/server/string/styledComponent.ts deleted file mode 100644 index d147c7e52b8a..000000000000 --- a/packages/runtime/plugin-runtime/src/core/server/string/styledComponent.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ReactElement } from 'react'; -import { ServerStyleSheet } from 'styled-components'; -import type { ChunkSet, Collector } from './types'; - -export class StyledCollector implements Collector { - #sheet: ServerStyleSheet = new ServerStyleSheet(); - - #chunkSet: ChunkSet; - - constructor(chunkSet: ChunkSet) { - this.#chunkSet = chunkSet; - } - - collect(comopnent: ReactElement) { - return this.#sheet.collectStyles(comopnent); - } - - effect() { - const css = this.#sheet.getStyleTags(); - - this.#chunkSet.cssChunk += css; - } -} diff --git a/packages/runtime/plugin-runtime/src/exports/styled.ts b/packages/runtime/plugin-runtime/src/exports/styled.ts deleted file mode 100644 index c97a440917bc..000000000000 --- a/packages/runtime/plugin-runtime/src/exports/styled.ts +++ /dev/null @@ -1,5 +0,0 @@ -import styled from 'styled-components'; - -export default styled; - -export * from 'styled-components'; diff --git a/packages/runtime/plugin-runtime/tests/ssr/__snapshots__/renderString.test.ts.snap b/packages/runtime/plugin-runtime/tests/ssr/__snapshots__/renderString.test.ts.snap deleted file mode 100644 index 956866cea62b..000000000000 --- a/packages/runtime/plugin-runtime/tests/ssr/__snapshots__/renderString.test.ts.snap +++ /dev/null @@ -1,28 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`test render should render styledComponent correctly 1`] = ` -" - - - - - - - - - - - -

Hello Modern.js

Hello Modern.js-----
- - - - - -" -`; diff --git a/packages/runtime/plugin-runtime/tests/ssr/fixtures/string-ssr/App.tsx b/packages/runtime/plugin-runtime/tests/ssr/fixtures/string-ssr/App.tsx deleted file mode 100644 index 8dd0b247b289..000000000000 --- a/packages/runtime/plugin-runtime/tests/ssr/fixtures/string-ssr/App.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; - -const RedDiv = styled.div` - color: red; -`; - -export default () => ( -
-

Hello Modern.js

- - Hello Modern.js----- -
-); diff --git a/packages/runtime/plugin-runtime/tests/ssr/renderString.test.ts b/packages/runtime/plugin-runtime/tests/ssr/renderString.test.ts deleted file mode 100644 index 6f2a2afcbb25..000000000000 --- a/packages/runtime/plugin-runtime/tests/ssr/renderString.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @jest-environment node - */ -import path from 'path'; -import { fs, createLogger } from '@modern-js/utils'; -import React from 'react'; -import { getInitialContext } from '../../src/core/context/runtime'; -import { wrapRuntimeContextProvider } from '../../src/core/react/wrapper'; -import { type RenderOptions, renderString } from '../../src/core/server/server'; -import App from './fixtures/string-ssr/App'; - -const htmlPath = path.resolve( - __dirname, - './fixtures/htmlTemplate/template.html', -); - -const onTiming = jest.fn(); - -describe('test render', () => { - it('should render styledComponent correctly', async () => { - const htmlTemplate = fs.readFileSync(htmlPath, 'utf8'); - - const runtimeContext = getInitialContext({} as any, false); - - class Request { - url: string; - - headers: Map = new Map(); - - constructor(url: string) { - this.url = url; - } - } - const request = new Request('http://localhost:8080'); - - runtimeContext.ssrContext = { - redirection: {}, - htmlModifiers: [], - request: { - url: 'http://localhost:8080', - userAgent: request.headers.get('user-agent')!, - raw: request as any, - } as any, - response: { - setHeader() { - // ignore - }, - status() { - // ignore - }, - locals: {}, - }, - mode: 'string', - } as any; - - const renderOptions: RenderOptions = { - runtimeContext, - resource: { - route: { - urlPath: '/', - entryPath: 'main', - }, - htmlTemplate, - entryName: 'main', - routeManifest: {} as any, - } as any, - loaderContext: new Map(), - logger: createLogger(), - params: {}, - config: { - ssr: true, - }, - onTiming, - }; - - const serverRoot = wrapRuntimeContextProvider(React.createElement(App), { - ssr: true, - } as any); - - const html = await renderString(request as any, serverRoot, renderOptions); - - expect(html).toMatchSnapshot(); - expect(onTiming).toBeCalled(); - }); -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef8880f40d8d..8fa23a1d3907 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1388,9 +1388,6 @@ importers: '@types/react-helmet': specifier: ^6.1.11 version: 6.1.11 - '@types/styled-components': - specifier: ^5.1.34 - version: 5.1.34 cookie: specifier: 0.7.2 version: 0.7.2 @@ -1415,9 +1412,6 @@ importers: react-side-effect: specifier: ^2.1.2 version: 2.1.2(react@19.1.0) - styled-components: - specifier: ^5.3.1 - version: 5.3.5(react-dom@19.1.0(react@19.1.0))(react-is@18.3.1)(react@19.1.0) devDependencies: '@modern-js/app-tools': specifier: workspace:* @@ -9074,9 +9068,6 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/hoist-non-react-statics@3.3.5': - resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} - '@types/html-minifier-terser@7.0.2': resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==} @@ -9275,9 +9266,6 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/styled-components@5.1.34': - resolution: {integrity: sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==} - '@types/superagent@8.1.9': resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} @@ -21110,11 +21098,6 @@ snapshots: dependencies: '@types/unist': 3.0.3 - '@types/hoist-non-react-statics@3.3.5': - dependencies: - '@types/react': 19.1.8 - hoist-non-react-statics: 3.3.2 - '@types/html-minifier-terser@7.0.2': {} '@types/http-assert@1.5.3': {} @@ -21320,12 +21303,6 @@ snapshots: '@types/stack-utils@2.0.3': {} - '@types/styled-components@5.1.34': - dependencies: - '@types/hoist-non-react-statics': 3.3.5 - '@types/react': 19.1.8 - csstype: 3.1.3 - '@types/superagent@8.1.9': dependencies: '@types/cookiejar': 2.1.5