2
2
3
3
const getEsmExports = require ( './get-esm-exports.js' )
4
4
const { parse : parseCjs } = require ( 'cjs-module-lexer' )
5
- const { readFileSync } = require ( 'fs' )
5
+ const { readFileSync, existsSync } = require ( 'fs' )
6
6
const { builtinModules } = require ( 'module' )
7
7
const { fileURLToPath, pathToFileURL } = require ( 'url' )
8
8
const { dirname, join } = require ( 'path' )
@@ -32,13 +32,9 @@ const urlsBeingProcessed = new Set() // Guard against circular imports.
32
32
* Once the package.json file has been found, we extract the file path from the specifier
33
33
* @param {string } specifier The specifier that is being search for inside the imports object
34
34
* @param {URL|string } fromUrl The url from which the search starts from
35
- * @returns file to url to file export
35
+ * @returns object with url and resolvedExport
36
36
*/
37
37
function resolvePackageImports ( specifier , fromUrl ) {
38
- if ( ! specifier . startsWith ( '#' ) ) {
39
- return null
40
- }
41
-
42
38
try {
43
39
const fromPath = fileURLToPath ( fromUrl )
44
40
let currentDir = dirname ( fromPath )
@@ -47,44 +43,39 @@ function resolvePackageImports (specifier, fromUrl) {
47
43
while ( currentDir !== dirname ( currentDir ) ) {
48
44
const packageJsonPath = join ( currentDir , 'package.json' )
49
45
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' ) )
62
48
if ( packageJson . imports && packageJson . imports [ specifier ] ) {
63
49
const imports = packageJson . imports [ specifier ]
64
50
65
51
// Look for path inside packageJson
66
- let resolvedPath
52
+ let resolvedExport
67
53
if ( Object . prototype . toString . call ( imports ) === '[object Object]' ) {
68
- const requireSpecifier = imports . require
69
- const importSpecifier = imports . import
54
+ const requireExport = imports . require
55
+ const importExport = imports . import
70
56
// look for the possibility of require and import which is standard for CJS/ESM
71
- if ( requireSpecifier || importSpecifier ) {
57
+ if ( requireExport || importExport ) {
72
58
// 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
74
60
} else if ( imports . node || imports . default ) {
75
- resolvedPath = imports . node || imports . default
61
+ resolvedExport = imports . node || imports . default
76
62
}
77
63
} else if ( typeof imports === 'string' ) {
78
- resolvedPath = imports
64
+ resolvedExport = imports
79
65
}
80
66
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, export : resolvedExport }
83
72
}
84
73
}
85
74
// return if we find a package.json but did not find an import
86
75
return null
87
76
}
77
+
78
+ currentDir = dirname ( currentDir )
88
79
}
89
80
} catch ( error ) {
90
81
throw new Error ( `Failed to find sub path export: ${ specifier } ` )
@@ -113,18 +104,19 @@ async function getCjsExports (url, context, parentLoad, source) {
113
104
re = './'
114
105
}
115
106
116
- let newUrl
117
107
// Entries in the import field should always start with #
118
108
if ( re . startsWith ( '#' ) ) {
119
- newUrl = resolvePackageImports ( re , url )
120
- if ( ! newUrl ) {
109
+ const resolvedSpecifier = resolvePackageImports ( re , url )
110
+ if ( ! resolvedSpecifier ) {
121
111
// Unable to resolve specifier import
122
112
return
123
113
}
124
- } else {
125
- newUrl = pathToFileURL ( require . resolve ( re , { paths : [ dirname ( fileURLToPath ( url ) ) ] } ) ) . href
114
+ re = resolvedSpecifier . export
115
+ url = resolvedSpecifier . url
126
116
}
127
117
118
+ const newUrl = pathToFileURL ( require . resolve ( re , { paths : [ dirname ( fileURLToPath ( url ) ) ] } ) ) . href
119
+
128
120
if ( newUrl . endsWith ( '.node' ) || newUrl . endsWith ( '.json' ) ) {
129
121
return
130
122
}
0 commit comments