@@ -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- ( / t y p e o f e x p o r t s \s * = = / . test ( content ) &&
584- / t y p e o f m o d u l e \s * = = / . test ( content ) ) ||
585- / m o d u l e \. e x p o r t s \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+ ( / t y p e o f e x p o r t s \s * = = / . test ( content ) &&
585+ / t y p e o f m o d u l e \s * = = / . test ( content ) ) ||
586+ / m o d u l e \. e x p o r t s \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+
632643function resolveExports (
633644 pkg : PackageData [ 'data' ] ,
634645 key : string ,
0 commit comments