Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node-resolve): preserve search params and hashes #487

Merged
merged 1 commit into from Jul 12, 2020
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
16 changes: 14 additions & 2 deletions packages/node-resolve/src/index.js
Expand Up @@ -90,6 +90,12 @@ export function nodeResolve(opts = {}) {
// ignore IDs with null character, these belong to other plugins
if (/\0/.test(importee)) return null;

// strip hash and query params from import
const [withoutHash, hash] = importee.split('#');
const [importPath, params] = withoutHash.split('?');
const importSuffix = `${params ? `?${params}` : ''}${hash ? `#${hash}` : ''}`;
importee = importPath;

const basedir = !importer || dedupe(importee) ? rootDir : dirname(importer);

// https://github.com/defunctzombie/package-browser-field-spec
Expand Down Expand Up @@ -235,11 +241,17 @@ export function nodeResolve(opts = {}) {
if (resolved && options.modulesOnly) {
const code = await readFile(resolved, 'utf-8');
if (isModule(code)) {
return { id: resolved, moduleSideEffects: hasModuleSideEffects(resolved) };
return {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
};
}
return null;
}
const result = { id: resolved, moduleSideEffects: hasModuleSideEffects(resolved) };
const result = {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
};
return result;
} catch (error) {
return null;
Expand Down
3 changes: 3 additions & 0 deletions packages/node-resolve/test/fixtures/hash.js
@@ -0,0 +1,3 @@
import test from 'test#foo';

export default test;
@@ -0,0 +1,3 @@
import test from 'test?foo=bar&lorem=ipsum#foo';

export default test;
3 changes: 3 additions & 0 deletions packages/node-resolve/test/fixtures/search-params.js
@@ -0,0 +1,3 @@
import test from 'test?foo=bar&lorem=ipsum';

export default test;
75 changes: 75 additions & 0 deletions packages/node-resolve/test/test.js
Expand Up @@ -219,3 +219,78 @@ test('handles package side-effects', async (t) => {

delete global.sideEffects;
});

test('can resolve imports with hashes', async (t) => {
const bundle = await rollup({
input: 'hash.js',
onwarn: () => t.fail('No warnings were expected'),
plugins: [
nodeResolve(),
{
load(id) {
if (id === resolve(__dirname, 'fixtures', 'node_modules', 'test', 'index.js#foo')) {
return 'export default "resolved with hash"';
}
return null;
}
}
]
});
const { module } = await testBundle(t, bundle);

t.is(module.exports, 'resolved with hash');
});

test('can resolve imports with search params', async (t) => {
const bundle = await rollup({
input: 'search-params.js',
onwarn: () => t.fail('No warnings were expected'),
plugins: [
nodeResolve(),
{
load(id) {
if (
id ===
resolve(__dirname, 'fixtures', 'node_modules', 'test', 'index.js?foo=bar&lorem=ipsum')
) {
return 'export default "resolved with search params"';
}
return null;
}
}
]
});
const { module } = await testBundle(t, bundle);

t.is(module.exports, 'resolved with search params');
});

test('can resolve imports with search params and hash', async (t) => {
const bundle = await rollup({
input: 'search-params-and-hash.js',
onwarn: () => t.fail('No warnings were expected'),
plugins: [
nodeResolve(),
{
load(id) {
if (
id ===
resolve(
__dirname,
'fixtures',
'node_modules',
'test',
'index.js?foo=bar&lorem=ipsum#foo'
)
) {
return 'export default "resolved with search params and hash"';
}
return null;
}
}
]
});
const { module } = await testBundle(t, bundle);

t.is(module.exports, 'resolved with search params and hash');
});