@@ -77,6 +77,32 @@ const alwaysNull = () => null;
7777
7878const resolveIdAsync = ( file , opts ) => new Promise ( ( fulfil , reject ) => resolveId ( file , opts , ( err , contents ) => err ? reject ( err ) : fulfil ( contents ) ) ) ;
7979
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+
80106export default function nodeResolve ( options = { } ) {
81107const mainFields = getMainFields ( options ) ;
82108const useBrowserOverrides = mainFields . indexOf ( 'browser' ) !== - 1 ;
@@ -238,29 +264,36 @@ export default function nodeResolve ( options = {} ) {
238264resolveOptions . preserveSymlinks = preserveSymlinks ;
239265}
240266
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+
241279const importeeIsBuiltin = builtins . has ( importee ) ;
242- const forceLocalLookup = importeeIsBuiltin && ( ! preferBuiltins || ! isPreferBuiltinsSet ) ;
243- let importSpecifier = importee ;
244280
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 + '/' ) ;
248289}
249290
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 ) ;
260292
261- // some other error, just forward it
262- throw err ;
263- } )
293+ return resolveImportSpecifiers (
294+ importSpecifierList ,
295+ Object . assign ( resolveOptions , customResolveOptions )
296+ )
264297. then ( resolved => {
265298if ( resolved && packageBrowserField ) {
266299if ( Object . prototype . hasOwnProperty . call ( packageBrowserField , resolved ) ) {
0 commit comments