Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
Fix path fragment inputs
Browse files Browse the repository at this point in the history
When resolving an import name that doesn't look like a relative or
absolute path, first attempt to resolve the corresponding relative path
before resolving the original import name.
  • Loading branch information
bterlson committed Jun 24, 2019
1 parent cdb7448 commit a5ff1a9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 18 deletions.
69 changes: 51 additions & 18 deletions src/index.js
Expand Up @@ -77,6 +77,32 @@ const alwaysNull = () => null;

const resolveIdAsync = (file, opts) => new Promise((fulfil, reject) => resolveId(file, opts, (err, contents) => err ? reject(err) : fulfil(contents)));

// Resolve module specifiers in order. Promise resolves to the first
// module that resolves successfully, or the error that resulted from
// the last attempted module resolution.
function resolveImportSpecifiers (importSpecifierList, resolveOptions) {
let p = Promise.resolve();
for (let i = 0; i < importSpecifierList.length; i++) {
p = p.then(v => {
// if we've already resolved to something, just return it.
if (v) return v;

return resolveIdAsync(importSpecifierList[i], resolveOptions);
});

if (i < importSpecifierList.length - 1) {
// swallow MODULE_NOT_FOUND errors from all but the last resolution
p = p.catch(err => {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err;
}
});
}
}

return p;
}

export default function nodeResolve ( options = {} ) {
const mainFields = getMainFields(options);
const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
Expand Down Expand Up @@ -239,29 +265,36 @@ export default function nodeResolve ( options = {} ) {
resolveOptions.preserveSymlinks = preserveSymlinks;
}

const importSpecifierList = [];

if (importer === undefined && !importee[0].match(/^\.?\.?\//)) {
// For module graph roots (i.e. when importer is undefined), we
// need to handle 'path fragments` like `foo/bar` that are commonly
// found in rollup config files. If importee doesn't look like a
// relative or absolute path, we make it relative and attempt to
// resolve it. If we don't find anything, we try resolving it as we
// got it.
importSpecifierList.push('./' + importee);
}

const importeeIsBuiltin = builtins.has(importee);
const forceLocalLookup = importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet);
let importSpecifier = importee;

if (forceLocalLookup) {
// need to attempt to look up a local module
importSpecifier += '/';
if (importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet)) {
// The `resolve` library will not resolve packages with the same
// name as a node built-in module. If we're resolving something
// that's a builtin, and we don't prefer to find built-ins, we
// first try to look up a local module with that name. If we don't
// find anything, we resolve the builtin which just returns back
// the built-in's name.
importSpecifierList.push(importee + '/');
}

return resolveIdAsync(
importSpecifier,
Object.assign( resolveOptions, customResolveOptions )
)
.catch(err => {
if (forceLocalLookup && err.code === 'MODULE_NOT_FOUND') {
// didn't find a local module, so fall back to the importee
// (i.e. the builtin's name)
return importee;
}
importSpecifierList.push(importee);

// some other error, just forward it
throw err;
})
return resolveImportSpecifiers(
importSpecifierList,
Object.assign(resolveOptions, customResolveOptions)
)
.then(resolved => {
if ( resolved && packageBrowserField ) {
if ( packageBrowserField.hasOwnProperty(resolved) ) {
Expand Down
15 changes: 15 additions & 0 deletions test/package.json
@@ -0,0 +1,15 @@
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "test.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"browser": {
"dummy-module": "component-type"
}
}
4 changes: 4 additions & 0 deletions test/samples/browser-local/main.js
@@ -0,0 +1,4 @@
// test browser mapped imports from the main entrypoint
import s from 'dummy-module';

export default s;
14 changes: 14 additions & 0 deletions test/test.js
Expand Up @@ -337,6 +337,20 @@ describe( 'rollup-plugin-node-resolve', function () {
});
});

it('respects local browser field', function () {
return rollup.rollup({
input: 'samples/browser-local/main.js',
onwarn: expectNoWarnings,
plugins: [
nodeResolve({
mainFields: ['browser', 'main']
})
]
}).then(executeBundle).then(module => {
assert.equal(module.exports, 'component-type');
});
});

it( 'warns when importing builtins', function () {
return rollup.rollup({
input: 'samples/builtins/main.js',
Expand Down

0 comments on commit a5ff1a9

Please sign in to comment.