Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSC: vite/clientSsr #10238

Merged
merged 105 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
93fc69d
RSC: vite/clientSsr
Tobbe Mar 16, 2024
73356ea
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 16, 2024
a973924
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 16, 2024
9670ae4
Add clientSsr export
Tobbe Mar 16, 2024
0d95410
Remove commented out loadModule code
Tobbe Mar 16, 2024
cd3a18f
Comment formatting
Tobbe Mar 16, 2024
bd2091b
webpack shims
Tobbe Mar 16, 2024
151cce8
more shim stuff
Tobbe Mar 16, 2024
9e3c7df
babel plugin changes
Tobbe Mar 16, 2024
34b2691
webpack shims as a vite plugin
Tobbe Mar 16, 2024
4a6f010
fix double auto import for streaming ssr setup
Josh-Walker-GM Mar 17, 2024
b787554
fix(rsc): use query string in rsc url (#10243)
jtoar Mar 16, 2024
a65daf3
fix(rsc): avoid overriding `NODE_ENV` (#10237)
jtoar Mar 16, 2024
c06b2fe
RSC: Use vite plugin to inject webpack shims (#10245)
Tobbe Mar 17, 2024
ec5c8ff
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 17, 2024
6886896
Revert unrelated changed to streamHelpers
Tobbe Mar 17, 2024
a30af78
buildForStreamingServer: inline plugins
Tobbe Mar 17, 2024
fc1f532
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 17, 2024
3a8fbf4
fix previous merge error
Tobbe Mar 17, 2024
ee1116a
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 17, 2024
f72bb45
minimal wip
Tobbe Mar 20, 2024
5978931
minimal wip 2
Tobbe Mar 21, 2024
c795d73
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 21, 2024
604a4cc
renderToReadableStream - no RSC
Tobbe Mar 22, 2024
dad013d
refactor plugins, get build working
Josh-Walker-GM Mar 17, 2024
07711cc
Remove debug console.log
Tobbe Mar 23, 2024
b4d0670
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 23, 2024
8e78ac6
onError error type
Tobbe Mar 23, 2024
a796a40
remove debug log that's not needed anymore
Tobbe Mar 23, 2024
7f2266c
Remove babel plugins that have been replaced by vite plugin
Tobbe Mar 24, 2024
41cf6a1
Always include the react plugin in common RW preset
Tobbe Mar 24, 2024
866f57b
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 24, 2024
8b3fadb
Restore streamHelpers
Tobbe Mar 24, 2024
82916ef
Infer error type
Tobbe Mar 24, 2024
df309ed
Delete empty file
Tobbe Mar 24, 2024
42e4538
Add proper type declaration for react-dom/server.edge
Tobbe Mar 24, 2024
611abe8
Remove stray blank-line
Tobbe Mar 24, 2024
688e88a
Restore more of original streamHelpers
Tobbe Mar 24, 2024
367ffad
Import from clientSsr
Tobbe Mar 24, 2024
a4ef484
clientSsr: Remove RSA code
Tobbe Mar 24, 2024
14d7a54
Remove -minimal file
Tobbe Mar 24, 2024
49fd3f8
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 24, 2024
fc4a5d6
Fix bad merge
Tobbe Mar 24, 2024
fcd94b5
Move console.logs to one place
Tobbe Mar 24, 2024
4859bfb
Restore ssr build
Tobbe Mar 24, 2024
6a30667
Try to incorporate code from minimal repro
Tobbe Mar 24, 2024
d30ff99
Fix build
Tobbe Mar 24, 2024
20351cf
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Mar 24, 2024
987dce6
Minimal streamHelpers changes
Tobbe Mar 24, 2024
00fd040
Use react-server bundle of react-server-dom-webpack/server.edge
Tobbe Mar 24, 2024
a19ed9c
Type react-server-dom-webpack/server.edge import
Tobbe Mar 25, 2024
c076013
Explain stream juggling
Tobbe Mar 25, 2024
aec83b6
importModule() bundled libraries
Tobbe Mar 25, 2024
4187105
Remove commented out code
Tobbe Mar 25, 2024
21cd869
Fix comment grammar
Tobbe Mar 25, 2024
380c7e3
Fix type issue with createElement
Tobbe Mar 25, 2024
b5b8525
Add rsdw to word list
Tobbe Mar 25, 2024
53439cf
clean up getEntries
Tobbe Mar 26, 2024
95005ed
RenderToStreamArgs better types
Tobbe Mar 26, 2024
3cae709
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 2, 2024
bbef2e4
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 4, 2024
e6c38fa
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 8, 2024
7284c48
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 15, 2024
9a7fe19
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 15, 2024
696a198
server-router
Tobbe Apr 4, 2024
2bf5bdd
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 16, 2024
a40a1ad
format web/tsconfig.json
Tobbe Apr 16, 2024
dbafef6
server-router: clean up imports and exports
Tobbe Apr 16, 2024
f0f04b6
Fix imports in tests
Tobbe Apr 16, 2024
c358e17
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 16, 2024
59a6485
limit churn in files
Tobbe Apr 16, 2024
ff7d3d5
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 16, 2024
6b6f140
undo changes to client.ts
Tobbe Apr 16, 2024
0cd97d0
undo changes to createReactStreamingHandler.ts
Tobbe Apr 16, 2024
edf0ec0
Re-enable the css pre-init plugin
Tobbe Apr 16, 2024
7616845
streamHelpers: restore more of the original code
Tobbe Apr 16, 2024
941055e
streamHelpers: rsc specific code flow
Tobbe Apr 16, 2024
f4f6315
Temporarily swallow all getFunctionComponent exceptions
Tobbe Apr 16, 2024
d868def
SSR Document + ServerRoutes
Tobbe Apr 16, 2024
ea4823c
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 17, 2024
25afff5
Use entry.server for RSC
Tobbe Apr 17, 2024
b6af4ee
Add ServerRouter ready templates to RSC setup command
Tobbe Apr 17, 2024
a7e6bc5
Force overwrite during setup
Tobbe Apr 17, 2024
fc06b22
Add ServerEntry to entries.ts.template
Tobbe Apr 17, 2024
622e9d4
Update RSC test fixtures
Tobbe Apr 17, 2024
cc082ad
Add comment explaining importModule
Tobbe Apr 17, 2024
bbf3a9e
Re-enable css plugin
Tobbe Apr 17, 2024
b0b6c8e
Fix mock in test
Tobbe Apr 17, 2024
43689b6
Delay checking for entryServer
Tobbe Apr 17, 2024
8bc4799
Disable rw dev CI test
Tobbe Apr 17, 2024
16008c6
Fix SSR when RSC is not enabled
Tobbe Apr 17, 2024
c92bbdb
Update Document template
Tobbe Apr 17, 2024
57e3096
false instead of disabled
Tobbe Apr 17, 2024
8839f46
Revert streamingSsr Document template update
Tobbe Apr 18, 2024
a839271
streamHelpers: make paths work with Windows
Tobbe Apr 18, 2024
c969da1
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 18, 2024
39c82bd
Use node:url pathToFileURL
Tobbe Apr 18, 2024
6016f05
createMiddlewareRouter.test.ts mock both win and unix
Tobbe Apr 18, 2024
53c1234
fix(filepath): Use node:url to convert to file path
Tobbe Apr 18, 2024
09efb37
Only test with current OS paths
Tobbe Apr 18, 2024
9a42ab6
fix rsdw-server path
Tobbe Apr 18, 2024
bdffa74
Merge branch 'main' into tobbe-rsc-vite-ssr
Tobbe Apr 18, 2024
39fb18b
Remove console logs
Tobbe Apr 18, 2024
0a96ba0
Make paths easier to read
Tobbe Apr 18, 2024
7239922
One more path to convert to file://
Tobbe Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,15 @@ jobs:
REDWOOD_TEST_PROJECT_PATH: ${{ steps.set-up-rsc-project.outputs.rsc-project-path }}
REDWOOD_DISABLE_TELEMETRY: 1

# TODO(jtoar): This workflow times out on Windows. It looks as if the dev server starts up ok,
# but it doesn't seem like the browser is rendering what it should be.
# TODO (RSC): This workflow times out on Windows. It looks as if the dev
# server starts up ok, but it doesn't seem like the browser is rendering
# what it should be. And now it's also started failing on Ubuntu. So I've
# disabled it for now. The error on Ubuntu is:
# Failed to read a RSC payload created by a development version of
# React on the server while using a production version on the client.
# Always use matching versions on the server and the client.
- name: 🐘 Run RSC dev smoke tests
if: matrix.os == 'ubuntu-latest'
if: matrix.os == 'false__ubuntu-latest'
working-directory: tasks/smoke-tests/rsc-dev
run: npx playwright test
env:
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"pino",
"Pistorius",
"redwoodjs",
"rsdw",
"RWJS",
"tailwindcss",
"waku"
Expand Down
4 changes: 2 additions & 2 deletions __fixtures__/test-project-rsa/web/src/Document.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'

import { Css, Meta } from '@redwoodjs/web'
import type { TagDescriptor } from '@redwoodjs/web'
import { Css, Meta } from '@redwoodjs/web/dist/components/htmlTags'
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

interface DocumentProps {
children: React.ReactNode
Expand Down
2 changes: 2 additions & 0 deletions __fixtures__/test-project-rsa/web/src/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default defineEntries(
return import('./pages/AboutPage/AboutPage')
case 'HomePage':
return import('./pages/HomePage/HomePage')
case 'ServerEntry':
return import('./entry.server')
default:
return null
}
Expand Down
5 changes: 2 additions & 3 deletions __fixtures__/test-project-rsa/web/src/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { TagDescriptor } from '@redwoodjs/web'
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

import App from './App'
import { Document } from './Document'

interface Props {
Expand All @@ -11,7 +10,7 @@ interface Props {
export const ServerEntry: React.FC<Props> = ({ css, meta }) => {
return (
<Document css={css} meta={meta}>
<App />
<div>App</div>
</Document>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'

import { Css, Meta } from '@redwoodjs/web'
import type { TagDescriptor } from '@redwoodjs/web'
import { Css, Meta } from '@redwoodjs/web/dist/components/htmlTags'
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

interface DocumentProps {
children: React.ReactNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default defineEntries(
return import('./pages/EmptyUser/NewEmptyUserPage/NewEmptyUserPage')
case 'MultiCellPage':
return import('./pages/MultiCellPage/MultiCellPage')
case 'ServerEntry':
return import('./entry.server')
default:
return null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { TagDescriptor } from '@redwoodjs/web'
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

import App from './App'
import { Document } from './Document'

interface Props {
Expand All @@ -11,7 +10,7 @@ interface Props {
export const ServerEntry: React.FC<Props> = ({ css, meta }) => {
return (
<Document css={css} meta={meta}>
<App />
<div>App</div>
</Document>
)
}
51 changes: 50 additions & 1 deletion packages/cli/src/commands/experimental/setupRscHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { prettify } from '@redwoodjs/cli-helpers'
import { getConfig, getConfigPath } from '@redwoodjs/project-config'
import { errorTelemetry } from '@redwoodjs/telemetry'

import { getPaths, writeFile } from '../../lib'
import { getPaths, transformTSToJS, writeFile } from '../../lib'
import c from '../../lib/colors'
import { isTypeScriptProject } from '../../lib/project'

Expand All @@ -18,6 +18,7 @@ export const handler = async ({ force, verbose }) => {
const rwPaths = getPaths()
const redwoodTomlPath = getConfigPath()
const configContent = fs.readFileSync(redwoodTomlPath, 'utf-8')
const ext = path.extname(rwPaths.web.entryClient || '')

const tasks = new Listr(
[
Expand Down Expand Up @@ -90,6 +91,54 @@ export const handler = async ({ force, verbose }) => {
})
},
},
{
title: `Overwriting entry.server${ext}...`,
task: async () => {
const entryServerTemplate = fs.readFileSync(
path.resolve(
__dirname,
'templates',
'rsc',
'entry.server.tsx.template',
),
'utf-8',
)
// Can't use rwPaths.web.entryServer because it might not be not created yet
const entryServerPath = path.join(
rwPaths.web.src,
`entry.server${ext}`,
)
const entryServerContent = isTypeScriptProject()
? entryServerTemplate
: transformTSToJS(entryServerPath, entryServerTemplate)

writeFile(entryServerPath, entryServerContent, {
overwriteExisting: true,
})
},
},
{
title: `Overwriting Document${ext}...`,
task: async () => {
const documentTemplate = fs.readFileSync(
path.resolve(
__dirname,
'templates',
'rsc',
'Document.tsx.template',
),
'utf-8',
)
const documentPath = path.join(rwPaths.web.src, `Document${ext}`)
const documentContent = isTypeScriptProject()
? documentTemplate
: transformTSToJS(documentPath, documentTemplate)

writeFile(documentPath, documentContent, {
overwriteExisting: true,
})
},
},
{
title: 'Adding Pages...',
task: async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react'

import { Css, Meta } from '@redwoodjs/web/dist/components/htmlTags'
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

interface DocumentProps {
children: React.ReactNode
css: string[] // array of css import strings
meta?: TagDescriptor[]
}

export const Document: React.FC<DocumentProps> = ({ children, css, meta }) => {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/favicon.png" />
<Css css={css} />
<Meta tags={meta} />
</head>
<body>
<div id="redwood-app">{children}</div>
</body>
</html>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default defineEntries(
return import('./pages/AboutPage/AboutPage')
case 'HomePage':
return import('./pages/HomePage/HomePage')
case 'ServerEntry':
return import('./entry.server')
default:
return null
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

import { Document } from './Document'

interface Props {
css: string[]
meta?: TagDescriptor[]
}

export const ServerEntry: React.FC<Props> = ({ css, meta }) => {
return (
<Document css={css} meta={meta}>
<div>App</div>
</Document>
)
}
28 changes: 28 additions & 0 deletions packages/project-config/src/__tests__/paths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ describe('paths', () => {
'server',
'entry.server.mjs',
),
distRscEntryServer: path.join(
FIXTURE_BASEDIR,
'web',
'dist',
'rsc',
'entry.server.mjs',
),
distRouteHooks: path.join(
FIXTURE_BASEDIR,
'web',
Expand Down Expand Up @@ -425,6 +432,13 @@ describe('paths', () => {
'server',
'entry.server.mjs',
),
distRscEntryServer: path.join(
FIXTURE_BASEDIR,
'web',
'dist',
'rsc',
'entry.server.mjs',
),
distDocumentServer: path.join(
FIXTURE_BASEDIR,
'web',
Expand Down Expand Up @@ -751,6 +765,13 @@ describe('paths', () => {
'server',
'entry.server.mjs',
),
distRscEntryServer: path.join(
FIXTURE_BASEDIR,
'web',
'dist',
'rsc',
'entry.server.mjs',
),
distDocumentServer: path.join(
FIXTURE_BASEDIR,
'web',
Expand Down Expand Up @@ -1028,6 +1049,13 @@ describe('paths', () => {
'server',
'entry.server.mjs',
),
distRscEntryServer: path.join(
FIXTURE_BASEDIR,
'web',
'dist',
'rsc',
'entry.server.mjs',
),
distDocumentServer: path.join(
FIXTURE_BASEDIR,
'web',
Expand Down
2 changes: 2 additions & 0 deletions packages/project-config/src/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export interface WebPaths {
distRsc: string
distServer: string
distEntryServer: string
distRscEntryServer: string
distDocumentServer: string
distRouteHooks: string
distRscEntries: string
Expand Down Expand Up @@ -250,6 +251,7 @@ export const getPaths = (BASE_DIR: string = getBaseDir()): Paths => {
BASE_DIR,
PATH_WEB_DIR_DIST_SERVER_ENTRY_SERVER,
),
distRscEntryServer: path.join(BASE_DIR, 'web/dist/rsc/entry.server.mjs'),
distDocumentServer: path.join(BASE_DIR, PATH_WEB_DIR_DIST_DOCUMENT),
distRouteHooks: path.join(BASE_DIR, PATH_WEB_DIR_DIST_SERVER_ROUTEHOOKS),
distRscEntries: path.join(BASE_DIR, PATH_WEB_DIR_DIST_RSC_ENTRIES),
Expand Down
44 changes: 44 additions & 0 deletions packages/router/src/server-route-loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { Suspense } from 'react'

import type { Spec } from './page'

interface Props {
path: string
spec: Spec
params?: Record<string, string>
whileLoadingPage?: () => React.ReactNode | null
children?: React.ReactNode
}

export const ActiveRouteLoader = ({ spec, params }: Props) => {
const LazyRouteComponent = spec.LazyComponent

// Delete params ref & key so that they are not spread on to the component
if (params) {
delete params['ref']
delete params['key']
}

return (
<Suspense fallback={<div>Loading...</div>}>
<LazyRouteComponent {...params} />
<div
id="redwood-announcer"
style={{
position: 'absolute',
top: 0,
width: 1,
height: 1,
padding: 0,
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
whiteSpace: 'nowrap',
border: 0,
}}
role="alert"
aria-live="assertive"
aria-atomic="true"
></div>
</Suspense>
)
}
Loading
Loading