Skip to content

Commit

Permalink
refactor: add vite-tsconfig-paths:resolve debug logs
Browse files Browse the repository at this point in the history
These are fine-grained logs related to the `resolveId` plugin hook.

Enable them with DEBUG="vite-tsconfig-paths:resolve".
  • Loading branch information
aleclarson committed Nov 19, 2024
1 parent 6430b46 commit 7160d6e
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 48 deletions.
4 changes: 4 additions & 0 deletions src/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import createDebug from 'debug'

export const debug = createDebug('vite-tsconfig-paths')
export const debugResolve = createDebug('vite-tsconfig-paths:resolve')
125 changes: 77 additions & 48 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { normalizePath, Plugin, searchForWorkspaceRoot } from 'vite'
import { resolvePathMappings } from './mappings'
import { basename, dirname, isAbsolute, join, relative } from './path'
import { PluginOptions } from './types'

const debug = _debug('vite-tsconfig-paths')
import { debug, debugResolve } from './debug'

const noMatch = [undefined, false] as [undefined, false]

Expand Down Expand Up @@ -161,36 +160,52 @@ export default (opts: PluginOptions = {}): Plugin => {
})
},
async resolveId(id, importer, options) {
if (importer && !relativeImportRE.test(id) && !isAbsolute(id)) {
// For Vite 4 and under, skipSelf needs to be set.
const resolveOptions = { ...options, skipSelf: true }
const viteResolve: ViteResolve = async (id, importer) =>
(await this.resolve(id, importer, resolveOptions))?.id

let prevProjectDir: string | undefined
let projectDir = normalizePath(dirname(importer))

// Find the nearest directory with a matching tsconfig file.
loop: while (projectDir && projectDir != prevProjectDir) {
const resolvers = resolversByDir[projectDir]
if (resolvers)
for (const resolve of resolvers) {
const [resolved, matched] = await resolve(
viteResolve,
id,
importer
)
if (resolved) {
return resolved
}
if (matched) {
// Once a matching resolver is found, stop looking.
break loop
}
if (debugResolve.enabled) {
debugResolve('resolving:', { id, importer })
}

if (!importer) {
debugResolve('importer is empty or undefined. skipping...')
return
}
if (relativeImportRE.test(id)) {
debugResolve('id is a relative import. skipping...')
return
}
if (isAbsolute(id)) {
debugResolve('id is an absolute path. skipping...')
return
}
if (id.includes('\0')) {
debugResolve('id is a virtual module. skipping...')
return
}

// For Vite 4 and under, skipSelf needs to be set.
const resolveOptions = { ...options, skipSelf: true }
const viteResolve: ViteResolve = async (id, importer) =>
(await this.resolve(id, importer, resolveOptions))?.id

let prevProjectDir: string | undefined
let projectDir = normalizePath(dirname(importer))

// Find the nearest directory with a matching tsconfig file.
loop: while (projectDir && projectDir != prevProjectDir) {
const resolvers = resolversByDir[projectDir]
if (resolvers) {
for (const resolve of resolvers) {
const [resolved, matched] = await resolve(viteResolve, id, importer)
if (resolved) {
return resolved
}
prevProjectDir = projectDir
projectDir = dirname(prevProjectDir)
if (matched) {
// Once a matching resolver is found, stop looking.
break loop
}
}
}
prevProjectDir = projectDir
projectDir = dirname(prevProjectDir)
}
},
}
Expand Down Expand Up @@ -231,7 +246,11 @@ export default (opts: PluginOptions = {}): Plugin => {
) => Promise<string | undefined>

const resolveWithBaseUrl: InternalResolver | undefined = baseUrl
? (viteResolve, id, importer) => viteResolve(join(baseUrl, id), importer)
? (viteResolve, id, importer) => {
const absoluteId = join(baseUrl, id)
debugResolve('trying with baseUrl:', absoluteId)
return viteResolve(absoluteId, importer)
}
: undefined

let resolveId: InternalResolver
Expand Down Expand Up @@ -259,6 +278,7 @@ export default (opts: PluginOptions = {}): Plugin => {
const matchIndex = Math.min(++starCount, match.length - 1)
return match[matchIndex]
})
debugResolve('found match, trying to resolve:', mappedId)
const resolved = await viteResolve(mappedId, importer)
if (resolved) {
return resolved
Expand Down Expand Up @@ -301,23 +321,24 @@ export default (opts: PluginOptions = {}): Plugin => {
: /\.[mc]?tsx?$/

const resolutionCache = new Map<string, string>()
return async (viteResolve, id, importer) => {
// Skip virtual modules.
if (id.includes('\0')) {
return noMatch
}

return async (viteResolve, id, importer) => {
// Ideally, Vite would normalize the importer path for us.
importer = normalizePath(importer)

// Remove query and hash parameters from the importer path.
const importerFile = importer.replace(/[#?].+$/, '')

// Ignore importers with unsupported extensions.
if (!importerExtRE.test(importerFile)) {
debugResolve('importer has unsupported extension. skipping...')
return noMatch
}

// Respect the include/exclude properties.
const relativeImporterFile = relative(configDir, importerFile)
if (!isIncludedRelative(relativeImporterFile)) {
debugResolve('importer is not included. skipping...')
return noMatch
}

Expand All @@ -328,21 +349,29 @@ export default (opts: PluginOptions = {}): Plugin => {
id = id.slice(0, -suffix.length)
}

let path = resolutionCache.get(id)
if (!path) {
path = await resolveId(viteResolve, id, importer)
if (!path) {
let resolvedId = resolutionCache.get(id)
if (!resolvedId) {
resolvedId = await resolveId(viteResolve, id, importer)
if (!resolvedId) {
return noMatch
}
resolutionCache.set(id, path)
debug(`resolved:`, {
id,
importer,
resolvedId: path,
configPath,
})
resolutionCache.set(id, resolvedId)
if (debugResolve.enabled) {
debugResolve('resolved without error:', {
id,
importer,
resolvedId,
configPath,
})
}
}
return [path && suffix ? path + suffix : path, true]

// Restore the suffix if one was removed earlier.
if (suffix) {
resolvedId += suffix
}

return [resolvedId, true]
}
}
}
Expand Down

0 comments on commit 7160d6e

Please sign in to comment.