From 997b8a5765ddd7abca84d53d5b2e107f4e8baf67 Mon Sep 17 00:00:00 2001 From: Lars den Bakker Date: Sun, 12 Jul 2020 22:05:51 +0200 Subject: [PATCH] feat(node-resolve): preserve search params and hashes (#487) --- packages/node-resolve/src/index.js | 16 +++- packages/node-resolve/test/fixtures/hash.js | 3 + .../test/fixtures/search-params-and-hash.js | 3 + .../test/fixtures/search-params.js | 3 + packages/node-resolve/test/test.js | 75 +++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 packages/node-resolve/test/fixtures/hash.js create mode 100644 packages/node-resolve/test/fixtures/search-params-and-hash.js create mode 100644 packages/node-resolve/test/fixtures/search-params.js diff --git a/packages/node-resolve/src/index.js b/packages/node-resolve/src/index.js index 5465b38bc..27ec0b797 100644 --- a/packages/node-resolve/src/index.js +++ b/packages/node-resolve/src/index.js @@ -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 @@ -244,11 +250,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; diff --git a/packages/node-resolve/test/fixtures/hash.js b/packages/node-resolve/test/fixtures/hash.js new file mode 100644 index 000000000..c4ebf73fd --- /dev/null +++ b/packages/node-resolve/test/fixtures/hash.js @@ -0,0 +1,3 @@ +import test from 'test#foo'; + +export default test; diff --git a/packages/node-resolve/test/fixtures/search-params-and-hash.js b/packages/node-resolve/test/fixtures/search-params-and-hash.js new file mode 100644 index 000000000..0d57a21e7 --- /dev/null +++ b/packages/node-resolve/test/fixtures/search-params-and-hash.js @@ -0,0 +1,3 @@ +import test from 'test?foo=bar&lorem=ipsum#foo'; + +export default test; diff --git a/packages/node-resolve/test/fixtures/search-params.js b/packages/node-resolve/test/fixtures/search-params.js new file mode 100644 index 000000000..64222f28e --- /dev/null +++ b/packages/node-resolve/test/fixtures/search-params.js @@ -0,0 +1,3 @@ +import test from 'test?foo=bar&lorem=ipsum'; + +export default test; diff --git a/packages/node-resolve/test/test.js b/packages/node-resolve/test/test.js index bf95d568c..69fd157b6 100755 --- a/packages/node-resolve/test/test.js +++ b/packages/node-resolve/test/test.js @@ -239,3 +239,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'); +});