Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
RSC: Add RW env var definitions to Vite config and include FatalError…
…Boundary
  • Loading branch information
Tobbe committed Dec 4, 2023
commit a75ec2935275626754a62a9628d3176d2e1cc860
20 changes: 20 additions & 0 deletions __fixtures__/test-project-rsa/web/src/AboutCounter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client'

import React from 'react'

// @ts-expect-error no types
import styles from './Counter.module.css'
import './Counter.css'

export const AboutCounter = () => {
const [count, setCount] = React.useState(0)

return (
<div style={{ border: '3px blue dashed', margin: '1em', padding: '1em' }}>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<h3 className={styles.header}>This is a client component.</h3>
<p>RSC on client: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
)
}
5 changes: 3 additions & 2 deletions __fixtures__/test-project-rsa/web/src/AboutPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Assets } from '@redwoodjs/vite/assets'
import { ProdRwRscServerGlobal } from '@redwoodjs/vite/rwRscGlobal'

import { Counter } from './Counter'
import { AboutCounter } from './AboutCounter'

import './AboutPage.css'

Expand All @@ -17,7 +17,8 @@ const AboutPage = () => {
<Assets />
<div style={{ border: '3px red dashed', margin: '1em', padding: '1em' }}>
<h1>About Redwood</h1>
<Counter />
<AboutCounter />
<p>RSC on server: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
</div>
)
Expand Down
18 changes: 11 additions & 7 deletions __fixtures__/test-project-rsa/web/src/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { createRoot } from 'react-dom/client'

import { Route, Router, Set } from '@redwoodjs/router'
import { serve } from '@redwoodjs/vite/client'
import { FatalErrorBoundary } from '@redwoodjs/web'

import NavigationLayout from './layouts/NavigationLayout/NavigationLayout'
import FatalErrorPage from './pages/FatalErrorPage/FatalErrorPage'
import NotFoundPage from './pages/NotFoundPage/NotFoundPage'

const redwoodAppElement = document.getElementById('redwood-app')
Expand All @@ -15,13 +17,15 @@ const root = createRoot(redwoodAppElement)

