diff --git a/packages/waku/src/lib/builder.ts b/packages/waku/src/lib/builder.ts index b257fc434..6a26aa51a 100644 --- a/packages/waku/src/lib/builder.ts +++ b/packages/waku/src/lib/builder.ts @@ -254,7 +254,7 @@ const emitRscFiles = async ( if (!rscFileSet.has(destFile)) { rscFileSet.add(destFile); fs.mkdirSync(path.dirname(destFile), { recursive: true }); - const [pipeable] = await renderRSC({ + const [readable] = await renderRSC({ input, method: "GET", headers: {}, @@ -262,7 +262,7 @@ const emitRscFiles = async ( context, moduleIdCallback: (id) => addClientModule(input, id), }); - await pipeline(pipeable, fs.createWriteStream(destFile)); + await pipeline(readable, fs.createWriteStream(destFile)); } } }), @@ -288,7 +288,7 @@ const emitHtmlFiles = async ( }); const htmlFiles = await Promise.all( Object.entries(buildConfig).map( - async ([pathStr, { entries, context, customCode }]) => { + async ([pathStr, { entries, customCode, context }]) => { const destFile = path.join( config.rootDir, config.distDir, diff --git a/packages/waku/src/lib/middleware/rsc.ts b/packages/waku/src/lib/middleware/rsc.ts index f7a7ec90d..338ec820b 100644 --- a/packages/waku/src/lib/middleware/rsc.ts +++ b/packages/waku/src/lib/middleware/rsc.ts @@ -21,7 +21,7 @@ type Middleware = ( export function rsc(options: { command: "dev" | "start"; - ssr: boolean; + ssr?: boolean; unstable_prehook?: (req: IncomingMessage, res: ServerResponse) => Context; unstable_posthook?: ( req: IncomingMessage, @@ -29,15 +29,16 @@ export function rsc(options: { ctx: Context, ) => void; }): Middleware { - if (!options.unstable_prehook && options.unstable_posthook) { + const { command, ssr, unstable_prehook, unstable_posthook } = options; + if (!unstable_prehook && unstable_posthook) { throw new Error("prehook is required if posthook is provided"); } const configPromise = resolveConfig(); - let viteServer: ViteDevServer | undefined; + let lastViteServer: ViteDevServer | undefined; const getViteServer = async (): Promise => { - if (viteServer) { - return viteServer; + if (lastViteServer) { + return lastViteServer; } const config = await configPromise; const { createServer: viteCreateServer } = await import("vite"); @@ -48,7 +49,7 @@ export function rsc(options: { const { rscHmrPlugin, hotImport } = await import( "../vite-plugin/rsc-hmr-plugin.js" ); - viteServer = await viteCreateServer({ + const viteServer = await viteCreateServer({ root: path.join(config.rootDir, config.srcDir), optimizeDeps: { include: ["react-server-dom-webpack/client"], @@ -63,9 +64,9 @@ export function rsc(options: { ], server: { middlewareMode: true }, }); - const vite = viteServer; - registerReloadCallback((type) => vite.ws.send({ type })); - registerImportCallback((source) => hotImport(vite, source)); + registerReloadCallback((type) => viteServer.ws.send({ type })); + registerImportCallback((source) => hotImport(viteServer, source)); + lastViteServer = viteServer; return viteServer; }; @@ -75,7 +76,7 @@ export function rsc(options: { if (!publicIndexHtml) { const publicIndexHtmlFile = path.join( config.rootDir, - options.command === "dev" + command === "dev" ? config.srcDir : path.join(config.distDir, config.publicDir), config.indexHtml, @@ -84,7 +85,7 @@ export function rsc(options: { encoding: "utf8", }); } - if (options.command === "start") { + if (command === "start") { const destFile = path.join( config.rootDir, config.distDir, @@ -97,25 +98,25 @@ export function rsc(options: { } catch (e) { return publicIndexHtml; } - } else { - const vite = await getViteServer(); - for (const item of vite.moduleGraph.idToModuleMap.values()) { - if (item.url === pathStr) { - return null; - } + } + // command === "dev" + const vite = await getViteServer(); + for (const item of vite.moduleGraph.idToModuleMap.values()) { + if (item.url === pathStr) { + return null; } - const destFile = path.join(config.rootDir, config.srcDir, pathStr); - try { - // check if exists? - const stats = await fsPromises.stat(destFile); - if (stats.isFile()) { - return null; - } - } catch (e) { - // does not exist + } + const destFile = path.join(config.rootDir, config.srcDir, pathStr); + try { + // check if exists? + const stats = await fsPromises.stat(destFile); + if (stats.isFile()) { + return null; } - return vite.transformIndexHtml(pathStr, publicIndexHtml); + } catch (e) { + // does not exist } + return vite.transformIndexHtml(pathStr, publicIndexHtml); }; return async (req, res, next) => { @@ -129,7 +130,7 @@ export function rsc(options: { console.info("Cannot render RSC", err); res.statusCode = 500; } - if (options.command === "dev") { + if (command === "dev") { res.end(String(err)); } else { res.end(); @@ -137,26 +138,20 @@ export function rsc(options: { }; let context: Context | undefined; try { - context = options.unstable_prehook?.(req, res); + context = unstable_prehook?.(req, res); } catch (e) { handleError(e); return; } - if (options.ssr) { + if (ssr) { try { const htmlStr = await getHtmlStr(pathStr); const result = htmlStr && - (await renderHtml( - config, - options.command, - pathStr, - htmlStr, - context, - )); + (await renderHtml(config, command, pathStr, htmlStr, context)); if (result) { const [readable, nextCtx] = result; - options.unstable_posthook?.(req, res, nextCtx as Context); + unstable_posthook?.(req, res, nextCtx as Context); readable.on("error", handleError); readable.pipe(res); return; @@ -176,11 +171,11 @@ export function rsc(options: { input: decodeInput(pathStr.slice(basePrefix.length)), method, headers, - command: options.command, + command, context, stream: req, }); - options.unstable_posthook?.(req, res, nextCtx as Context); + unstable_posthook?.(req, res, nextCtx as Context); readable.on("error", handleError); readable.pipe(res); } catch (e) { @@ -188,7 +183,7 @@ export function rsc(options: { } return; } - if (options.command === "dev") { + if (command === "dev") { const vite = await getViteServer(); // HACK re-export "?v=..." URL to avoid dual module hazard. const fname = pathStr.startsWith(config.basePath + "@fs/") diff --git a/packages/waku/src/lib/middleware/rsc/ssr.ts b/packages/waku/src/lib/middleware/rsc/ssr.ts index 5dd599a1c..d42223a65 100644 --- a/packages/waku/src/lib/middleware/rsc/ssr.ts +++ b/packages/waku/src/lib/middleware/rsc/ssr.ts @@ -24,7 +24,6 @@ const { createFromNodeStream } = RSDWClient; type Entries = { default: ReturnType }; let lastViteServer: ViteDevServer | undefined; - const getViteServer = async () => { if (lastViteServer) { return lastViteServer; @@ -326,6 +325,7 @@ export const renderHtml = async ( name, }; } + // command === "dev" const f = file.startsWith("@fs/") ? file.slice(3) : path.join(config.rootDir, config.srcDir, file); diff --git a/packages/waku/src/lib/middleware/rsc/worker-impl.ts b/packages/waku/src/lib/middleware/rsc/worker-impl.ts index 8ea363f04..f7aa95038 100644 --- a/packages/waku/src/lib/middleware/rsc/worker-impl.ts +++ b/packages/waku/src/lib/middleware/rsc/worker-impl.ts @@ -91,7 +91,6 @@ const handleGetBuildConfig = async ( }; let lastViteServer: ViteDevServer | undefined; - const getViteServer = async () => { if (lastViteServer) { return lastViteServer;