From 8289aaa6048433103f2e433df6b5c082b2dce795 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 18 Oct 2024 17:28:55 +0200 Subject: [PATCH] refactor ssg --- .../docusaurus/src/client/renderToHtml.tsx | 82 ++++--------------- 1 file changed, 15 insertions(+), 67 deletions(-) diff --git a/packages/docusaurus/src/client/renderToHtml.tsx b/packages/docusaurus/src/client/renderToHtml.tsx index 0f79eb5bbe7e..dcfcea16d678 100644 --- a/packages/docusaurus/src/client/renderToHtml.tsx +++ b/packages/docusaurus/src/client/renderToHtml.tsx @@ -7,74 +7,22 @@ import type {ReactNode} from 'react'; import {renderToPipeableStream} from 'react-dom/server'; -import {Writable} from 'stream'; +import {PassThrough} from 'node:stream'; +import {text} from 'node:stream/consumers'; +// See also https://github.com/facebook/react/issues/31134 +// See also https://github.com/facebook/docusaurus/issues/9985#issuecomment-2396367797 export async function renderToHtml(app: ReactNode): Promise { - // Inspired from - // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation - // https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/static-entry.js - const writableStream = new WritableAsPromise(); - - const {pipe} = renderToPipeableStream(app, { - onError(error) { - writableStream.destroy(error as Error); - }, - onAllReady() { - pipe(writableStream); - }, - }); - - return writableStream.getPromise(); -} - -// WritableAsPromise inspired by https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/server-utils/writable-as-promise.js - -/* eslint-disable no-underscore-dangle */ -class WritableAsPromise extends Writable { - private _output: string; - private _deferred: { - promise: Promise | null; - resolve: (value: string) => void; - reject: (reason: Error) => void; - }; - - constructor() { - super(); - this._output = ``; - this._deferred = { - promise: null, - resolve: () => null, - reject: () => null, - }; - this._deferred.promise = new Promise((resolve, reject) => { - this._deferred.resolve = resolve; - this._deferred.reject = reject; + return new Promise((resolve, reject) => { + const passThrough = new PassThrough(); + const {pipe} = renderToPipeableStream(app, { + onError(error) { + reject(error); + }, + onAllReady() { + pipe(passThrough); + text(passThrough).then(resolve, reject); + }, }); - } - - override _write( - chunk: {toString: () => string}, - _enc: unknown, - next: () => void, - ) { - this._output += chunk.toString(); - next(); - } - - override _destroy(error: Error | null, next: (error?: Error | null) => void) { - if (error instanceof Error) { - this._deferred.reject(error); - } else { - next(); - } - } - - override end() { - this._deferred.resolve(this._output); - return this.destroy(); - } - - getPromise(): Promise { - return this._deferred.promise!; - } + }); }