22
33const getEsmExports = require ( './get-esm-exports.js' )
44const { parse : parseCjs } = require ( 'cjs-module-lexer' )
5- const { readFileSync } = require ( 'fs' )
5+ const { readFileSync, existsSync } = require ( 'fs' )
66const { builtinModules } = require ( 'module' )
77const { fileURLToPath, pathToFileURL } = require ( 'url' )
88const { dirname, join } = require ( 'path' )
@@ -32,13 +32,9 @@ const urlsBeingProcessed = new Set() // Guard against circular imports.
3232 * Once the package.json file has been found, we extract the file path from the specifier
3333 * @param {string } specifier The specifier that is being search for inside the imports object
3434 * @param {URL|string } fromUrl The url from which the search starts from
35- * @returns file to url to file export
35+ * @returns array with url and resolvedExport
3636 */
3737function resolvePackageImports ( specifier , fromUrl ) {
38- if ( ! specifier . startsWith ( '#' ) ) {
39- return null
40- }
41-
4238 try {
4339 const fromPath = fileURLToPath ( fromUrl )
4440 let currentDir = dirname ( fromPath )
@@ -47,47 +43,42 @@ function resolvePackageImports (specifier, fromUrl) {
4743 while ( currentDir !== dirname ( currentDir ) ) {
4844 const packageJsonPath = join ( currentDir , 'package.json' )
4945
50- let packageJson
51- try {
52- packageJson = JSON . parse ( readFileSync ( packageJsonPath , 'utf8' ) )
53- } catch ( error ) {
54- if ( error . code === 'ENOENT' ) {
55- currentDir = dirname ( currentDir )
56- continue
57- }
58- throw error
59- }
60-
61- if ( packageJson ) {
46+ if ( existsSync ( packageJsonPath ) ) {
47+ const packageJson = JSON . parse ( readFileSync ( packageJsonPath , 'utf8' ) )
6248 if ( packageJson . imports && packageJson . imports [ specifier ] ) {
6349 const imports = packageJson . imports [ specifier ]
6450
6551 // Look for path inside packageJson
66- let resolvedPath
67- if ( Object . prototype . toString . call ( imports ) === '[ object Object] ' ) {
68- const requireSpecifier = imports . require
69- const importSpecifier = imports . import
52+ let resolvedExport
53+ if ( typeof imports === 'object' ) {
54+ const requireExport = imports . require
55+ const importExport = imports . import
7056 // look for the possibility of require and import which is standard for CJS/ESM
71- if ( requireSpecifier || importSpecifier ) {
57+ if ( requireExport || importExport ) {
7258 // trying to resolve based on order of importance
73- resolvedPath = requireSpecifier . node || requireSpecifier . default || importSpecifier . node || importSpecifier . default
59+ resolvedExport = requireExport . node || requireExport . default || importExport . node || importExport . default
7460 } else if ( imports . node || imports . default ) {
75- resolvedPath = imports . node || imports . default
61+ resolvedExport = imports . node || imports . default
7662 }
7763 } else if ( typeof imports === 'string' ) {
78- resolvedPath = imports
64+ resolvedExport = imports
7965 }
8066
81- if ( resolvedPath ) {
82- return pathToFileURL ( require . resolve ( resolvedPath , { paths : [ currentDir ] } ) ) . href
67+ if ( resolvedExport ) {
68+ const url = resolvedExport . startsWith ( '.' )
69+ ? pathToFileURL ( join ( currentDir , resolvedExport ) )
70+ : fromUrl
71+ return [ url , resolvedExport ]
8372 }
8473 }
8574 // return if we find a package.json but did not find an import
8675 return null
8776 }
77+
78+ currentDir = dirname ( currentDir )
8879 }
8980 } catch ( error ) {
90- throw new Error ( `Failed to find sub path export: ${ specifier } ` )
81+ throw new Error ( `Failed to find export: ${ specifier } ` )
9182 }
9283
9384 return null
@@ -113,18 +104,15 @@ async function getCjsExports (url, context, parentLoad, source) {
113104 re = './'
114105 }
115106
116- let newUrl
117107 // Entries in the import field should always start with #
118108 if ( re . startsWith ( '#' ) ) {
119- newUrl = resolvePackageImports ( re , url )
120- if ( ! newUrl ) {
121- // Unable to resolve specifier import
122- return
123- }
124- } else {
125- newUrl = pathToFileURL ( require . resolve ( re , { paths : [ dirname ( fileURLToPath ( url ) ) ] } ) ) . href
109+ const resolved = resolvePackageImports ( re , url )
110+ if ( ! resolved ) return
111+ [ url , re ] = resolved
126112 }
127113
114+ const newUrl = pathToFileURL ( require . resolve ( re , { paths : [ dirname ( fileURLToPath ( url ) ) ] } ) ) . href
115+
128116 if ( newUrl . endsWith ( '.node' ) || newUrl . endsWith ( '.json' ) ) {
129117 return
130118 }
0 commit comments