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

Follow up to #843, refining exports and browser field interaction #866

Merged
merged 10 commits into from Apr 30, 2021
2 changes: 1 addition & 1 deletion packages/node-resolve/README.md
Expand Up @@ -64,7 +64,7 @@ Setting this option will add extra conditions on top of the default conditions.
Type: `Boolean`<br>
Default: `false`

If `true`, instructs the plugin to use the `"browser"` property in `package.json` files to specify alternative files to load for bundling. This is useful when bundling for a browser environment. Alternatively, a value of `'browser'` can be added to the `mainFields` option. If `false`, any `"browser"` properties in package files will be ignored. This option takes precedence over `mainFields`.
If `true`, instructs the plugin to use the browser module resolutions in `package.json` and adds `'browser'` to `exportConditions` if it is not present so browser conditionals in `exports` are applied. If `false`, any browser properties in package files will be ignored. Alternatively, a value of `'browser'` can be added to both the `mainFields` and `exportConditions` options, however this option takes precedence over `mainFields`.

> This option does not work when a package is using [package entrypoints](https://nodejs.org/api/packages.html#packages_package_entry_points)

Expand Down
3 changes: 3 additions & 0 deletions packages/node-resolve/src/index.js
Expand Up @@ -161,6 +161,9 @@ export function nodeResolve(opts = {}) {
opts && opts.custom && opts.custom['node-resolve'] && opts.custom['node-resolve'].isRequire;
const exportConditions = isRequire ? conditionsCjs : conditionsEsm;

if (useBrowserOverrides && !exportConditions.includes('browser'))
exportConditions.push('browser');

const resolvedWithoutBuiltins = await resolveImportSpecifiers({
importer,
importSpecifierList,
Expand Down
4 changes: 2 additions & 2 deletions packages/node-resolve/src/package/resolvePackageTarget.js
Expand Up @@ -24,11 +24,11 @@ async function resolvePackageTarget(context, { target, subpath, pattern, interna
target.replace(/\*/g, subpath),
context.pkgURL.href
);
return result ? pathToFileURL(result.location) : null;
return result ? pathToFileURL(result.location).href : null;
}

const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
return result ? pathToFileURL(result.location) : null;
return result ? pathToFileURL(result.location).href : null;
}
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
Expand Down
20 changes: 20 additions & 0 deletions packages/node-resolve/test/browser.js
Expand Up @@ -199,3 +199,23 @@ test('pkg.browser with mapping to prevent bundle by specifying a value of false'

t.is(module.exports, 'ok');
});

test('exports.browser can be mapped via pkg.browser', async (t) => {
const bundle = await rollup({
input: 'browser-exports-browser-browser.js',
plugins: [nodeResolve({ browser: true }), commonjs()]
});
const { module } = await testBundle(t, bundle);

t.is(module.exports, 'browser');
});

test('browser field does not take precedence over export map result', 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, 'require');
});
@@ -0,0 +1,3 @@
import b from 'exports-browser-browser';

module.exports = b;
@@ -0,0 +1,3 @@
const b = require('exports-browser');

module.exports = b;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.