const App = () => {
return (
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
<FatalErrorBoundary page={FatalErrorPage}>
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
</FatalErrorBoundary>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client'

import React from 'react'

// @ts-expect-error no types
import styles from './Counter.module.css'
import './Counter.css'

export const AboutCounter = () => {
const [count, setCount] = React.useState(0)

return (
<div style={{ border: '3px blue dashed', margin: '1em', padding: '1em' }}>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<h3 className={styles.header}>This is a client component.</h3>
<p>RSC on client: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Assets } from '@redwoodjs/vite/assets'
import { ProdRwRscServerGlobal } from '@redwoodjs/vite/rwRscGlobal'

import { Counter } from './Counter'
import { AboutCounter } from './AboutCounter'

import './AboutPage.css'

Expand All @@ -17,7 +17,8 @@ const AboutPage = () => {
<Assets />
<div style={{ border: '3px red dashed', margin: '1em', padding: '1em' }}>
<h1>About Redwood</h1>
<Counter />
<AboutCounter />
<p>RSC on server: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { createRoot } from 'react-dom/client'

import { Route, Router, Set } from '@redwoodjs/router'
import { serve } from '@redwoodjs/vite/client'
import { FatalErrorBoundary } from '@redwoodjs/web'

import NavigationLayout from './layouts/NavigationLayout/NavigationLayout'
import FatalErrorPage from './pages/FatalErrorPage/FatalErrorPage'
import NotFoundPage from './pages/NotFoundPage/NotFoundPage'

const redwoodAppElement = document.getElementById('redwood-app')
Expand All @@ -15,13 +17,15 @@ const root = createRoot(redwoodAppElement)

const App = () => {
return (
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
<FatalErrorBoundary page={FatalErrorPage}>
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
</FatalErrorBoundary>
)
}

Expand Down
19 changes: 19 additions & 0 deletions packages/cli/src/commands/experimental/setupRscHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,25 @@ export const handler = async ({ force, verbose }) => {
})
},
},
{
title: 'Adding AboutCounter.tsx...',
task: async () => {
const counterTemplate = fs.readFileSync(
path.resolve(
__dirname,
'templates',
'rsc',
'AboutCounter.tsx.template'
),
'utf-8'
)
const counterPath = path.join(rwPaths.web.src, 'AboutCounter.tsx')

writeFile(counterPath, counterTemplate, {
overwriteExisting: force,
})
},
},
{
title: 'Adding CSS files...',
task: async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client'

import React from 'react'

// @ts-expect-error no types
import styles from './Counter.module.css'
import './Counter.css'

export const AboutCounter = () => {
const [count, setCount] = React.useState(0)

return (
<div style={{ border: '3px blue dashed', margin: '1em', padding: '1em' }}>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<h3 className={styles.header}>This is a client component.</h3>
<p>RSC on client: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Assets } from '@redwoodjs/vite/assets'
import { ProdRwRscServerGlobal } from '@redwoodjs/vite/rwRscGlobal'

import { Counter } from './Counter'
import { AboutCounter } from './AboutCounter'

import './AboutPage.css'

Expand All @@ -17,7 +17,8 @@ const AboutPage = () => {
<Assets />
<div style={{ border: '3px red dashed', margin: '1em', padding: '1em' }}>
<h1>About Redwood</h1>
<Counter />
<AboutCounter />
<p>RSC on server: {globalThis.RWJS_EXP_RSC ? 'enabled' : 'disabled'}</p>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { createRoot } from 'react-dom/client'

import { Route, Router, Set } from '@redwoodjs/router'
import { serve } from '@redwoodjs/vite/client'
import { FatalErrorBoundary } from '@redwoodjs/web'

import NavigationLayout from './layouts/NavigationLayout/NavigationLayout'
import FatalErrorPage from './pages/FatalErrorPage/FatalErrorPage'
import NotFoundPage from './pages/NotFoundPage/NotFoundPage'

const redwoodAppElement = document.getElementById('redwood-app')
Expand All @@ -15,13 +17,15 @@ const root = createRoot(redwoodAppElement)

const App = () => {
return (
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
<FatalErrorBoundary page={FatalErrorPage}>
<Router>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
</Set>
<Route notfound page={NotFoundPage} />
</Router>
</FatalErrorBoundary>
)
}

Expand Down
56 changes: 56 additions & 0 deletions packages/vite/src/rsc/rscBuildClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import path from 'node:path'

import react from '@vitejs/plugin-react'
import { build as viteBuild } from 'vite'

import { getConfig, getPaths } from '@redwoodjs/project-config'

import { onWarn } from '../lib/onWarn'
import { rscIndexPlugin } from '../waku-lib/vite-plugin-rsc'

Expand All @@ -15,9 +19,61 @@ export async function rscBuildClient(
webDist: string,
clientEntryFiles: Record<string, string>
) {
const rwPaths = getPaths()
const rwConfig = getConfig()

const clientBuildOutput = await viteBuild({
// configFile: viteConfigPath,
root: webSrc,
envPrefix: 'REDWOOD_ENV_',
publicDir: path.join(rwPaths.web.base, 'public'),
define: {
RWJS_ENV: {
// @NOTE we're avoiding process.env here, unlike webpack
RWJS_API_GRAPHQL_URL:
rwConfig.web.apiGraphQLUrl ?? rwConfig.web.apiUrl + '/graphql',
RWJS_API_URL: rwConfig.web.apiUrl,
__REDWOOD__APP_TITLE: rwConfig.web.title || path.basename(rwPaths.base),
RWJS_EXP_STREAMING_SSR:
rwConfig.experimental.streamingSsr &&
rwConfig.experimental.streamingSsr.enabled,
RWJS_EXP_RSC: rwConfig.experimental?.rsc?.enabled,
},
RWJS_DEBUG_ENV: {
RWJS_SRC_ROOT: rwPaths.web.src,
REDWOOD_ENV_EDITOR: JSON.stringify(process.env.REDWOOD_ENV_EDITOR),
},
// Vite can automatically expose environment variables, but we
// disable that in `buildFeServer.ts` by setting `envFile: false`
// because we want to use our own logic for loading .env,
// .env.defaults, etc
// The two object spreads below will expose all environment
// variables listed in redwood.toml and all environment variables
// prefixed with REDWOOD_ENV_
...Object.fromEntries(
rwConfig.web.includeEnvironmentVariables.flatMap((envName) => [
// TODO (RSC): Figure out if/why we need to disable eslint here.
// Re-enable if possible
// eslint-disable-next-line
[`import.meta.env.${envName}`, JSON.stringify(process.env[envName])],
// TODO (RSC): Figure out if/why we need to disable eslint here
// Re-enable if possible
// eslint-disable-next-line
[`process.env.${envName}`, JSON.stringify(process.env[envName])],
])
),
...Object.entries(process.env).reduce<Record<string, any>>(
(acc, [key, value]) => {
if (key.startsWith('REDWOOD_ENV_')) {
acc[`import.meta.env.${key}`] = JSON.stringify(value)
acc[`process.env.${key}`] = JSON.stringify(value)
}

return acc
},
{}
),
},
plugins: [react(), rscIndexPlugin()],
build: {
outDir: webDist,
Expand Down