Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(resolve): remove deep import syntax handling #12381

Merged
merged 6 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions packages/vite/src/node/optimizer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getHash,
isOptimizable,
lookupFile,
nestedResolveFrom,
normalizeId,
normalizePath,
removeDir,
Expand Down Expand Up @@ -812,18 +813,13 @@ export async function addManuallyIncludedOptimizeDeps(
)
}
}
const resolve = config.createResolver({
asSrc: false,
scan: true,
ssrOptimizeCheck: ssr,
ssrConfig: config.ssr,
})
const resolve = createOptimizeDepsIncludeResolver(config, ssr)
for (const id of [...optimizeDepsInclude, ...extra]) {
// normalize 'foo >bar` as 'foo > bar' to prevent same id being added
// and for pretty printing
const normalizedId = normalizeId(id)
if (!deps[normalizedId] && filter?.(normalizedId) !== false) {
const entry = await resolve(id, undefined, undefined, ssr)
const entry = await resolve(id)
if (entry) {
if (isOptimizable(entry, optimizeDeps)) {
if (!entry.endsWith('?__vite_skip_optimization')) {
Expand All @@ -840,6 +836,30 @@ export async function addManuallyIncludedOptimizeDeps(
}
}

function createOptimizeDepsIncludeResolver(
config: ResolvedConfig,
ssr: boolean,
) {
const resolve = config.createResolver({
asSrc: false,
scan: true,
ssrOptimizeCheck: ssr,
ssrConfig: config.ssr,
})
return async (id: string) => {
const lastArrowIndex = id.lastIndexOf('>')
if (lastArrowIndex === -1) {
return await resolve(id, undefined, undefined, ssr)
}
// split nested selected id by last '>', for example:
// 'foo > bar > baz' => 'foo > bar' & 'baz'
const nestedRoot = id.substring(0, lastArrowIndex).trim()
const nestedPath = id.substring(lastArrowIndex + 1).trim()
const basedir = nestedResolveFrom(nestedRoot, config.root, false, ssr)
bluwy marked this conversation as resolved.
Show resolved Hide resolved
return await resolve(nestedPath, basedir, undefined, ssr)
}
}

export function newDepOptimizationProcessing(): DepOptimizationProcessing {
let resolve: () => void
const promise = new Promise((_resolve) => {
Expand Down
50 changes: 15 additions & 35 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
isTsRequest,
isWindows,
lookupFile,
nestedResolveFrom,
normalizePath,
resolveFrom,
slash,
Expand Down Expand Up @@ -645,32 +644,20 @@ export function tryNodeResolve(
options: InternalResolveOptionsWithOverrideConditions,
targetWeb: boolean,
depsOptimizer?: DepsOptimizer,
ssr?: boolean,
ssr: boolean = false,
externalize?: boolean,
allowLinkedExternal: boolean = true,
): PartialResolvedId | undefined {
const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options

ssr ??= false

// split id by last '>' for nested selected packages, for example:
// 'foo > bar > baz' => 'foo > bar' & 'baz'
// 'foo' => '' & 'foo'
const lastArrowIndex = id.lastIndexOf('>')
const nestedRoot = id.substring(0, lastArrowIndex).trim()
const nestedPath = id.substring(lastArrowIndex + 1).trim()

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

const part = nestedPath.slice(
prevSlashIndex + 1,
(prevSlashIndex = slashIndex),
)
const part = id.slice(prevSlashIndex + 1, (prevSlashIndex = slashIndex))
if (!part) {
break
}
Expand All @@ -683,7 +670,7 @@ export function tryNodeResolve(
continue
}

const possiblePkgId = nestedPath.slice(0, slashIndex)
const possiblePkgId = id.slice(0, slashIndex)
possiblePkgIds.push(possiblePkgId)
}

Expand All @@ -700,11 +687,6 @@ export function tryNodeResolve(
basedir = root
}

// nested node module, step-by-step resolve to the basedir of the nestedPath
if (nestedRoot) {
basedir = nestedResolveFrom(nestedRoot, basedir, preserveSymlinks)
}

let pkg: PackageData | undefined
let pkgId: string | undefined
// nearest package.json
Expand Down Expand Up @@ -742,9 +724,9 @@ export function tryNodeResolve(
// if so, we can resolve to a special id that errors only when imported.
if (
basedir !== root && // root has no peer dep
!isBuiltin(nestedPath) &&
!nestedPath.includes('\0') &&
bareImportRE.test(nestedPath)
!isBuiltin(id) &&
!id.includes('\0') &&
bareImportRE.test(id)
) {
// find package.json with `name` as main
const mainPackageJson = lookupFile(basedir, ['package.json'], {
Expand All @@ -753,11 +735,11 @@ export function tryNodeResolve(
if (mainPackageJson) {
const mainPkg = JSON.parse(mainPackageJson)
if (
mainPkg.peerDependencies?.[nestedPath] &&
mainPkg.peerDependenciesMeta?.[nestedPath]?.optional
mainPkg.peerDependencies?.[id] &&
mainPkg.peerDependenciesMeta?.[id]?.optional
) {
return {
id: `${optionalPeerDepId}:${nestedPath}:${mainPkg.name}`,
id: `${optionalPeerDepId}:${id}:${mainPkg.name}`,
}
}
}
Expand All @@ -767,10 +749,10 @@ export function tryNodeResolve(

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

let resolved: string | undefined
Expand Down Expand Up @@ -865,16 +847,14 @@ export function tryNodeResolve(
!isJsType ||
importer?.includes('node_modules') ||
exclude?.includes(pkgId) ||
exclude?.includes(nestedPath) ||
exclude?.includes(id) ||
SPECIAL_QUERY_RE.test(resolved) ||
// During dev SSR, we don't have a way to reload the module graph if
// a non-optimized dep is found. So we need to skip optimization here.
// 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(nestedPath)))
(ssr && !isCJS && !(include?.includes(pkgId) || include?.includes(id)))

if (options.ssrOptimizeCheck) {
return {
Expand Down
3 changes: 2 additions & 1 deletion packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ export function nestedResolveFrom(
id: string,
basedir: string,
preserveSymlinks = false,
ssr = false,
): string {
const pkgs = id.split('>').map((pkg) => pkg.trim())
try {
for (const pkg of pkgs) {
basedir = resolveFrom(pkg, basedir, preserveSymlinks)
basedir = resolveFrom(pkg, basedir, preserveSymlinks, ssr)
}
} catch {}
return basedir
Expand Down