Skip to content

fix(rsc): replace ?v= check with more robust node_modules detection #696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
29 changes: 18 additions & 11 deletions packages/plugin-rsc/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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=<hash>` 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=<hash>" from client optimizer in client reference can make a hashed
Expand All @@ -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') {
Expand Down Expand Up @@ -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) =>
Expand All @@ -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))
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-rsc/src/plugins/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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, '')
}
Loading