Skip to content

Commit d4ddde9

Browse files
committed
feat: add realpath function and update resolver to use it
- Introduced a new `realpath` function to resolve symlinks and normalize paths, providing a fallback to normalization on error. - Updated the resolver to utilize `realpath` for directory and file path handling, improving accuracy in path resolution. - Added test fixtures for symlink resolution, including configuration and example files to validate the new functionality.
1 parent 1ca02a3 commit d4ddde9

7 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/path.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as fs from 'node:fs'
12
import * as os from 'node:os'
23
import * as path from 'node:path'
34
import * as vite from 'vite'
@@ -47,4 +48,13 @@ export const basename = (p: NormalizedPath, suffix?: string): NormalizedPath =>
4748
export const dirname = (p: NormalizedPath): NormalizedPath =>
4849
path.dirname(p) as NormalizedPath
4950

51+
/** Resolve symlinks and normalize. Falls back to normalize on error. */
52+
export const realpath = (p: string): NormalizedPath => {
53+
try {
54+
return normalize(fs.realpathSync(p))
55+
} catch {
56+
return normalize(p)
57+
}
58+
}
59+
5060
export const relativeImportRE: RegExp = /^\.\.?(\/|$)/

src/resolver.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export function createTsconfigResolvers({
111111

112112
const addProject = (project: Project, data?: Directory) => {
113113
const tsconfigFile = project.tsconfigFile
114-
const dir = path.normalize(path.dirname(tsconfigFile))
114+
const dir = path.realpath(path.dirname(tsconfigFile))
115115
data ??= directoryCache.get(dir)
116116

117117
// Sanity check
@@ -247,7 +247,7 @@ export function createTsconfigResolvers({
247247
): AsyncIterable<Resolver> {
248248
await initializing
249249

250-
let dir = path.normalize(importer)
250+
let dir = path.realpath(importer)
251251
const { root } = path.parse(dir)
252252
while (dir !== (dir = path.dirname(dir)) && dir !== root) {
253253
let data = directoryCache.get(dir)
@@ -292,7 +292,7 @@ export function createTsconfigResolvers({
292292
watcher.add(tsconfigFile)
293293
}
294294
watcher.on('all', (event, file) => {
295-
const normalizedFile = path.normalize(file)
295+
const normalizedFile = path.realpath(file)
296296
if (
297297
!normalizedFile.endsWith('.json') ||
298298
!path.isAbsolute(normalizedFile)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"root": "link"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
real
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { log } from '~/log'
2+
3+
log('Hello, world!')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const log = console.log.bind(console)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"exclude": ["dist"],
3+
"compilerOptions": {
4+
"module": "esnext",
5+
"moduleResolution": "bundler",
6+
"skipLibCheck": true,
7+
"rootDir": ".",
8+
"paths": {
9+
"~/*": ["./*"]
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)