11import { existsSync , promises as fs } from 'node:fs'
2- import { dirname } from 'pathe'
2+ import { dirname , isAbsolute , join } from 'pathe'
33import { createBirpc } from 'birpc'
44import { parse , stringify } from 'flatted'
55import type { WebSocket } from 'ws'
@@ -8,11 +8,12 @@ import type { BrowserCommandContext } from 'vitest/node'
88import { createDebugger , isFileServingAllowed } from 'vitest/node'
99import type { WebSocketBrowserEvents , WebSocketBrowserHandlers } from './types'
1010import type { BrowserServer } from './server'
11- import { resolveMock } from './resolveMock'
11+ import { cleanUrl , resolveMock } from './resolveMock'
1212
1313const debug = createDebugger ( 'vitest:browser:api' )
1414
1515const BROWSER_API_PATH = '/__vitest_browser_api__'
16+ const VALID_ID_PREFIX = '/@id/'
1617
1718export function setupBrowserRpc (
1819 server : BrowserServer ,
@@ -118,14 +119,44 @@ export function setupBrowserRpc(
118119 ctx . cancelCurrentRun ( reason )
119120 } ,
120121 async resolveId ( id , importer ) {
121- const result = await project . server . pluginContainer . resolveId (
122+ const resolved = await vite . pluginContainer . resolveId (
122123 id ,
123124 importer ,
124125 {
125126 ssr : false ,
126127 } ,
127128 )
128- return result
129+ if ( ! resolved ) {
130+ return null
131+ }
132+ const isOptimized = resolved . id . startsWith ( withTrailingSlash ( vite . config . cacheDir ) )
133+ let url : string
134+ // normalise the URL to be acceptible by the browser
135+ // https://github.com/vitejs/vite/blob/e833edf026d495609558fd4fb471cf46809dc369/packages/vite/src/node/plugins/importAnalysis.ts#L335
136+ const root = vite . config . root
137+ if ( resolved . id . startsWith ( withTrailingSlash ( root ) ) ) {
138+ url = resolved . id . slice ( root . length )
139+ }
140+ else if (
141+ resolved . id !== '/@react-refresh'
142+ && isAbsolute ( resolved . id )
143+ && existsSync ( cleanUrl ( resolved . id ) )
144+ ) {
145+ url = join ( '/@fs/' , resolved . id )
146+ }
147+ else {
148+ url = resolved . id
149+ }
150+ if ( url [ 0 ] !== '.' && url [ 0 ] !== '/' ) {
151+ url = id . startsWith ( VALID_ID_PREFIX )
152+ ? id
153+ : VALID_ID_PREFIX + id . replace ( '\0' , '__x00__' )
154+ }
155+ return {
156+ id : resolved . id ,
157+ url,
158+ optimized : isOptimized ,
159+ }
129160 } ,
130161 debug ( ...args ) {
131162 ctx . logger . console . debug ( ...args )
@@ -242,3 +273,11 @@ export function stringifyReplace(key: string, value: any) {
242273 return value
243274 }
244275}
276+
277+ function withTrailingSlash ( path : string ) : string {
278+ if ( path [ path . length - 1 ] !== '/' ) {
279+ return `${ path } /`
280+ }
281+
282+ return path
283+ }
0 commit comments