@@ -77,6 +77,32 @@ const alwaysNull = () => null;
77
77
78
78
const resolveIdAsync = ( file , opts ) => new Promise ( ( fulfil , reject ) => resolveId ( file , opts , ( err , contents ) => err ? reject ( err ) : fulfil ( contents ) ) ) ;
79
79
80
+ // Resolve module specifiers in order. Promise resolves to the first
81
+ // module that resolves successfully, or the error that resulted from
82
+ // the last attempted module resolution.
83
+ function resolveImportSpecifiers ( importSpecifierList , resolveOptions ) {
84
+ let p = Promise . resolve ( ) ;
85
+ for ( let i = 0 ; i < importSpecifierList . length ; i ++ ) {
86
+ p = p . then ( v => {
87
+ // if we've already resolved to something, just return it.
88
+ if ( v ) return v ;
89
+
90
+ return resolveIdAsync ( importSpecifierList [ i ] , resolveOptions ) ;
91
+ } ) ;
92
+
93
+ if ( i < importSpecifierList . length - 1 ) {
94
+ // swallow MODULE_NOT_FOUND errors from all but the last resolution
95
+ p = p . catch ( err => {
96
+ if ( err . code !== 'MODULE_NOT_FOUND' ) {
97
+ throw err ;
98
+ }
99
+ } ) ;
100
+ }
101
+ }
102
+
103
+ return p ;
104
+ }
105
+
80
106
export default function nodeResolve ( options = { } ) {
81
107
const mainFields = getMainFields ( options ) ;
82
108
const useBrowserOverrides = mainFields . indexOf ( 'browser' ) !== - 1 ;
@@ -238,29 +264,36 @@ export default function nodeResolve ( options = {} ) {
238
264
resolveOptions . preserveSymlinks = preserveSymlinks ;
239
265
}
240
266
267
+ const importSpecifierList = [ ] ;
268
+
269
+ if ( importer === undefined && ! importee [ 0 ] . match ( / ^ \. ? \. ? \/ / ) ) {
270
+ // For module graph roots (i.e. when importer is undefined), we
271
+ // need to handle 'path fragments` like `foo/bar` that are commonly
272
+ // found in rollup config files. If importee doesn't look like a
273
+ // relative or absolute path, we make it relative and attempt to
274
+ // resolve it. If we don't find anything, we try resolving it as we
275
+ // got it.
276
+ importSpecifierList . push ( './' + importee ) ;
277
+ }
278
+
241
279
const importeeIsBuiltin = builtins . has ( importee ) ;
242
- const forceLocalLookup = importeeIsBuiltin && ( ! preferBuiltins || ! isPreferBuiltinsSet ) ;
243
- let importSpecifier = importee ;
244
280
245
- if ( forceLocalLookup ) {
246
- // need to attempt to look up a local module
247
- importSpecifier += '/' ;
281
+ if ( importeeIsBuiltin && ( ! preferBuiltins || ! isPreferBuiltinsSet ) ) {
282
+ // The `resolve` library will not resolve packages with the same
283
+ // name as a node built-in module. If we're resolving something
284
+ // that's a builtin, and we don't prefer to find built-ins, we
285
+ // first try to look up a local module with that name. If we don't
286
+ // find anything, we resolve the builtin which just returns back
287
+ // the built-in's name.
288
+ importSpecifierList . push ( importee + '/' ) ;
248
289
}
249
290
250
- return resolveIdAsync (
251
- importSpecifier ,
252
- Object . assign ( resolveOptions , customResolveOptions )
253
- )
254
- . catch ( err => {
255
- if ( forceLocalLookup && err . code === 'MODULE_NOT_FOUND' ) {
256
- // didn't find a local module, so fall back to the importee
257
- // (i.e. the builtin's name)
258
- return importee ;
259
- }
291
+ importSpecifierList . push ( importee ) ;
260
292
261
- // some other error, just forward it
262
- throw err ;
263
- } )
293
+ return resolveImportSpecifiers (
294
+ importSpecifierList ,
295
+ Object . assign ( resolveOptions , customResolveOptions )
296
+ )
264
297
. then ( resolved => {
265
298
if ( resolved && packageBrowserField ) {
266
299
if ( Object . prototype . hasOwnProperty . call ( packageBrowserField , resolved ) ) {
0 commit comments