Skip to content

Commit

Permalink
don't mutate InputTarget's passed to @babel/helper-compilation-targets
Browse files Browse the repository at this point in the history
If `@babel/helper-compilation-targets` is called directly, as it is in the
[Ember-CLI
babel](https://github.com/babel/ember-cli-babel/blob/6f76f405b9dd2a48cce394c4826dd50847f74282/index.js#L543-L545)
and [Vue
CLI](https://github.com/vuejs/vue-cli/blob/c8cecffedbf7b19cf930bb2821b5c352bc716a67/packages/%40vue/babel-preset-app/index.js#L17)
integrations, we don't want to mutate the input passed in. At least in Ember
CLI, babel could be called multiple times. So, on subsequent passes all
`browsers` and `esmodules` info would be lost (and losing the `browsers` info
affects the output in negative ways.. Copying the object before dropping keys
allows callers not have to worry about babel mutating the object they pass in.
Switching to a more functional approach makes it easier for babel to not worry
about what consumers are passing in.

Dropping the `browser` property was introduced in: #11500
Dropping the `esmodules` property was introduced in #11124

Discussion about dropping the `esmodules` property: #11124 (comment)
  • Loading branch information
fivetanley committed May 29, 2020
1 parent 5b24d79 commit 7bf0302
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
16 changes: 9 additions & 7 deletions packages/babel-helper-compilation-targets/src/index.js
Expand Up @@ -166,24 +166,26 @@ export default function getTargets(
options: Object = {},
): Targets {
const targetOpts: Targets = {};
let { browsers } = inputTargets;

// `esmodules` as a target indicates the specific set of browsers supporting ES Modules.
// These values OVERRIDE the `browsers` field.
if (inputTargets.esmodules) {
const supportsESModules = browserModulesData["es6.module"];
inputTargets.browsers = Object.keys(supportsESModules)
browsers = Object.keys(supportsESModules)
.map(browser => `${browser} ${supportsESModules[browser]}`)
.join(", ");
}

// Remove esmodules after being consumed to fix `hasTargets` below
delete inputTargets.esmodules;

// Parse browsers target via browserslist
const browsersquery = validateBrowsers(inputTargets.browsers);
delete inputTargets.browsers;
const browsersquery = validateBrowsers(browsers);

// Remove esmodules after being consumed to fix `hasTargets` below
const input = { ...inputTargets };
delete input.esmodules;
delete input.browsers;

let targets: Targets = validateTargetNames(inputTargets);
let targets: Targets = validateTargetNames(input);

const shouldParseBrowsers = !!browsersquery;
const hasTargets = shouldParseBrowsers || Object.keys(targets).length > 0;
Expand Down
Expand Up @@ -20,6 +20,18 @@ describe("getTargets", () => {
});
});

it("does not mutate the input", () => {
const input = Object.freeze({ browsers: "defaults", esmodules: true });
const expected = getTargets({
browsers: browserslist.defaults,
esmodules: true,
});
const actual = getTargets(input);
expect(actual).toEqual(expected);
expect(input.browsers).toEqual("defaults");
expect(input.esmodules).toEqual(true);
});

it("allows 'defaults' query", () => {
const browserslistDefaults = browserslist.defaults;

Expand Down

0 comments on commit 7bf0302

Please sign in to comment.