Skip to content

Commit

Permalink
perf(resolve): refactor package.json handling for deep imports (#12461)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Mar 21, 2023
1 parent 58e99b6 commit 596b661
Showing 1 changed file with 19 additions and 75 deletions.
94 changes: 19 additions & 75 deletions packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -19,6 +19,7 @@ import {
bareImportRE,
cleanUrl,
createDebugger,
deepImportRE,
ensureVolumeInPath,
fsPathFromId,
getPotentialTsSrcPaths,
Expand Down Expand Up @@ -663,32 +664,12 @@ export function tryNodeResolve(
): PartialResolvedId | undefined {
const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options

const possiblePkgIds: string[] = []
for (let prevSlashIndex = -1; ; ) {
let slashIndex = id.indexOf('/', prevSlashIndex + 1)
if (slashIndex < 0) {
slashIndex = id.length
}

const part = id.slice(prevSlashIndex + 1, (prevSlashIndex = slashIndex))
if (!part) {
break
}

// Assume path parts with an extension are not package roots, except for the
// first path part (since periods are sadly allowed in package names).
// At the same time, skip the first path part if it begins with "@"
// (since "@foo/bar" should be treated as the top-level path).
if (possiblePkgIds.length ? path.extname(part) : part[0] === '@') {
continue
}

const possiblePkgId = id.slice(0, slashIndex)
possiblePkgIds.push(possiblePkgId)
}
// check for deep import, e.g. "my-lib/foo"
const deepMatch = id.match(deepImportRE)
const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : id

let basedir: string
if (dedupe?.some((id) => possiblePkgIds.includes(id))) {
if (dedupe?.includes(pkgId)) {
basedir = root
} else if (
importer &&
Expand All @@ -700,39 +681,8 @@ export function tryNodeResolve(
basedir = root
}

let pkg: PackageData | undefined
let pkgId: string | undefined
// nearest package.json
let nearestPkg: PackageData | undefined

const rootPkgId = possiblePkgIds[0]

const rootPkg = resolvePackageData(
rootPkgId,
basedir,
preserveSymlinks,
packageCache,
)!

const nearestPkgId = [...possiblePkgIds].reverse().find((pkgId) => {
nearestPkg = resolvePackageData(
pkgId,
basedir,
preserveSymlinks,
packageCache,
)!
return nearestPkg
})!

if (rootPkg?.data?.exports) {
pkgId = rootPkgId
pkg = rootPkg
} else {
pkgId = nearestPkgId
pkg = nearestPkg
}

if (!pkg || !nearestPkg) {
const pkg = resolvePackageData(pkgId, basedir, preserveSymlinks, packageCache)
if (!pkg) {
// if import can't be found, check if it's an optional peer dep.
// if so, we can resolve to a special id that errors only when imported.
if (
Expand Down Expand Up @@ -760,13 +710,8 @@ export function tryNodeResolve(
return
}

let resolveId = resolvePackageEntry
let unresolvedId = pkgId
const isDeepImport = unresolvedId !== id
if (isDeepImport) {
resolveId = resolveDeepImport
unresolvedId = '.' + id.slice(pkgId.length)
}
const resolveId = deepMatch ? resolveDeepImport : resolvePackageEntry
const unresolvedId = deepMatch ? '.' + id.slice(pkgId.length) : pkgId

let resolved: string | undefined
try {
Expand Down Expand Up @@ -807,14 +752,10 @@ export function tryNodeResolve(
return resolved
}
let resolvedId = id
if (isDeepImport) {
if (!pkg?.data.exports && path.extname(id) !== resolvedExt) {
resolvedId = resolved.id.slice(resolved.id.indexOf(id))
isDebug &&
debug(
`[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`,
)
}
if (deepMatch && !pkg?.data.exports && path.extname(id) !== resolvedExt) {
resolvedId = resolved.id.slice(resolved.id.indexOf(id))
isDebug &&
debug(`[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`)
}
return { ...resolved, id: resolvedId, external: true }
}
Expand All @@ -831,8 +772,6 @@ export function tryNodeResolve(
}

const ext = path.extname(resolved)
const isCJS =
ext === '.cjs' || (ext === '.js' && nearestPkg.data.type !== 'module')

if (
!options.ssrOptimizeCheck &&
Expand Down Expand Up @@ -867,7 +806,12 @@ export function tryNodeResolve(
// The only optimized deps are the ones explicitly listed in the config.
(!options.ssrOptimizeCheck && !isBuild && ssr) ||
// Only optimize non-external CJS deps during SSR by default
(ssr && !isCJS && !(include?.includes(pkgId) || include?.includes(id)))
(ssr &&
!(
ext === '.cjs' ||
(ext === '.js' && resolvePkg(resolved, options)?.data.type !== 'module')
) &&
!(include?.includes(pkgId) || include?.includes(id)))

if (options.ssrOptimizeCheck) {
return {
Expand Down

0 comments on commit 596b661

Please sign in to comment.