diff --git a/packages/node-resolve/rollup.config.js b/packages/node-resolve/rollup.config.js index 6d6adea13..f7f4671ef 100755 --- a/packages/node-resolve/rollup.config.js +++ b/packages/node-resolve/rollup.config.js @@ -12,7 +12,7 @@ export default { throw new Error(warning); }, output: [ - { file: pkg.main, format: 'cjs', exports: 'named' }, + { file: pkg.main, format: 'cjs', exports: 'named', sourcemap: true }, { file: pkg.module, format: 'es', plugins: [emitModulePackageFile()] } ] }; diff --git a/packages/node-resolve/src/package/resolvePackageTarget.js b/packages/node-resolve/src/package/resolvePackageTarget.js index 47ead33d5..65a781a07 100644 --- a/packages/node-resolve/src/package/resolvePackageTarget.js +++ b/packages/node-resolve/src/package/resolvePackageTarget.js @@ -86,10 +86,25 @@ async function resolvePackageTarget(context, { target, subpath, pattern, interna } if (target && typeof target === 'object') { + const { packageBrowserField, useBrowserOverrides } = context; + let browserTarget = null; + + if (useBrowserOverrides) { + if (Object.keys(target).includes('browser')) { + browserTarget = target.browser; + } else { + for (const [, value] of Object.entries(target)) { + if (packageBrowserField[value]) { + browserTarget = value; + } + } + } + } + for (const [key, value] of Object.entries(target)) { if (key === 'default' || context.conditions.includes(key)) { const resolved = await resolvePackageTarget(context, { - target: value, + target: browserTarget || value, subpath, pattern, internal diff --git a/packages/node-resolve/src/resolveImportSpecifiers.js b/packages/node-resolve/src/resolveImportSpecifiers.js index 6c0904bf8..5909e7fa0 100644 --- a/packages/node-resolve/src/resolveImportSpecifiers.js +++ b/packages/node-resolve/src/resolveImportSpecifiers.js @@ -92,6 +92,8 @@ async function resolveId({ importer, moduleDirs: moduleDirectories, conditions: exportConditions, + useBrowserOverrides, + packageBrowserField, resolveId(id, parent) { return resolveId({ importSpecifier: id, @@ -103,6 +105,7 @@ async function resolveId({ mainFields, preserveSymlinks, useBrowserOverrides, + packageBrowserField, baseDir, moduleDirectories }); @@ -127,7 +130,9 @@ async function resolveId({ moduleDirs: moduleDirectories, pkgURL, pkgJsonPath, - conditions: exportConditions + conditions: exportConditions, + useBrowserOverrides, + packageBrowserField }; const resolvedPackageExport = await resolvePackageExports( context, diff --git a/packages/node-resolve/test/browser.js b/packages/node-resolve/test/browser.js index 69a63dfe7..172de3646 100644 --- a/packages/node-resolve/test/browser.js +++ b/packages/node-resolve/test/browser.js @@ -199,3 +199,33 @@ test('pkg.browser with mapping to prevent bundle by specifying a value of false' t.is(module.exports, 'ok'); }); + +test('pkg.browser can override the export map result', async (t) => { + const bundle = await rollup({ + input: 'browser-override-exports.js', + plugins: [nodeResolve({ browser: true }), commonjs()] + }); + const { module } = await testBundle(t, bundle); + + t.is(module.exports, 'browser'); +}); + +test('exports.browser takes precedence over export map result, when browser:true', async (t) => { + const bundle = await rollup({ + input: 'browser-exports-browser.js', + plugins: [nodeResolve({ browser: true }), commonjs()] + }); + const { module } = await testBundle(t, bundle); + + t.is(module.exports, 'browser'); +}); + +test('exports.browser does not take precedence over export map result, when browser:false', async (t) => { + const bundle = await rollup({ + input: 'browser-exports-browser.js', + plugins: [nodeResolve(), commonjs()] + }); + const { module } = await testBundle(t, bundle); + + t.is(module.exports, 'require'); +}); diff --git a/packages/node-resolve/test/fixtures/browser-exports-browser.js b/packages/node-resolve/test/fixtures/browser-exports-browser.js new file mode 100644 index 000000000..259175621 --- /dev/null +++ b/packages/node-resolve/test/fixtures/browser-exports-browser.js @@ -0,0 +1,3 @@ +const b = require('exports-browser'); + +module.exports = b; diff --git a/packages/node-resolve/test/fixtures/browser-override-exports.js b/packages/node-resolve/test/fixtures/browser-override-exports.js new file mode 100755 index 000000000..72cf3596c --- /dev/null +++ b/packages/node-resolve/test/fixtures/browser-override-exports.js @@ -0,0 +1,3 @@ +const Nanoid = require('nanoid'); + +module.exports = Nanoid; diff --git a/packages/node-resolve/test/fixtures/node_modules/exports-browser/browser.js b/packages/node-resolve/test/fixtures/node_modules/exports-browser/browser.js new file mode 100644 index 000000000..842765579 --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/exports-browser/browser.js @@ -0,0 +1 @@ +module.exports = 'browser'; diff --git a/packages/node-resolve/test/fixtures/node_modules/exports-browser/ignored-browser.js b/packages/node-resolve/test/fixtures/node_modules/exports-browser/ignored-browser.js new file mode 100644 index 000000000..9081288bf --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/exports-browser/ignored-browser.js @@ -0,0 +1 @@ +module.exports = 'ignored-browser'; diff --git a/packages/node-resolve/test/fixtures/node_modules/exports-browser/import.js b/packages/node-resolve/test/fixtures/node_modules/exports-browser/import.js new file mode 100644 index 000000000..c3d68ff4b --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/exports-browser/import.js @@ -0,0 +1 @@ +module.exports = 'import'; diff --git a/packages/node-resolve/test/fixtures/node_modules/exports-browser/package.json b/packages/node-resolve/test/fixtures/node_modules/exports-browser/package.json new file mode 100644 index 000000000..81776a7df --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/exports-browser/package.json @@ -0,0 +1,14 @@ +{ + "main": "index.cjs", + "module": "index.js", + "browser": { + "./index.js": "./ignored-browser.js" + }, + "exports": { + ".": { + "require": "./require.js", + "import": "./import.js", + "browser": "./browser.js" + } + } +} diff --git a/packages/node-resolve/test/fixtures/node_modules/exports-browser/require.js b/packages/node-resolve/test/fixtures/node_modules/exports-browser/require.js new file mode 100644 index 000000000..67b9a8353 --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/exports-browser/require.js @@ -0,0 +1 @@ +module.exports = 'require' diff --git a/packages/node-resolve/test/fixtures/node_modules/nanoid/index.cjs b/packages/node-resolve/test/fixtures/node_modules/nanoid/index.cjs new file mode 100644 index 000000000..3c0bd0ba3 --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/nanoid/index.cjs @@ -0,0 +1 @@ +module.exports = 'node' \ No newline at end of file diff --git a/packages/node-resolve/test/fixtures/node_modules/nanoid/index.js b/packages/node-resolve/test/fixtures/node_modules/nanoid/index.js new file mode 100644 index 000000000..e1aec08d4 --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/nanoid/index.js @@ -0,0 +1 @@ +module.exports = 'browser' \ No newline at end of file diff --git a/packages/node-resolve/test/fixtures/node_modules/nanoid/package.json b/packages/node-resolve/test/fixtures/node_modules/nanoid/package.json new file mode 100644 index 000000000..9ae3ffb5f --- /dev/null +++ b/packages/node-resolve/test/fixtures/node_modules/nanoid/package.json @@ -0,0 +1,13 @@ +{ + "main": "index.cjs", + "module": "index.js", + "browser": { + "./index.js": "./index.js" + }, + "exports": { + ".": { + "require": "./index.cjs", + "import": "./index.js" + } + } +} \ No newline at end of file