Skip to content

Commit

Permalink
chore(rsc): upgrade to react canary (#10194)
Browse files Browse the repository at this point in the history
Want to see how CI reacts to upgrading to React canary. ~I may have
over-upgraded (i.e. some fixtures and maybe the docs don't need to be
upgraded), but let's see what happens.~

This upgrade was complicated by
facebook/react#27436 which added a poisoned
import to `react-server-dom-webpack/server`, meaning that if you tried
to import from that entry point without the "react-server" condition, it
would throw.

In a much-earlier PR, Sebastian mentions there generally being two ways
to do things:

> Either you can have the server code prebundled using Webpack (what
Next.js does in practice) or you can use an unbundled Node.js server
(what the reference implementation does).

See facebook/react#26172.

This PR goes with the former, prebundling
`react-server-dom-webpack/server` with the "react-server" condition so
that we can avoid having to specify it at runtime. It's hard to tell if
this the better option long-term, but since we're keen on getting rid of
the worker right now, this moves us closer in that direction. The
alternative solution was to move decoding the reply into the worker
where the condition is specified.

---------

Co-authored-by: Tobbe Lundberg <tobbe@tlundberg.com>
  • Loading branch information
jtoar and Tobbe authored Mar 17, 2024
1 parent acbc56d commit 93459f9
Show file tree
Hide file tree
Showing 34 changed files with 241 additions and 152 deletions.
5 changes: 1 addition & 4 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@
"enabled": false,

"matchPackageNames": [
"@apollo/experimental-nextjs-app-support",
"react",
"react-dom",
"react-server-dom-webpack"
"@apollo/experimental-nextjs-app-support"
]
}
]
Expand Down
4 changes: 2 additions & 2 deletions __fixtures__/fragment-test-project/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"@redwoodjs/router": "7.0.0",
"@redwoodjs/web": "7.0.0",
"humanize-string": "2.1.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "7.0.0",
Expand Down
4 changes: 2 additions & 2 deletions __fixtures__/test-project-rsa/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"@redwoodjs/forms": "8.0.0-canary.144",
"@redwoodjs/router": "8.0.0-canary.144",
"@redwoodjs/web": "8.0.0-canary.144",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "8.0.0-canary.144",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"@redwoodjs/web": "7.0.0-canary.1011",
"@tobbe.dev/rsc-test": "0.0.5",
"client-only": "0.0.1",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "7.0.0-canary.1011",
Expand Down
4 changes: 2 additions & 2 deletions __fixtures__/test-project/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"@redwoodjs/router": "7.0.0",
"@redwoodjs/web": "7.0.0",
"humanize-string": "2.1.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "7.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/auth0/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@babel/cli": "7.23.9",
"@babel/core": "^7.22.20",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@babel/core": "^7.22.20",
"@types/netlify-identity-widget": "1.9.6",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/clerk/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@clerk/clerk-react": "4.30.7",
"@clerk/types": "3.60.0",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/dbAuth/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@types/react": "^18.2.55",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3"
},
"gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1"
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/firebase/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"firebase": "10.7.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/netlify/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@babel/core": "^7.22.20",
"@types/netlify-identity-widget": "1.9.6",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/supabase/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@babel/core": "^7.22.20",
"@supabase/supabase-js": "2.39.7",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-providers/supertokens/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@babel/cli": "7.23.9",
"@babel/core": "^7.22.20",
"@types/react": "^18.2.55",
"react": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"supertokens-auth-react": "0.34.0",
"typescript": "5.3.3",
"vitest": "1.3.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"dependencies": {
"@babel/runtime-corejs3": "7.24.0",
"core-js": "3.35.1",
"react": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@babel/cli": "7.23.9",
Expand Down
4 changes: 2 additions & 2 deletions packages/create-redwood-app/templates/js/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"@redwoodjs/forms": "7.0.0",
"@redwoodjs/router": "7.0.0",
"@redwoodjs/web": "7.0.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "7.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/create-redwood-app/templates/ts/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"@redwoodjs/forms": "7.0.0",
"@redwoodjs/router": "7.0.0",
"@redwoodjs/web": "7.0.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"devDependencies": {
"@redwoodjs/vite": "7.0.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/forms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"nodemon": "3.0.2",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314",
"typescript": "5.3.3",
"vitest": "1.3.1"
},
"peerDependencies": {
"react": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314"
},
"gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1"
}
4 changes: 2 additions & 2 deletions packages/prerender/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"vitest": "1.3.1"
},
"peerDependencies": {
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"externals": {
"react": "react",
Expand Down
8 changes: 4 additions & 4 deletions packages/router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@
"@types/react-dom": "^18.2.19",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314",
"tstyche": "1.0.0",
"typescript": "5.3.3"
},
"peerDependencies": {
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913"
"react": "18.3.0-canary-a870b2d54-20240314",
"react-dom": "18.3.0-canary-a870b2d54-20240314"
},
"gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1"
}
2 changes: 2 additions & 0 deletions packages/vite/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ declare global {
var __REDWOOD__PRERENDER_PAGES: any

var __REDWOOD__HELMET_CONTEXT: { helmet?: HelmetServerState }

var __rw_module_cache__: Map<string, unknown>
}

export {}
25 changes: 23 additions & 2 deletions packages/vite/build.mts
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
import { build } from '@redwoodjs/framework-tools'
import { build, defaultIgnorePatterns } from '@redwoodjs/framework-tools'

await build()
import * as esbuild from 'esbuild'

await build({
entryPointOptions: {
ignore: [...defaultIgnorePatterns, '**/bundled'],
}
})

// We bundle some react packages with the "react-server" condition
// so that we don't need to specify it at runtime.

