9
9
* @oncall react_native
10
10
*/
11
11
12
- import type { ExportMap , PackageInfo , ResolutionContext } from './types' ;
12
+ import type { ExportMap , ResolutionContext , SourceFileResolution } from './types' ;
13
13
14
+ import path from 'path' ;
14
15
import invariant from 'invariant' ;
16
+ import toPosixPath from './utils/toPosixPath' ;
15
17
16
18
/**
17
- * Resolve the main entry point subpath for a package.
19
+ * Resolve a package subpath based on the entry points defined in the package's
20
+ * "exports" field. If there is no match for the given subpath (which may be
21
+ * augmented by resolution of conditional exports for the passed `context`),
22
+ * returns `null`.
18
23
*
19
24
* Implements modern package resolution behaviour based on the [Package Entry
20
25
* Points spec](https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points).
21
26
*/
22
- export function getPackageEntryPointFromExports (
27
+ export function resolvePackageTargetFromExports (
23
28
context : ResolutionContext ,
24
- packageInfo : PackageInfo ,
29
+ /**
30
+ * The path to the containing npm package directory.
31
+ */
32
+ packageRoot : string ,
33
+ /**
34
+ * The unresolved absolute path to the target module. This will be converted
35
+ * to a package-relative subpath for comparison.
36
+ */
37
+ modulePath : string ,
38
+ exportsField : ExportMap | string ,
25
39
platform : string | null ,
26
- ) : ?string {
27
- return matchSubpathFromExports ( '.' , context , packageInfo , platform ) ;
40
+ ) : SourceFileResolution | null {
41
+ const packageSubpath = path . relative ( packageRoot , modulePath ) ;
42
+ const subpath =
43
+ // Convert to prefixed POSIX path for "exports" lookup
44
+ packageSubpath === '' ? '.' : './' + toPosixPath ( packageSubpath ) ;
45
+ const match = matchSubpathFromExports (
46
+ context ,
47
+ subpath ,
48
+ exportsField ,
49
+ platform ,
50
+ ) ;
51
+
52
+ if ( match != null ) {
53
+ const filePath = path . join ( packageRoot , match ) ;
54
+
55
+ if ( context . doesFileExist ( filePath ) ) {
56
+ return { type : 'sourceFile' , filePath} ;
57
+ }
58
+ // TODO(T143882479): Throw InvalidPackageConfigurationError (entry point
59
+ // missing) and log as warning in calling context.
60
+ }
61
+
62
+ return null ;
28
63
}
29
64
30
65
/**
@@ -33,22 +68,16 @@ export function getPackageEntryPointFromExports(
33
68
* Implements modern package resolution behaviour based on the [Package Entry
34
69
* Points spec](https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points).
35
70
*/
36
- export function matchSubpathFromExports (
71
+ function matchSubpathFromExports (
72
+ context : ResolutionContext ,
37
73
/**
38
74
* The package-relative subpath (beginning with '.') to match against either
39
75
* an exact subpath key or subpath pattern key in "exports".
40
76
*/
41
77
subpath : string ,
42
- context : ResolutionContext ,
43
- { packageJson} : PackageInfo ,
78
+ exportsField : ExportMap | string ,
44
79
platform : string | null ,
45
80
) : ?string {
46
- const { exports : exportsField } = packageJson ;
47
-
48
- if ( exportsField == null ) {
49
- return null ;
50
- }
51
-
52
81
const conditionNames = new Set ( [
53
82
'default' ,
54
83
...context . unstable_conditionNames ,
@@ -57,15 +86,7 @@ export function matchSubpathFromExports(
57
86
: [ ] ) ,
58
87
] ) ;
59
88
60
- let exportMap : FlattenedExportMap ;
61
-
62
- try {
63
- exportMap = reduceExportsField ( exportsField , conditionNames ) ;
64
- } catch ( e ) {
65
- // TODO(T143882479): Log a warning if the "exports" field cannot be parsed
66
- // NOTE: Under strict mode, this should throw an InvalidPackageConfigurationError
67
- return null ;
68
- }
89
+ const exportMap = reduceExportsField ( exportsField , conditionNames ) ;
69
90
70
91
return exportMap [ subpath ] ;
71
92
}
@@ -93,6 +114,8 @@ function reduceExportsField(
93
114
subpathOrCondition . startsWith ( '.' ) ,
94
115
) ;
95
116
117
+ // TODO(T143882479): Throw InvalidPackageConfigurationError and log as
118
+ // warning in calling context.
96
119
invariant (
97
120
subpathKeys . length === 0 || subpathKeys . length === firstLevelKeys . length ,
98
121
'"exports" object cannot have keys mapping both subpaths and conditions ' +
@@ -125,6 +148,8 @@ function reduceExportsField(
125
148
value => value != null && ! value . startsWith ( './' ) ,
126
149
) ;
127
150
151
+ // TODO(T143882479): Throw InvalidPackageConfigurationError and log as
152
+ // warning in calling context.
128
153
invariant (
129
154
invalidValues . length === 0 ,
130
155
'One or more mappings for subpaths in "exports" is invalid. All values ' +
0 commit comments