From dbc3d29725b0d163857e5c5e814970fcf3bf94c7 Mon Sep 17 00:00:00 2001 From: daishi Date: Fri, 29 Dec 2023 10:03:15 +0900 Subject: [PATCH] fix various issues with an example --- e2e/fixtures/ssr-basic/src/main.tsx | 2 +- examples/01_counter/src/main.tsx | 2 +- examples/02_async/src/main.tsx | 2 +- examples/03_promise/src/main.tsx | 2 +- examples/04_callserver/src/main.tsx | 2 +- examples/05_mutation/src/main.tsx | 2 +- examples/06_nesting/src/main.tsx | 2 +- examples/07_router/src/main.tsx | 2 +- examples/08_cookies/src/main.tsx | 2 +- examples/09_cssmodules/.env.local | 1 + examples/09_cssmodules/src/components/App.tsx | 1 + .../09_cssmodules/src/components/Counter.tsx | 1 + examples/09_cssmodules/src/main.tsx | 2 +- examples/10_dynamicroute/src/main.tsx | 2 +- examples/11_form/src/main.tsx | 2 +- examples/12_css/src/main.tsx | 2 +- packages/waku/src/lib/builder/build.ts | 3 +- .../waku/src/lib/handlers/dev-worker-api.ts | 1 + .../waku/src/lib/handlers/dev-worker-impl.ts | 85 ++++++++++--------- packages/waku/src/lib/handlers/handler-dev.ts | 4 +- .../src/lib/plugins/vite-plugin-rsc-env.ts | 30 ++++--- .../waku/src/lib/renderers/html-renderer.ts | 3 +- packages/website/src/main.tsx | 2 +- 23 files changed, 88 insertions(+), 69 deletions(-) create mode 100644 examples/09_cssmodules/.env.local diff --git a/e2e/fixtures/ssr-basic/src/main.tsx b/e2e/fixtures/ssr-basic/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/e2e/fixtures/ssr-basic/src/main.tsx +++ b/e2e/fixtures/ssr-basic/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/01_counter/src/main.tsx b/examples/01_counter/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/01_counter/src/main.tsx +++ b/examples/01_counter/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/02_async/src/main.tsx b/examples/02_async/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/02_async/src/main.tsx +++ b/examples/02_async/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/03_promise/src/main.tsx b/examples/03_promise/src/main.tsx index 99fbdddc2..dce443795 100644 --- a/examples/03_promise/src/main.tsx +++ b/examples/03_promise/src/main.tsx @@ -12,7 +12,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/04_callserver/src/main.tsx b/examples/04_callserver/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/04_callserver/src/main.tsx +++ b/examples/04_callserver/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/05_mutation/src/main.tsx b/examples/05_mutation/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/05_mutation/src/main.tsx +++ b/examples/05_mutation/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/06_nesting/src/main.tsx b/examples/06_nesting/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/06_nesting/src/main.tsx +++ b/examples/06_nesting/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/07_router/src/main.tsx b/examples/07_router/src/main.tsx index 1792a845f..93b72ef52 100644 --- a/examples/07_router/src/main.tsx +++ b/examples/07_router/src/main.tsx @@ -12,7 +12,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/08_cookies/src/main.tsx b/examples/08_cookies/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/08_cookies/src/main.tsx +++ b/examples/08_cookies/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/09_cssmodules/.env.local b/examples/09_cssmodules/.env.local new file mode 100644 index 000000000..44cd37bb6 --- /dev/null +++ b/examples/09_cssmodules/.env.local @@ -0,0 +1 @@ +WAKU_PUBLIC_HELLO="Hello from env file" diff --git a/examples/09_cssmodules/src/components/App.tsx b/examples/09_cssmodules/src/components/App.tsx index 01b0ca7a5..ead9d7c3e 100644 --- a/examples/09_cssmodules/src/components/App.tsx +++ b/examples/09_cssmodules/src/components/App.tsx @@ -9,6 +9,7 @@ const App = ({ name }: { name: string }) => {

Hello {name}!!

This is a server component.

+ Env: {import.meta.env.WAKU_PUBLIC_HELLO} ); }; diff --git a/examples/09_cssmodules/src/components/Counter.tsx b/examples/09_cssmodules/src/components/Counter.tsx index 45146ca6c..cecffcdaa 100644 --- a/examples/09_cssmodules/src/components/Counter.tsx +++ b/examples/09_cssmodules/src/components/Counter.tsx @@ -9,6 +9,7 @@ export const Counter = () => {

Count: {count}

This is a client component.

+ Env: {import.meta.env.WAKU_PUBLIC_HELLO} ); }; diff --git a/examples/09_cssmodules/src/main.tsx b/examples/09_cssmodules/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/09_cssmodules/src/main.tsx +++ b/examples/09_cssmodules/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/10_dynamicroute/src/main.tsx b/examples/10_dynamicroute/src/main.tsx index 1792a845f..93b72ef52 100644 --- a/examples/10_dynamicroute/src/main.tsx +++ b/examples/10_dynamicroute/src/main.tsx @@ -12,7 +12,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/11_form/src/main.tsx b/examples/11_form/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/11_form/src/main.tsx +++ b/examples/11_form/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/examples/12_css/src/main.tsx b/examples/12_css/src/main.tsx index 182bd1bf3..bc436da93 100644 --- a/examples/12_css/src/main.tsx +++ b/examples/12_css/src/main.tsx @@ -10,7 +10,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement); diff --git a/packages/waku/src/lib/builder/build.ts b/packages/waku/src/lib/builder/build.ts index ebe7c61c0..6083d142e 100644 --- a/packages/waku/src/lib/builder/build.ts +++ b/packages/waku/src/lib/builder/build.ts @@ -159,6 +159,7 @@ const buildServerBundle = async ( }, serverEntryFiles, }), + rscEnvPlugin({ config }), ], ssr: { resolve: { @@ -260,7 +261,7 @@ const buildClientBundle = async ( plugins: [ patchReactRefresh(viteReact()), rscIndexPlugin({ ...config, cssAssets }), - rscEnvPlugin({ config, ssr }), + rscEnvPlugin({ config, hydrate: ssr }), ], build: { outDir: joinPath(rootDir, config.distDir, config.publicDir), diff --git a/packages/waku/src/lib/handlers/dev-worker-api.ts b/packages/waku/src/lib/handlers/dev-worker-api.ts index 441fefe4d..ade6f4cd2 100644 --- a/packages/waku/src/lib/handlers/dev-worker-api.ts +++ b/packages/waku/src/lib/handlers/dev-worker-api.ts @@ -12,6 +12,7 @@ export type RenderRequest = { context: unknown; stream?: ReadableStream; moduleIdCallback?: (id: string) => void; + env: Record; }; export type BuildOutput = { diff --git a/packages/waku/src/lib/handlers/dev-worker-impl.ts b/packages/waku/src/lib/handlers/dev-worker-impl.ts index d9189b209..2f76e84f3 100644 --- a/packages/waku/src/lib/handlers/dev-worker-impl.ts +++ b/packages/waku/src/lib/handlers/dev-worker-impl.ts @@ -4,6 +4,7 @@ import { pathToFileURL } from 'node:url'; import { parentPort } from 'node:worker_threads'; import { Server } from 'node:http'; import { createServer as createViteServer } from 'vite'; +import type { ViteDevServer } from 'vite'; import type { EntriesDev } from '../../server.js'; import type { ResolvedConfig } from '../config.js'; @@ -17,6 +18,7 @@ import type { import { renderRsc } from '../renderers/rsc-renderer.js'; import { nonjsResolvePlugin } from '../plugins/vite-plugin-nonjs-resolve.js'; import { rscTransformPlugin } from '../plugins/vite-plugin-rsc-transform.js'; +import { rscEnvPlugin } from '../plugins/vite-plugin-rsc-env.js'; import { rscReloadPlugin } from '../plugins/vite-plugin-rsc-reload.js'; import { rscDelegatePlugin } from '../plugins/vite-plugin-rsc-delegate.js'; import { mergeUserViteConfig } from '../utils/merge-vite-config.js'; @@ -31,6 +33,7 @@ const controllerMap = new Map(); const handleRender = async (mesg: MessageReq & { type: 'render' }) => { const { id, type: _removed, hasModuleIdCallback, ...rest } = mesg; const rr: RenderRequest = rest; + (globalThis as any).__WAKU_PRIVATE_ENV__ = rr.env || {}; try { const stream = new ReadableStream({ start(controller) { @@ -89,52 +92,56 @@ const handleRender = async (mesg: MessageReq & { type: 'render' }) => { } }; -const dummyServer = new Server(); // FIXME we hope to avoid this hack - -const moduleImports: Set = new Set(); - -const mergedViteConfig = await mergeUserViteConfig({ - plugins: [ - nonjsResolvePlugin(), - rscTransformPlugin({ isBuild: false }), - rscReloadPlugin(moduleImports, (type) => { - const mesg: MessageRes = { type }; - parentPort!.postMessage(mesg); - }), - rscDelegatePlugin(moduleImports, (resultOrSource) => { - const mesg: MessageRes = - typeof resultOrSource === 'object' - ? { type: 'module-import', result: resultOrSource } - : { type: 'hot-import', source: resultOrSource }; - parentPort!.postMessage(mesg); - }), - ], - // HACK to suppress 'Skipping dependency pre-bundling' warning - optimizeDeps: { include: [] }, - ssr: { - resolve: { - conditions: ['react-server', 'workerd'], - externalConditions: ['react-server', 'workerd'], +let lastViteServer: ViteDevServer | undefined; +const getViteServer = async () => { + if (lastViteServer) { + return lastViteServer; + } + const dummyServer = new Server(); // FIXME we hope to avoid this hack + const moduleImports: Set = new Set(); + const mergedViteConfig = await mergeUserViteConfig({ + plugins: [ + nonjsResolvePlugin(), + rscTransformPlugin({ isBuild: false }), + rscEnvPlugin({}), + rscReloadPlugin(moduleImports, (type) => { + const mesg: MessageRes = { type }; + parentPort!.postMessage(mesg); + }), + rscDelegatePlugin(moduleImports, (resultOrSource) => { + const mesg: MessageRes = + typeof resultOrSource === 'object' + ? { type: 'module-import', result: resultOrSource } + : { type: 'hot-import', source: resultOrSource }; + parentPort!.postMessage(mesg); + }), + ], + // HACK to suppress 'Skipping dependency pre-bundling' warning + optimizeDeps: { include: [] }, + ssr: { + resolve: { + conditions: ['react-server', 'workerd'], + externalConditions: ['react-server', 'workerd'], + }, + external: ['react', 'react-server-dom-webpack'], + noExternal: /^(?!node:)/, }, - external: ['react', 'react-server-dom-webpack'], - noExternal: /^(?!node:)/, - }, - appType: 'custom', - server: { middlewareMode: true, hmr: { server: dummyServer } }, -}); - -const vitePromise = createViteServer(mergedViteConfig).then(async (vite) => { - await vite.ws.close(); - return vite; -}); + appType: 'custom', + server: { middlewareMode: true, hmr: { server: dummyServer } }, + }); + const viteServer = await createViteServer(mergedViteConfig); + await viteServer.ws.close(); + lastViteServer = viteServer; + return viteServer; +}; const loadServerFile = async (fileURL: string) => { - const vite = await vitePromise; + const vite = await getViteServer(); return vite.ssrLoadModule(fileURLToFilePath(fileURL)); }; const loadEntries = async (config: ResolvedConfig) => { - const vite = await vitePromise; + const vite = await getViteServer(); const filePath = joinPath(vite.config.root, config.srcDir, config.entriesJs); return vite.ssrLoadModule(filePath) as Promise; }; diff --git a/packages/waku/src/lib/handlers/handler-dev.ts b/packages/waku/src/lib/handlers/handler-dev.ts index 29e93a3bb..691ba1179 100644 --- a/packages/waku/src/lib/handlers/handler-dev.ts +++ b/packages/waku/src/lib/handlers/handler-dev.ts @@ -56,7 +56,7 @@ export function createHandler< patchReactRefresh(viteReact()), rscIndexPlugin(config), rscHmrPlugin(), - rscEnvPlugin({ config, ssr }), + rscEnvPlugin({ config, hydrate: ssr }), ], ssr: { external: ['waku'], @@ -149,6 +149,7 @@ export function createHandler< contentType: undefined, config, context, + env: (globalThis as any).__WAKU_PRIVATE_ENV__, }); context = nextCtx as Context; return readable; @@ -184,6 +185,7 @@ export function createHandler< config, context, stream: req.stream, + env: (globalThis as any).__WAKU_PRIVATE_ENV__, }); unstable_posthook?.(req, res, nextCtx as Context); readable.pipeTo(res.stream); diff --git a/packages/waku/src/lib/plugins/vite-plugin-rsc-env.ts b/packages/waku/src/lib/plugins/vite-plugin-rsc-env.ts index 76080cf86..05bde0128 100644 --- a/packages/waku/src/lib/plugins/vite-plugin-rsc-env.ts +++ b/packages/waku/src/lib/plugins/vite-plugin-rsc-env.ts @@ -2,13 +2,13 @@ import type { Plugin } from 'vite'; export function rscEnvPlugin({ config, - ssr, + hydrate, }: { - config: { + config?: { basePath: string; rscPath: string; }; - ssr: boolean | undefined; + hydrate?: boolean | undefined; }): Plugin { return { name: 'rsc-env-plugin', @@ -22,16 +22,20 @@ export function rscEnvPlugin({ ? [[`import.meta.env.${k}`, JSON.stringify(v)]] : [], ), - [ - 'import.meta.env.WAKU_CONFIG_BASE_PATH', - JSON.stringify(config.basePath), - ], - [ - 'import.meta.env.WAKU_CONFIG_RSC_PATH', - JSON.stringify(config.rscPath), - ], - ...(ssr - ? [['import.meta.env.WAKU_SSR_ENABLED', JSON.stringify('true')]] + ...(config + ? [ + [ + 'import.meta.env.WAKU_CONFIG_BASE_PATH', + JSON.stringify(config.basePath), + ], + [ + 'import.meta.env.WAKU_CONFIG_RSC_PATH', + JSON.stringify(config.rscPath), + ], + ] + : []), + ...(hydrate + ? [['import.meta.env.WAKU_HYDRATE', JSON.stringify('true')]] : []), ]), }; diff --git a/packages/waku/src/lib/renderers/html-renderer.ts b/packages/waku/src/lib/renderers/html-renderer.ts index be634acf6..9822a5308 100644 --- a/packages/waku/src/lib/renderers/html-renderer.ts +++ b/packages/waku/src/lib/renderers/html-renderer.ts @@ -50,8 +50,9 @@ const getViteServer = async () => { const { nonjsResolvePlugin } = await import( '../plugins/vite-plugin-nonjs-resolve.js' ); + const { rscEnvPlugin } = await import('../plugins/vite-plugin-rsc-env.js'); const viteServer = await createViteServer({ - plugins: [nonjsResolvePlugin()], + plugins: [nonjsResolvePlugin(), rscEnvPlugin({})], // HACK to suppress 'Skipping dependency pre-bundling' warning optimizeDeps: { include: [] }, ssr: { diff --git a/packages/website/src/main.tsx b/packages/website/src/main.tsx index 1792a845f..93b72ef52 100644 --- a/packages/website/src/main.tsx +++ b/packages/website/src/main.tsx @@ -12,7 +12,7 @@ const rootElement = ( ); -if (import.meta.env.WAKU_SSR_ENABLED) { +if (import.meta.env.WAKU_HYDRATE) { hydrateRoot(document.body, rootElement); } else { createRoot(document.body).render(rootElement);