diff --git a/packages/vite/src/waku-lib/build-server.ts b/packages/vite/src/waku-lib/build-server.ts index ea63c97b12f4..2ff6dfe70201 100644 --- a/packages/vite/src/waku-lib/build-server.ts +++ b/packages/vite/src/waku-lib/build-server.ts @@ -1,4 +1,6 @@ // TODO (RSC) Take ownership of this file and move it out ouf the waku-lib folder +import path from 'node:path' + import react from '@vitejs/plugin-react' import { build as viteBuild } from 'vite' @@ -12,14 +14,6 @@ export async function serverBuild( serverEntryFiles: Record, customModules: Record ) { - // const noExternal = Array.from(clientEntryFileSet).map( - // // FIXME this might not work with pnpm - // (fname) => - // path - // .relative(path.join(config.root, "node_modules"), fname) - // .split("/")[0]! - // ); - // const input = { entries: entriesFile, ...clientEntryFiles, @@ -35,19 +29,30 @@ export async function serverBuild( // ...configFileConfig, root: rwPaths.web.base, ssr: { - // Externalize everything except files that have 'use client' in them - // (this includes packages in node_modules that you use that have - // 'use client' in them) + // Externalize everything except packages with files that have + // 'use client' in them // Files included in `noExternal` are files we want Vite to analyze - noExternal: Object.values(clientEntryFiles), - // TODO (RSC) This is the original code from waku. I think we can simplify it as above - // The code below will for most basic cases just be `[ '..' ]`, which we - // believe to be overly broad - // noExternal: Object.values(clientEntryFiles).map((fname) => { - // return path - // .relative(path.join(rwPaths.base, 'node_modules'), fname) - // .split('/')[0] - // }), + // The values in the array here are compared to npm package names, like + // 'react', 'core-js', @anthropic-ai/sdk', @redwoodjs/vite', etc + // The map function below will return '..' for local files. That's not + // very pretty, but it works. It just won't match anything. + noExternal: Object.values(clientEntryFiles).map((fname) => { + const relativePath = path.relative( + path.join(rwPaths.base, 'node_modules'), + fname + ) + const splitPath = relativePath.split('/') + + // TODO (RSC): Verify this is correct. Need to find a scoped packages + // that uses 'use client' + // Handle scoped packages + if (relativePath.startsWith('@')) { + return splitPath[0] + '/' + splitPath[1] + } + + // Packages without scope + return splitPath[0] + }), }, plugins: [react()], resolve: { diff --git a/packages/vite/src/waku-lib/builder.ts b/packages/vite/src/waku-lib/builder.ts index f8374ddb47cb..95acfac199d7 100644 --- a/packages/vite/src/waku-lib/builder.ts +++ b/packages/vite/src/waku-lib/builder.ts @@ -49,6 +49,7 @@ export async function build() { ), ], ssr: { + // TODO (RSC): Is this still relevant? // FIXME Without this, waku/router isn't considered to have client // entries, and "No client entry" error occurs. // Unless we fix this, RSC-capable packages aren't supported. diff --git a/packages/vite/src/waku-lib/rsc-handler-worker.ts b/packages/vite/src/waku-lib/rsc-handler-worker.ts index f52971d87f6b..c1e1cb7d0617 100644 --- a/packages/vite/src/waku-lib/rsc-handler-worker.ts +++ b/packages/vite/src/waku-lib/rsc-handler-worker.ts @@ -238,12 +238,15 @@ const resolveClientEntry = ( filePath: string ) => { const clientEntry = absoluteClientEntries[filePath] + if (!clientEntry) { if (absoluteClientEntries['*'] === '*') { return config.base + path.relative(config.root, filePath) } + throw new Error('No client entry found for ' + filePath) } + return clientEntry }