Skip to content

Commit

Permalink
chore(client-entry): Slight tweaks around entry.client handling (#10741)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe committed Jun 6, 2024
1 parent 9303d26 commit 1866d6f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 30 deletions.
2 changes: 1 addition & 1 deletion packages/vite/src/rsc/rscBuildClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function rscBuildClient(clientEntryFiles: Record<string, string>) {
input: {
// @MARK: temporary hack to find the entry client so we can get the
// index.css bundle but we don't actually want this on an rsc page!
'rwjs-client-entry': rwPaths.web.entryClient,
__rwjs__client_entry: rwPaths.web.entryClient,
// we need this, so that the output contains rsc-specific bundles
// for the client-only components. They get loaded once the page is
// rendered
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/rsc/rscBuildForSsr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export async function rscBuildForSsr({
// index.css bundle but we don't actually want this on an rsc page!
// TODO (RSC): Look into if we can remove this (and perhaps instead
// use entry.server)
'rwjs-client-entry': rwPaths.web.entryClient,
__rwjs__client_entry: rwPaths.web.entryClient,
'entry.server': rwPaths.web.entryServer,
// we need this, so that the output contains rsc-specific bundles
// for the client-only components. They get loaded once the page is
Expand Down
40 changes: 24 additions & 16 deletions packages/vite/src/runFeServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,29 @@ export async function runFeServer() {
await import(clientBuildManifestUrl, { with: { type: 'json' } })
).default

// @MARK: Surely there's a better way than this!
const clientEntry = Object.values(clientBuildManifest).find(
(manifestItem) => {
// For RSC builds, we pass in many Vite entries, so we need to find it differently.
return rscEnabled
? manifestItem.file.includes('rwjs-client-entry-')
: manifestItem.isEntry
},
)
// Even though `entry.server.tsx` is the main entry point for SSR, we still
// need to read the client build manifest and find `entry.client.tsx` to get
// the correct links to insert for the initial CSS files that will eventually
// be rendered when the finalized html output is being streamed to the
// browser. We also need it to tell React what JS bundle contains
// `hydrateRoot` when it'll eventually get to hydrating things in the browser
//
// So, `clientEntry` is used to find the initial JS bundle to load in the
// browser and also to discover CSS files that will be needed to render the
// initial page.
//
// In addition to all the above the discovered CSS files are also passed to
// all middleware that have been registered
const clientEntry = rscEnabled
? clientBuildManifest['entry.client.tsx'] ||
clientBuildManifest['entry.client.jsx']
: Object.values(clientBuildManifest).find(
(manifestItem) => manifestItem.isEntry,
)

if (!clientEntry) {
throw new Error('Could not find client entry in build manifest')
}

// @MARK: In prod, we create it once up front!
const middlewareRouter = await createMiddlewareRouter()
Expand All @@ -111,10 +125,6 @@ export async function runFeServer() {
})
}

if (!clientEntry) {
throw new Error('Could not find client entry in build manifest')
}

// 1. Use static handler for assets
// For CF workers, we'd need an equivalent of this
app.use(
Expand Down Expand Up @@ -166,15 +176,13 @@ export async function runFeServer() {
// the static assets over any application routing.
app.use(express.static(rwPaths.web.distClient, { index: false }))

const clientEntryPath = '/' + clientEntry.file

const getStylesheetLinks = rscEnabled
? getRscStylesheetLinkGenerator(clientEntry.css)
: () => clientEntry.css || []

const routeHandler = await createReactStreamingHandler({
routes: Object.values(routeManifest),
clientEntryPath,
clientEntryPath: clientEntry.file,
getStylesheetLinks,
getMiddlewareRouter: async () => middlewareRouter,
})
Expand Down
25 changes: 13 additions & 12 deletions packages/vite/src/streaming/createReactStreamingHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,19 @@ export const createReactStreamingHandler = async (
route.pathDefinition,
currentUrl.pathname,
)

if (match) {
currentRoute = route
parsedParams = rest

break
}
}

// Using a function to get the CSS links because we need to wait for the
// vite dev server to analyze the module graph
const cssLinks = getStylesheetLinks(currentRoute)

// ~~~ Middleware Handling ~~~
if (middlewareRouter) {
const matchedMw = middlewareRouter.find(req.method as HTTPMethod, req.url)
Expand All @@ -107,7 +113,7 @@ export const createReactStreamingHandler = async (
matchedMw?.handler as Middleware | undefined,
{
route: currentRoute,
cssPaths: getStylesheetLinks(currentRoute),
cssPaths: cssLinks,
params: matchedMw?.params,
viteDevServer,
},
Expand Down Expand Up @@ -172,20 +178,15 @@ export const createReactStreamingHandler = async (

metaTags = routeHookOutput.meta

// @MARK @TODO(RSC_DC): the entry path for RSC will be different,
// because we don't want to inject a full bundle, just a slice of it
// I'm not sure what though....
const jsBundles = [
clientEntryPath, // @NOTE: must have slash in front
currentRoute.bundle && '/' + currentRoute.bundle,
].filter(Boolean) as string[]
// TODO (RSC): Do we really want to inject the full bundle here, or is
// there a smaller slice of it we can inject?
const jsBundles = ['/' + clientEntryPath]
if (currentRoute.bundle) {
jsBundles.push('/' + currentRoute.bundle)
}

const isSeoCrawler = isbot(req.headers.get('user-agent') || '')

// Using a function to get the CSS links because we need to wait for the
// vite dev server to analyze the module graph
const cssLinks = getStylesheetLinks(currentRoute)

const reactResponse = await reactRenderToStreamResponse(
mwResponse,
{
Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/streaming/streamHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export async function reactRenderToStreamResponse(
clearTimeout(timeoutHandle)
}
}

function applyStreamTransforms(
reactStream: ReactDOMServerReadableStream,
transformsToApply: (TransformStream | false)[],
Expand Down

0 comments on commit 1866d6f

Please sign in to comment.