diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index 45fea171ddcc1e..4bbd79cd5cc2f6 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -1,5 +1,4 @@ import { extname } from 'node:path' -import { parse as parseUrl } from 'node:url' import type { ModuleInfo, PartialResolvedId } from 'rollup' import { isDirectCSSRequest } from '../plugins/css' import { @@ -237,10 +236,16 @@ export class ModuleGraph { url = removeImportQuery(removeTimestampQuery(url)) const resolved = await this.resolveId(url, !!ssr) const resolvedId = resolved?.id || url - const ext = extname(cleanUrl(resolvedId)) - const { pathname, search, hash } = parseUrl(url) - if (ext && !pathname!.endsWith(ext)) { - url = pathname + ext + (search || '') + (hash || '') + if ( + url !== resolvedId && + !url.includes('\0') && + !url.startsWith(`virtual:`) + ) { + const ext = extname(cleanUrl(resolvedId)) + const { pathname, search, hash } = new URL(url, 'relative://') + if (ext && !pathname!.endsWith(ext)) { + url = pathname + ext + search + hash + } } return [url, resolvedId, resolved?.meta] } diff --git a/playground/resolve/index.html b/playground/resolve/index.html index a1befcc2757348..bca49d55388e27 100644 --- a/playground/resolve/index.html +++ b/playground/resolve/index.html @@ -76,6 +76,9 @@

Monorepo linked dep

Plugin resolved virtual file

+

Plugin resolved virtual file (#9036)

+

+

Plugin resolved custom virtual file

@@ -221,6 +224,9 @@

resolve package that contains # in path

import { msg as virtualMsg } from '@virtual-file' text('.virtual', virtualMsg) + import { msg as virtualMsg9036 } from 'virtual:file-9036.js' + text('.virtual-9036', virtualMsg9036) + import { msg as customVirtualMsg } from '@custom-virtual-file' text('.custom-virtual', customVirtualMsg) diff --git a/playground/resolve/vite.config.js b/playground/resolve/vite.config.js index e2fa303598a26a..b27613eb6bc2ad 100644 --- a/playground/resolve/vite.config.js +++ b/playground/resolve/vite.config.js @@ -4,6 +4,9 @@ const { normalizePath } = require('vite') const virtualFile = '@virtual-file' const virtualId = '\0' + virtualFile +const virtualFile9036 = 'virtual:file-9036.js' +const virtualId9036 = '\0' + virtualFile9036 + const customVirtualFile = '@custom-virtual-file' const { a } = require('./config-dep') @@ -44,6 +47,19 @@ module.exports = { } } }, + { + name: 'virtual-module-9036', + resolveId(id) { + if (id === virtualFile9036) { + return virtualId9036 + } + }, + load(id) { + if (id === virtualId9036) { + return `export const msg = "[success] from virtual file #9036"` + } + } + }, { name: 'custom-resolve', resolveId(id) {