Skip to content

Commit cc2f616

Browse files
committed
fix: surface exception when failing to resolve package entry
1 parent 31444ec commit cc2f616

1 file changed

Lines changed: 79 additions & 68 deletions

File tree

packages/vite/src/node/plugins/resolve.ts

Lines changed: 79 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -545,90 +545,101 @@ export function resolvePackageEntry(
545545
if (cached) {
546546
return cached
547547
}
548-
let entryPoint: string | undefined | void
548+
try {
549+
let entryPoint: string | undefined | void
549550

550-
// resolve exports field with highest priority
551-
// using https://github.com/lukeed/resolve.exports
552-
if (data.exports) {
553-
entryPoint = resolveExports(data, '.', options, targetWeb)
554-
}
551+
// resolve exports field with highest priority
552+
// using https://github.com/lukeed/resolve.exports
553+
if (data.exports) {
554+
entryPoint = resolveExports(data, '.', options, targetWeb)
555+
}
555556

556-
// if exports resolved to .mjs, still resolve other fields.
557-
// This is because .mjs files can technically import .cjs files which would
558-
// make them invalid for pure ESM environments - so if other module/browser
559-
// fields are present, prioritize those instead.
560-
if (targetWeb && (!entryPoint || entryPoint.endsWith('.mjs'))) {
561-
// check browser field
562-
// https://github.com/defunctzombie/package-browser-field-spec
563-
const browserEntry =
564-
typeof data.browser === 'string'
565-
? data.browser
566-
: isObject(data.browser) && data.browser['.']
567-
if (browserEntry) {
568-
// check if the package also has a "module" field.
569-
if (typeof data.module === 'string' && data.module !== browserEntry) {
570-
// if both are present, we may have a problem: some package points both
571-
// to ESM, with "module" targeting Node.js, while some packages points
572-
// "module" to browser ESM and "browser" to UMD.
573-
// the heuristics here is to actually read the browser entry when
574-
// possible and check for hints of UMD. If it is UMD, prefer "module"
575-
// instead; Otherwise, assume it's ESM and use it.
576-
const resolvedBrowserEntry = tryFsResolve(
577-
path.join(dir, browserEntry),
578-
options
579-
)
580-
if (resolvedBrowserEntry) {
581-
const content = fs.readFileSync(resolvedBrowserEntry, 'utf-8')
582-
if (
583-
(/typeof exports\s*==/.test(content) &&
584-
/typeof module\s*==/.test(content)) ||
585-
/module\.exports\s*=/.test(content)
586-
) {
587-
// likely UMD or CJS(!!! e.g. firebase 7.x), prefer module
588-
entryPoint = data.module
557+
// if exports resolved to .mjs, still resolve other fields.
558+
// This is because .mjs files can technically import .cjs files which would
559+
// make them invalid for pure ESM environments - so if other module/browser
560+
// fields are present, prioritize those instead.
561+
if (targetWeb && (!entryPoint || entryPoint.endsWith('.mjs'))) {
562+
// check browser field
563+
// https://github.com/defunctzombie/package-browser-field-spec
564+
const browserEntry =
565+
typeof data.browser === 'string'
566+
? data.browser
567+
: isObject(data.browser) && data.browser['.']
568+
if (browserEntry) {
569+
// check if the package also has a "module" field.
570+
if (typeof data.module === 'string' && data.module !== browserEntry) {
571+
// if both are present, we may have a problem: some package points both
572+
// to ESM, with "module" targeting Node.js, while some packages points
573+
// "module" to browser ESM and "browser" to UMD.
574+
// the heuristics here is to actually read the browser entry when
575+
// possible and check for hints of UMD. If it is UMD, prefer "module"
576+
// instead; Otherwise, assume it's ESM and use it.
577+
const resolvedBrowserEntry = tryFsResolve(
578+
path.join(dir, browserEntry),
579+
options
580+
)
581+
if (resolvedBrowserEntry) {
582+
const content = fs.readFileSync(resolvedBrowserEntry, 'utf-8')
583+
if (
584+
(/typeof exports\s*==/.test(content) &&
585+
/typeof module\s*==/.test(content)) ||
586+
/module\.exports\s*=/.test(content)
587+
) {
588+
// likely UMD or CJS(!!! e.g. firebase 7.x), prefer module
589+
entryPoint = data.module
590+
}
589591
}
592+
} else {
593+
entryPoint = browserEntry
590594
}
591-
} else {
592-
entryPoint = browserEntry
593595
}
594596
}
595-
}
596597

597-
if (!entryPoint || entryPoint.endsWith('.mjs')) {
598-
for (const field of options.mainFields || DEFAULT_MAIN_FIELDS) {
599-
if (typeof data[field] === 'string') {
600-
entryPoint = data[field]
601-
break
598+
if (!entryPoint || entryPoint.endsWith('.mjs')) {
599+
for (const field of options.mainFields || DEFAULT_MAIN_FIELDS) {
600+
if (typeof data[field] === 'string') {
601+
entryPoint = data[field]
602+
break
603+
}
602604
}
603605
}
604-
}
605606

606-
entryPoint = entryPoint || data.main || 'index.js'
607+
entryPoint = entryPoint || data.main || 'index.js'
607608

608-
// resolve object browser field in package.json
609-
const { browser: browserField } = data
610-
if (targetWeb && isObject(browserField)) {
611-
entryPoint = mapWithBrowserField(entryPoint, browserField) || entryPoint
612-
}
609+
// resolve object browser field in package.json
610+
const { browser: browserField } = data
611+
if (targetWeb && isObject(browserField)) {
612+
entryPoint = mapWithBrowserField(entryPoint, browserField) || entryPoint
613+
}
613614

614-
entryPoint = path.join(dir, entryPoint)
615-
const resolvedEntryPoint = tryFsResolve(entryPoint, options)
615+
entryPoint = path.join(dir, entryPoint)
616+
const resolvedEntryPoint = tryFsResolve(entryPoint, options)
616617

617-
if (resolvedEntryPoint) {
618-
isDebug &&
619-
debug(
620-
`[package entry] ${chalk.cyan(id)} -> ${chalk.dim(resolvedEntryPoint)}`
621-
)
622-
setResolvedCache('.', resolvedEntryPoint, targetWeb)
623-
return resolvedEntryPoint
624-
} else {
625-
throw new Error(
626-
`Failed to resolve entry for package "${id}". ` +
627-
`The package may have incorrect main/module/exports specified in its package.json.`
628-
)
618+
if (resolvedEntryPoint) {
619+
isDebug &&
620+
debug(
621+
`[package entry] ${chalk.cyan(id)} -> ${chalk.dim(
622+
resolvedEntryPoint
623+
)}`
624+
)
625+
setResolvedCache('.', resolvedEntryPoint, targetWeb)
626+
return resolvedEntryPoint
627+
} else {
628+
packageEntryFailure(id)
629+
}
630+
} catch (e) {
631+
packageEntryFailure(id, e.message)
629632
}
630633
}
631634

635+
function packageEntryFailure(id: string, details?: string) {
636+
throw new Error(
637+
`Failed to resolve entry for package "${id}". ` +
638+
`The package may have incorrect main/module/exports specified in its package.json` +
639+
(details ? ': ' + details : '.')
640+
)
641+
}
642+
632643
function resolveExports(
633644
pkg: PackageData['data'],
634645
key: string,

0 commit comments

Comments
 (0)