@@ -15,6 +15,7 @@ const AliasPlugin = require("./AliasPlugin");
1515const AppendPlugin = require ( "./AppendPlugin" ) ;
1616const DescriptionFilePlugin = require ( "./DescriptionFilePlugin" ) ;
1717const DirectoryExistsPlugin = require ( "./DirectoryExistsPlugin" ) ;
18+ const ExportsFieldPlugin = require ( "./ExportsFieldPlugin" ) ;
1819const FileExistsPlugin = require ( "./FileExistsPlugin" ) ;
1920const FileKindPlugin = require ( "./FileKindPlugin" ) ;
2021const JoinRequestPartPlugin = require ( "./JoinRequestPartPlugin" ) ;
@@ -27,6 +28,7 @@ const NextPlugin = require("./NextPlugin");
2728const ParsePlugin = require ( "./ParsePlugin" ) ;
2829const PnpPlugin = require ( "./PnpPlugin" ) ;
2930const ResultPlugin = require ( "./ResultPlugin" ) ;
31+ const SelfReferencePlugin = require ( "./SelfReferencePlugin" ) ;
3032const SymlinkPlugin = require ( "./SymlinkPlugin" ) ;
3133const TryNextPlugin = require ( "./TryNextPlugin" ) ;
3234const UnsafeCachePlugin = require ( "./UnsafeCachePlugin" ) ;
@@ -48,7 +50,9 @@ const UseFilePlugin = require("./UseFilePlugin");
4850 * @property {(function(ResolveRequest): boolean)= } cachePredicate A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties.
4951 * @property {boolean= } cacheWithContext Whether or not the unsafeCache should include request context as part of the cache key.
5052 * @property {string[]= } descriptionFiles A list of description files to read from
53+ * @property {string[]= } conditionNames A list of exports field condition names.
5154 * @property {boolean= } enforceExtension Enforce that a extension from extensions must be used
55+ * @property {(string | string[])[]= } exportsFields A list of exports fields in description files
5256 * @property {string[]= } extensions A list of extensions which should be tried for files
5357 * @property {FileSystem } fileSystem The file system which should be used
5458 * @property {(Object | boolean)= } unsafeCache Use this cache object to unsafely cache the successful requests
@@ -69,8 +73,10 @@ const UseFilePlugin = require("./UseFilePlugin");
6973 * @property {Set<string | string[]> } aliasFields
7074 * @property {(function(ResolveRequest): boolean) } cachePredicate
7175 * @property {boolean } cacheWithContext
76+ * @property {Set<string> } conditionNames A list of exports field condition names.
7277 * @property {string[] } descriptionFiles
7378 * @property {boolean } enforceExtension
79+ * @property {Set<string | string[]> } exportsFields
7480 * @property {Set<string> } extensions
7581 * @property {FileSystem } fileSystem
7682 * @property {Object | false } unsafeCache
@@ -144,6 +150,8 @@ function createOptions(options) {
144150 typeof options . cacheWithContext !== "undefined"
145151 ? options . cacheWithContext
146152 : true ,
153+ exportsFields : new Set ( options . exportsFields || [ "exports" ] ) ,
154+ conditionNames : new Set ( options . conditionNames ) ,
147155 descriptionFiles : Array . from (
148156 new Set ( options . descriptionFiles || [ "package.json" ] )
149157 ) ,
@@ -189,8 +197,10 @@ exports.createResolver = function(options) {
189197 aliasFields,
190198 cachePredicate,
191199 cacheWithContext,
200+ conditionNames,
192201 descriptionFiles,
193202 enforceExtension,
203+ exportsFields,
194204 extensions,
195205 fileSystem,
196206 mainFields,
@@ -217,7 +227,9 @@ exports.createResolver = function(options) {
217227 resolver . ensureHook ( "describedResolve" ) ;
218228 resolver . ensureHook ( "rawModule" ) ;
219229 resolver . ensureHook ( "module" ) ;
220- resolver . ensureHook ( "resolveInDirectory" ) ;
230+ resolver . ensureHook ( "resolveAsModule" ) ;
231+ resolver . ensureHook ( "undescribedResolveInPackage" ) ;
232+ resolver . ensureHook ( "resolveInPackage" ) ;
221233 resolver . ensureHook ( "resolveInExistingDirectory" ) ;
222234 resolver . ensureHook ( "relative" ) ;
223235 resolver . ensureHook ( "describedRelative" ) ;
@@ -227,6 +239,7 @@ exports.createResolver = function(options) {
227239 resolver . ensureHook ( "undescribedRawFile" ) ;
228240 resolver . ensureHook ( "rawFile" ) ;
229241 resolver . ensureHook ( "file" ) ;
242+ resolver . ensureHook ( "finalFile" ) ;
230243 resolver . ensureHook ( "existingFile" ) ;
231244 resolver . ensureHook ( "resolved" ) ;
232245
@@ -266,7 +279,12 @@ exports.createResolver = function(options) {
266279 plugins . push ( new ModuleKindPlugin ( "after-described-resolve" , "raw-module" ) ) ;
267280 plugins . push ( new JoinRequestPlugin ( "after-described-resolve" , "relative" ) ) ;
268281
269- // module
282+ // raw-module
283+ exportsFields . forEach ( exportsField => {
284+ plugins . push (
285+ new SelfReferencePlugin ( "raw-module" , exportsField , "resolve-as-module" )
286+ ) ;
287+ } ) ;
270288 if ( pnpApi ) {
271289 plugins . push ( new PnpPlugin ( "raw-module" , pnpApi , "relative" ) ) ;
272290 }
@@ -279,25 +297,53 @@ exports.createResolver = function(options) {
279297 } ) ;
280298
281299 // module
282- plugins . push ( new JoinRequestPartPlugin ( "module" , "resolve-in-directory " ) ) ;
300+ plugins . push ( new JoinRequestPartPlugin ( "module" , "resolve-as-module " ) ) ;
283301
284- // resolve-in-directory
302+ // resolve-as-module
285303 if ( ! resolveToContext ) {
286304 plugins . push (
287305 new FileKindPlugin (
288- "resolve-in-directory " ,
306+ "resolve-as-module " ,
289307 "single file module" ,
290308 "undescribed-raw-file"
291309 )
292310 ) ;
293311 }
294312 plugins . push (
295313 new DirectoryExistsPlugin (
296- "resolve-in-directory " ,
297- "resolve-in-existing-directory "
314+ "resolve-as-module " ,
315+ "undescribed- resolve-in-package "
298316 )
299317 ) ;
300318
319+ // undescribed-resolve-in-package
320+ plugins . push (
321+ new DescriptionFilePlugin (
322+ "undescribed-resolve-in-package" ,
323+ descriptionFiles ,
324+ false ,
325+ "resolve-in-package"
326+ )
327+ ) ;
328+ plugins . push (
329+ new NextPlugin ( "after-undescribed-resolve-in-package" , "resolve-in-package" )
330+ ) ;
331+
332+ // resolve-in-package
333+ exportsFields . forEach ( exportsField => {
334+ plugins . push (
335+ new ExportsFieldPlugin (
336+ "resolve-in-package" ,
337+ conditionNames ,
338+ exportsField ,
339+ "final-file"
340+ )
341+ ) ;
342+ } ) ;
343+ plugins . push (
344+ new NextPlugin ( "resolve-in-package" , "resolve-in-existing-directory" )
345+ ) ;
346+
301347 // resolve-in-existing-directory
302348 plugins . push (
303349 new JoinRequestPlugin ( "resolve-in-existing-directory" , "relative" )
@@ -391,7 +437,10 @@ exports.createResolver = function(options) {
391437 aliasFields . forEach ( item => {
392438 plugins . push ( new AliasFieldPlugin ( "file" , item , "resolve" ) ) ;
393439 } ) ;
394- plugins . push ( new FileExistsPlugin ( "file" , "existing-file" ) ) ;
440+ plugins . push ( new NextPlugin ( "file" , "final-file" ) ) ;
441+
442+ // final-file
443+ plugins . push ( new FileExistsPlugin ( "final-file" , "existing-file" ) ) ;
395444
396445 // existing-file
397446 if ( symlinks )
0 commit comments