await esbuild.build({
entryPoints: ['src/bundled/*'],
outdir: 'dist/bundled',

bundle: true,
conditions: ['react-server'],
platform: 'node',
target: ['node20'],

logLevel: 'info',
})
63 changes: 61 additions & 2 deletions packages/vite/modules.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
declare module 'react-server-dom-webpack/node-loader'
declare module 'react-server-dom-webpack/server'
declare module 'react-server-dom-webpack/server.node.unbundled'

declare module 'react-server-dom-webpack/client' {
// https://github.com/facebook/react/blob/dfaed5582550f11b27aae967a8e7084202dd2d90/packages/react-server-dom-webpack/src/ReactFlightDOMClientBrowser.js#L31
Expand All @@ -21,5 +19,66 @@ declare module 'react-server-dom-webpack/client' {
): Promise<string | URLSearchParams | FormData>
}

declare module 'react-server-dom-webpack/server' {
import type { Writable } from 'stream'

import type { Busboy } from 'busboy'

// It's difficult to know the true type of `ServerManifest`.
// A lot of react's source files are stubs that are replaced at build time.
// Going off this reference for now: https://github.com/facebook/react/blob/b09e102ff1e2aaaf5eb6585b04609ac7ff54a5c8/packages/react-server-dom-webpack/src/ReactFlightClientConfigBundlerWebpack.js#L40
type ImportManifestEntry = {
id: string
chunks: Array<string>
name: string
}

type ServerManifest = {
[id: string]: ImportManifestEntry
}

// The types for `decodeReply` and `decodeReplyFromBusboy` were taken from
// https://github.com/facebook/react/blob/b09e102ff1e2aaaf5eb6585b04609ac7ff54a5c8/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js
// which is what 'react-server-dom-webpack/server' resolves to with the 'react-server' condition.

/**
* WARNING: The types for this were handwritten by looking at React's source and could be wrong.
*/
export function decodeReply<T>(
body: string | FormData,
webpackMap?: ServerManifest,
): Promise<T>

/**
* WARNING: The types for this were handwritten by looking at React's source and could be wrong.
*/
export function decodeReplyFromBusboy<T>(
busboyStream: Busboy,
webpackMap?: ServerManifest,
): Promise<T>

type ClientReferenceManifestEntry = ImportManifestEntry

type ClientManifest = {
[id: string]: ClientReferenceManifestEntry
}

type PipeableStream = {
abort(reason: any): void
pipe<T extends Writable>(destination: T): T
}

// The types for `renderToPipeableStream` are incomplete and were taken from
// https://github.com/facebook/react/blob/b09e102ff1e2aaaf5eb6585b04609ac7ff54a5c8/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js#L75.

/**
* WARNING: The types for this were handwritten by looking at React's source and could be wrong.
*/
export function renderToPipeableStream(
model: ReactClientValue,
webpackMap: ClientManifest,
): PipeableStream
}

declare module 'acorn-loose'
declare module 'vite-plugin-cjs-interop'
4 changes: 2 additions & 2 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@
"express": "4.18.2",
"http-proxy-middleware": "2.0.6",
"isbot": "3.7.1",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-server-dom-webpack": "0.0.0-experimental-e5205658f-20230913",
"react": "18.3.0-canary-a870b2d54-20240314",
"react-server-dom-webpack": "18.3.0-canary-a870b2d54-20240314",
"vite": "5.1.6",
"vite-plugin-cjs-interop": "2.1.0",
"yargs-parser": "21.1.1"
Expand Down
7 changes: 7 additions & 0 deletions packages/vite/src/bundled/react-server-dom-webpack.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// We bundle out these functions with the "react-server" condition
// so that we don't need to specify it at runtime.

export {
decodeReply,
decodeReplyFromBusboy,
} from 'react-server-dom-webpack/server'
4 changes: 2 additions & 2 deletions packages/vite/src/devFeServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { getProjectRoutes } from '@redwoodjs/internal/dist/routes'
import type { Paths } from '@redwoodjs/project-config'
import { getConfig, getPaths } from '@redwoodjs/project-config'

import { registerFwGlobals } from './lib/registerGlobals.js'
import { registerFwGlobalsAndShims } from './lib/registerFwGlobalsAndShims.js'
import { invoke } from './middleware/invokeMiddleware.js'
import { createRscRequestHandler } from './rsc/rscRequestHandler.js'
import { collectCssPaths, componentsModules } from './streaming/collectCss.js'
Expand All @@ -27,7 +27,7 @@ globalThis.__REDWOOD__PRERENDER_PAGES = {}
async function createServer() {
ensureProcessDirWeb()

registerFwGlobals()
registerFwGlobalsAndShims()

const app = express()
const rwPaths = getPaths()
Expand Down
2 changes: 0 additions & 2 deletions packages/vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { getConfig, getPaths } from '@redwoodjs/project-config'
import { getMergedConfig } from './lib/getMergedConfig.js'
import handleJsAsJsx from './plugins/vite-plugin-jsx-loader.js'
import removeFromBundle from './plugins/vite-plugin-remove-from-bundle.js'
import { rscTransformEntryPlugin } from './plugins/vite-plugin-rsc-transform-entry.js'
import swapApolloProvider from './plugins/vite-plugin-swap-apollo-provider.js'

/**
Expand Down Expand Up @@ -41,7 +40,6 @@ export default function redwoodPluginVite(): PluginOption[] {
const rscEnabled = rwConfig.experimental.rsc.enabled

return [
rscEnabled && rscTransformEntryPlugin(),
{
name: 'redwood-plugin-vite-html-env',

Expand Down
Loading

0 comments on commit 93459f9

Please sign in to comment.