Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 14 additions & 5 deletions packages/plugin-rsc/e2e/browser-mode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@ import { expect, test, type Page } from '@playwright/test'
import { useFixture } from './fixture'
import { defineStarterTest } from './starter'

test.describe('dev-browser-mode', () => {
// Webkit fails by
// > TypeError: ReadableByteStreamController is not implemented
test.skip(({ browserName }) => browserName === 'webkit')
// Webkit fails by
// > TypeError: ReadableByteStreamController is not implemented
test.skip(({ browserName }) => browserName === 'webkit')
Comment on lines +5 to +7
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kasperpeulen FYI, I'm not sure what to do about this, but probably this means this setup would be broken on all Safari. I tried web-streams-polyfill but it probably broke other things #807.


test.describe('dev-browser-mode', () => {
const f = useFixture({ root: 'examples/browser-mode', mode: 'dev' })
defineStarterTest(f, 'browser-mode')
defineBrowserModeTest(f)
})

test.describe('build-browser-mode', () => {
const f = useFixture({ root: 'examples/browser-mode', mode: 'build' })
defineStarterTest(f, 'browser-mode')
defineBrowserModeTest(f)
})

function defineBrowserModeTest(f: ReturnType<typeof useFixture>) {
// action-bind tests copied from basic.test.ts

test('action bind simple', async ({ page }) => {
Expand Down Expand Up @@ -71,4 +80,4 @@ test.describe('dev-browser-mode', () => {
.getByRole('button', { name: 'test-server-action-bind-reset' })
.click()
}
})
}
4 changes: 2 additions & 2 deletions packages/plugin-rsc/examples/browser-mode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "false && vite build",
"preview": "false && vite preview"
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ import {
encodeReply,
} from '@vitejs/plugin-rsc/react/browser'
import type { RscPayload } from './entry.rsc'
import buildClientReferences from 'virtual:vite-rsc-browser-mode/build-client-references'

let fetchServer: typeof import('./entry.rsc').fetchServer

export function initialize(options: { fetchServer: typeof fetchServer }) {
fetchServer = options.fetchServer
setRequireModule({
load: (id) => import(/* @vite-ignore */ id),
load: (id) => {
if (import.meta.env.__vite_rsc_build__) {
const import_ = buildClientReferences[id]
if (!import_) {
throw new Error(`invalid client reference: ${id}`)
}
return import_()
} else {
return import(/* @vite-ignore */ id)
}
},
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import type React from 'react'
import { Root } from '../root'
import type { ReactFormState } from 'react-dom/client'
import buildServerReferences from 'virtual:vite-rsc-browser-mode/build-server-references'

export type RscPayload = {
root: React.ReactNode
Expand All @@ -20,7 +21,19 @@ export type RscPayload = {
declare let __vite_rsc_raw_import__: (id: string) => Promise<unknown>

export function initialize() {
setRequireModule({ load: (id) => __vite_rsc_raw_import__(id) })
setRequireModule({
load: (id) => {
if (import.meta.env.__vite_rsc_build__) {
const import_ = buildServerReferences[id]
if (!import_) {
throw new Error(`invalid server reference: ${id}`)
}
return import_()
} else {
return __vite_rsc_raw_import__(/* @vite-ignore */ id)
}
},
})
}

export async function fetchServer(request: Request): Promise<Response> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner'

export default async function loadClient() {
const runner = new ModuleRunner(
{
sourcemapInterceptor: false,
transport: {
invoke: async (payload) => {
const response = await fetch(
'/@vite/invoke-react-client?' +
new URLSearchParams({
data: JSON.stringify(payload),
}),
)
return response.json()
},
},
hmr: false,
},
new ESModulesEvaluator(),
)
return await runner.import<typeof import('./entry.browser')>(
'/src/framework/entry.browser.tsx',
)
}
28 changes: 2 additions & 26 deletions packages/plugin-rsc/examples/browser-mode/src/framework/main.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner'
import * as server from './entry.rsc'
import loadClient from 'virtual:vite-rsc-browser-mode/load-client'

async function main() {
const client = await importClient()
const client = await loadClient()
server.initialize()
client.initialize({ fetchServer: server.fetchServer })
await client.main()
}

async function importClient() {
const runner = new ModuleRunner(
{
sourcemapInterceptor: false,
transport: {
invoke: async (payload) => {
const response = await fetch(
'/@vite/invoke-react-client?' +
new URLSearchParams({
data: JSON.stringify(payload),
}),
)
return response.json()
},
},
hmr: false,
},
new ESModulesEvaluator(),
)
return await runner.import<typeof import('./entry.browser')>(
'/src/framework/entry.browser.tsx',
)
}

main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
declare module 'virtual:vite-rsc-browser-mode/build-client-references' {
const default_: Record<string, () => Promise<any>>
export default default_
}

declare module 'virtual:vite-rsc-browser-mode/build-server-references' {
const default_: Record<string, () => Promise<any>>
export default default_
}

declare module 'virtual:vite-rsc-browser-mode/load-client' {
const default_: () => Promise<typeof import('./entry.browser')>
export default default_
}
Loading
Loading