diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 7bba9b1a..1181c7d1 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -32,7 +32,11 @@ import { } from './transforms' import { generateEncryptionKey, toBase64 } from './utils/encryption-utils' import { createRpcServer } from './utils/rpc' -import { normalizeViteImportAnalysisUrl, prepareError } from './vite-utils' +import { + cleanUrl, + normalizeViteImportAnalysisUrl, + prepareError, +} from './vite-utils' import { cjsModuleRunnerPlugin } from './plugins/cjs' import { evalValue, parseIdQuery } from './plugins/utils' @@ -959,9 +963,12 @@ function vitePluginUseClient( let importId: string let referenceKey: string const packageSource = packageSources.get(id) - if (!packageSource && id.includes('?v=')) { - assert(this.environment.mode === 'dev') - // If non package source `?v=` reached here, this is a client boundary + if ( + !packageSource && + this.environment.mode === 'dev' && + id.includes('/node_modules/') + ) { + // If non package source reached here (often with ?v=... query), this is a client boundary // created by a package imported on server environment, which breaks the // expectation on dependency optimizer on browser. Directly copying over // "?v=" from client optimizer in client reference can make a hashed @@ -978,9 +985,7 @@ function vitePluginUseClient( `[vite-rsc] detected an internal client boundary created by a package imported on rsc environment`, ) } - importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent( - id.split('?v=')[0]!, - )}` + importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent(cleanUrl(id))}` referenceKey = importId } else if (packageSource) { if (this.environment.mode === 'dev') { @@ -1223,8 +1228,10 @@ function vitePluginUseServer( let normalizedId_: string | undefined const getNormalizedId = () => { if (!normalizedId_) { - if (id.includes('?v=')) { - assert(this.environment.mode === 'dev') + if ( + this.environment.mode === 'dev' && + id.includes('/node_modules/') + ) { const ignored = useServerPluginOptions.ignoredPackageWarnings?.some( (pattern) => @@ -1238,8 +1245,8 @@ function vitePluginUseServer( ) } // module runner has additional resolution step and it's not strict about - // module identity of `import(id)` like browser, so we simply strip it off. - id = id.split('?v=')[0]! + // module identity of `import(id)` like browser, so we simply strip queries such as `?v=`. + id = cleanUrl(id) } if (config.command === 'build') { normalizedId_ = hashString(path.relative(config.root, id)) diff --git a/packages/plugin-rsc/src/plugins/utils.ts b/packages/plugin-rsc/src/plugins/utils.ts index 5628fad5..a544a58e 100644 --- a/packages/plugin-rsc/src/plugins/utils.ts +++ b/packages/plugin-rsc/src/plugins/utils.ts @@ -19,3 +19,9 @@ export function parseIdQuery(id: string): { const query = Object.fromEntries(new URLSearchParams(rawQuery)) return { filename, query } } + +// https://github.com/vitejs/vite/blob/946831f986cb797009b8178659d2b31f570c44ff/packages/vite/src/shared/utils.ts#L31-L34 +const postfixRE = /[?#].*$/ +export function cleanUrl(url: string): string { + return url.replace(postfixRE, '') +}