@@ -4,14 +4,11 @@ import express from 'express'
44import { createServer as createViteServer } from 'vite'
55
66import { getProjectRoutes } from '@redwoodjs/internal/dist/routes'
7- import { getAppRouteHook , getConfig , getPaths } from '@redwoodjs/project-config'
8- import { matchPath } from '@redwoodjs/router'
9- import type { TagDescriptor } from '@redwoodjs/web'
7+ import { getConfig , getPaths } from '@redwoodjs/project-config'
108
9+ import { createReactStreamingHandler } from './streaming/createReactStreamingHandler'
1110import { registerFwGlobals } from './streaming/registerGlobals'
12- import { reactRenderToStream } from './streaming/streamHelpers'
13- import { loadAndRunRouteHooks } from './streaming/triggerRouteHooks'
14- import { ensureProcessDirWeb , stripQueryStringAndHashFromPath } from './utils'
11+ import { ensureProcessDirWeb } from './utils'
1512
1613// TODO (STREAMING) Just so it doesn't error out. Not sure how to handle this.
1714globalThis . __REDWOOD__PRERENDER_PAGES = { }
@@ -24,14 +21,24 @@ async function createServer() {
2421 const app = express ( )
2522 const rwPaths = getPaths ( )
2623
24+ // ~~~ Dev time validations ~~~~
2725 // TODO (STREAMING) When Streaming is released Vite will be the only bundler,
2826 // and this file should always exist. So the error message needs to change
2927 // (or be removed perhaps)
28+ if ( ! rwPaths . web . entryServer || ! rwPaths . web . entryClient ) {
29+ throw new Error (
30+ 'Vite entry points not found. Please check that your project has ' +
31+ 'an entry.client.{jsx,tsx} and entry.server.{jsx,tsx} file in ' +
32+ 'the web/src directory.'
33+ )
34+ }
35+
3036 if ( ! rwPaths . web . viteConfig ) {
3137 throw new Error (
3238 'Vite config not found. You need to setup your project with Vite using `yarn rw setup vite`'
3339 )
3440 }
41+ // ~~~~ Dev time validations ~~~~
3542
3643 // Create Vite server in middleware mode and configure the app type as
3744 // 'custom', disabling Vite's own HTML serving logic so parent server
@@ -47,89 +54,35 @@ async function createServer() {
4754 // use vite's connect instance as middleware
4855 app . use ( vite . middlewares )
4956
50- app . use ( '*' , async ( req , res , next ) => {
51- const currentPathName = stripQueryStringAndHashFromPath ( req . originalUrl )
52- globalThis . __REDWOOD__HELMET_CONTEXT = { }
53-
54- try {
55- const routes = getProjectRoutes ( )
56-
57- // Do a simple match with regex, don't bother parsing params yet
58- const currentRoute = routes . find ( ( route ) => {
59- if ( ! route . matchRegexString ) {
60- // This is the 404/NotFoundPage case
61- return false
62- }
63-
64- const matches = [
65- ...currentPathName . matchAll ( new RegExp ( route . matchRegexString , 'g' ) ) ,
66- ]
67-
68- return matches . length > 0
69- } )
70-
71- let metaTags : TagDescriptor [ ] = [ ]
72-
73- if ( currentRoute ?. redirect ) {
74- return res . redirect ( currentRoute . redirect . to )
75- }
76-
77- if ( currentRoute ) {
78- const parsedParams = currentRoute . hasParams
79- ? matchPath ( currentRoute . path , currentPathName ) . params
80- : undefined
81-
82- const routeHookOutput = await loadAndRunRouteHooks ( {
83- paths : [ getAppRouteHook ( ) , currentRoute . routeHooks ] ,
84- reqMeta : {
85- req,
86- parsedParams,
87- } ,
88- viteDevServer : vite , // because its dev
89- } )
90-
91- metaTags = routeHookOutput . meta
92- }
93-
94- if ( ! currentRoute ) {
95- // TODO (STREAMING) do something
96- }
97-
98- if ( ! rwPaths . web . entryServer || ! rwPaths . web . entryClient ) {
99- throw new Error (
100- 'Vite entry points not found. Please check that your project has ' +
101- 'an entry.client.{jsx,tsx} and entry.server.{jsx,tsx} file in ' +
102- 'the web/src directory.'
103- )
104- }
105-
106- // 3. Load the server entry. vite.ssrLoadModule automatically transforms
107- // your ESM source code to be usable in Node.js! There is no bundling
108- // required, and provides efficient invalidation similar to HMR.
109- const { ServerEntry } = await vite . ssrLoadModule ( rwPaths . web . entryServer )
110-
111- const pageWithJs = currentRoute ?. renderMode !== 'html'
112-
113- res . setHeader ( 'content-type' , 'text/html; charset=utf-8' )
114-
115- reactRenderToStream ( {
116- ServerEntry,
117- currentPathName,
118- metaTags,
119- includeJs : pageWithJs ,
120- res,
121- } )
122- } catch ( e ) {
123- // TODO (STREAMING) Is this what we want to do?
124- // send back a SPA page
125- // res.status(200).set({ 'Content-Type': 'text/html' }).end(template)
126-
127- // If an error is caught, let Vite fix the stack trace so it maps back to
128- // your actual source code.
129- vite . ssrFixStacktrace ( e as any )
130- next ( e )
57+ const routes = getProjectRoutes ( )
58+
59+ // TODO (STREAMING) CSS is handled by Vite in dev mode, we don't need to
60+ // worry about it in dev but..... it causes a flash of unstyled content.
61+ // For now I'm just injecting index css here
62+ // Look at collectStyles in packages/vite/src/fully-react/find-styles.ts
63+ const FIXME_HardcodedIndexCss = [ 'index.css' ]
64+
65+ for ( const route of routes ) {
66+ const routeHandler = await createReactStreamingHandler (
67+ {
68+ route,
69+ clientEntryPath : rwPaths . web . entryClient as string ,
70+ cssLinks : FIXME_HardcodedIndexCss ,
71+ } ,
72+ vite
73+ )
74+
75+ // @TODO if it is a 404, hand over to 404 handler
76+ if ( ! route . matchRegexString ) {
77+ continue
13178 }
132- } )
79+
80+ const expressPathDef = route . hasParams
81+ ? route . matchRegexString
82+ : route . pathDefinition
83+
84+ app . get ( expressPathDef , routeHandler )
85+ }
13386
13487 const port = getConfig ( ) . web . port
13588 console . log ( `Started server on http://localhost:${ port } ` )
@@ -141,7 +94,9 @@ let devApp = createServer()
14194process . stdin . on ( 'data' , async ( data ) => {
14295 const str = data . toString ( ) . trim ( ) . toLowerCase ( )
14396 if ( str === 'rs' || str === 'restart' ) {
144- ; ( await devApp ) . close ( )
145- devApp = createServer ( )
97+ console . log ( 'Restarting dev web server.....' )
98+ ; ( await devApp ) . close ( ( ) => {
99+ devApp = createServer ( )
100+ } )
146101 }
147102} )
0 commit comments