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

Fix path fragment inputs #229

Merged
merged 1 commit into from Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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