Skip to content

Commit

Permalink
fix(vite-node): normalize drive letter to keep the same reference to …
Browse files Browse the repository at this point in the history
…a module (#3836)
  • Loading branch information
sheremet-va committed Jul 29, 2023
1 parent 54409a2 commit 4552185
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
13 changes: 13 additions & 0 deletions packages/vite-node/src/utils.ts
Expand Up @@ -6,6 +6,15 @@ import type { Arrayable, Nullable } from './types'

export const isWindows = process.platform === 'win32'

const drive = isWindows ? process.cwd()[0] : null
const driveOpposite = drive
? (drive === drive.toUpperCase()
? drive.toLowerCase()
: drive.toUpperCase())
: null
const driveRegexp = drive ? new RegExp(`(?:^|/@fs/)${drive}(\:[\\/])`) : null
const driveOppositeRegext = driveOpposite ? new RegExp(`(?:^|/@fs/)${driveOpposite}(\:[\\/])`) : null

export function slash(str: string) {
return str.replace(/\\/g, '/')
}
Expand All @@ -16,6 +25,10 @@ export function normalizeRequestId(id: string, base?: string): string {
if (base && id.startsWith(base))
id = `/${id.slice(base.length)}`

// keep drive the same as in process cwd
if (driveRegexp && !driveRegexp?.test(id) && driveOppositeRegext?.test(id))
id = id.replace(driveOppositeRegext, `${drive}$1`)

return id
.replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0`
.replace(/^\/@id\//, '')
Expand Down
1 change: 1 addition & 0 deletions test/core/src/esm/esm.js
@@ -0,0 +1 @@
export const test = 1
3 changes: 3 additions & 0 deletions test/core/src/esm/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}
34 changes: 33 additions & 1 deletion test/core/test/imports.test.ts
@@ -1,6 +1,7 @@
import { mkdir, writeFile } from 'node:fs/promises'
import { fileURLToPath } from 'node:url'
import { resolve } from 'pathe'
import { describe, expect, test } from 'vitest'
import { describe, expect, test, vi } from 'vitest'
import { dynamicRelativeImport } from '../src/relative-import'

// @ts-expect-error module is not typed
Expand Down Expand Up @@ -130,3 +131,34 @@ describe('importing special files from node_modules', async () => {
expect(mod.default).toBe('/src/node_modules/file.mp3')
})
})

describe.runIf(process.platform === 'win32')('importing files with different drive casing', async () => {
test('importing a local file with different drive casing works', async () => {
const path = new URL('./../src/timeout', import.meta.url)
const filepath = fileURLToPath(path)
const drive = filepath[0].toLowerCase()
const upperDrive = drive.toUpperCase()
const lowercasePath = filepath.replace(`${upperDrive}:`, `${drive}:`)
const uppercasePath = filepath.replace(`${drive}:`, `${upperDrive}:`)
expect(lowercasePath).not.toBe(uppercasePath)
const mod1 = await import(lowercasePath)
const mod2 = await import(uppercasePath)
const mod3 = await import('./../src/timeout')
expect(mod1).toBe(mod2)
expect(mod1).toBe(mod3)
})

test('importing an external file with different drive casing works', async () => {
const path = new URL('./../src/esm/esm.js', import.meta.url)
const filepath = fileURLToPath(path)
const drive = filepath[0].toLowerCase()
const upperDrive = drive.toUpperCase()
const lowercasePath = filepath.replace(`${upperDrive}:`, `${drive}:`)
const uppercasePath = filepath.replace(`${drive}:`, `${upperDrive}:`)
expect(lowercasePath).not.toBe(uppercasePath)
const mod1 = await import(lowercasePath)
vi.resetModules() // since they reference the same global ESM cache, it should not matter
const mod2 = await import(uppercasePath)
expect(mod1).toBe(mod2)
})
})
2 changes: 1 addition & 1 deletion test/core/vitest.config.ts
Expand Up @@ -66,7 +66,7 @@ export default defineConfig({
seed: 101,
},
deps: {
external: ['tinyspy', /src\/external/],
external: ['tinyspy', /src\/external/, /esm\/esm/],
inline: ['inline-lib'],
moduleDirectories: ['node_modules', 'projects', 'packages'],
},
Expand Down

0 comments on commit 4552185

Please sign in to comment.