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

Correctly handle relative browserslistConfigFile paths #13031

Merged
merged 2 commits into from Mar 26, 2021
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
19 changes: 17 additions & 2 deletions packages/babel-core/src/config/config-descriptors.js
Expand Up @@ -19,6 +19,8 @@ import type {
PluginItem,
} from "./validation/options";

import { resolveBrowserslistConfigFile } from "./resolve-targets";

// Represents a config object and functions to lazily load the descriptors
// for the plugins and presets so we don't load the plugins/presets unless
// the options object actually ends up being applicable.
Expand Down Expand Up @@ -71,6 +73,19 @@ function* handlerOf<T>(value: T): Handler<T> {
return value;
}

function optionsWithResolvedBrowserslistConfigFile(
options: ValidatedOptions,
dirname: string,
): ValidatedOptions {
if (typeof options.browserslistConfigFile === "string") {
options.browserslistConfigFile = resolveBrowserslistConfigFile(
options.browserslistConfigFile,
dirname,
);
}
return options;
}

/**
* Create a set of descriptors from a given options object, preserving
* descriptor identity based on the identity of the plugin/preset arrays
Expand All @@ -83,7 +98,7 @@ export function createCachedDescriptors(
): OptionsAndDescriptors {
const { plugins, presets, passPerPreset } = options;
return {
options,
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
plugins: plugins
? () => createCachedPluginDescriptors(plugins, dirname)(alias)
: () => handlerOf([]),
Expand Down Expand Up @@ -112,7 +127,7 @@ export function createUncachedDescriptors(
let presets;

return {
options,
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
*plugins() {
if (!plugins) {
plugins = yield* createPluginDescriptors(
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-core/src/config/partial.js
Expand Up @@ -126,7 +126,7 @@ export default function* loadPrivatePartialConfig(

const options: NormalizedOptions = {
...merged,
targets: resolveTargets(merged, absoluteRootDir, absoluteRootDir),
targets: resolveTargets(merged, absoluteRootDir),

// Tack the passes onto the object itself so that, if this object is
// passed back to Babel a second time, it will be in the right structure
Expand Down
11 changes: 9 additions & 2 deletions packages/babel-core/src/config/resolve-targets-browser.js
Expand Up @@ -3,12 +3,19 @@
import type { ValidatedOptions } from "./validation/options";
import getTargets, { type Targets } from "@babel/helper-compilation-targets";

export function resolveBrowserslistConfigFile(
// eslint-disable-next-line no-unused-vars
browserslistConfigFile: string,
// eslint-disable-next-line no-unused-vars
configFilePath: string,
): string | void {
return undefined;
}

export function resolveTargets(
options: ValidatedOptions,
// eslint-disable-next-line no-unused-vars
root: string,
// eslint-disable-next-line no-unused-vars
configFilePath: string | void,
): Targets {
let { targets } = options;
if (typeof targets === "string" || Array.isArray(targets)) {
Expand Down
18 changes: 14 additions & 4 deletions packages/babel-core/src/config/resolve-targets.js
Expand Up @@ -11,10 +11,16 @@ import type { ValidatedOptions } from "./validation/options";
import path from "path";
import getTargets, { type Targets } from "@babel/helper-compilation-targets";

export function resolveBrowserslistConfigFile(
browserslistConfigFile: string,
configFileDir: string,
): string | void {
return path.resolve(configFileDir, browserslistConfigFile);
}

export function resolveTargets(
options: ValidatedOptions,
root: string,
configFilePath: string = root,
): Targets {
let { targets } = options;
if (typeof targets === "string" || Array.isArray(targets)) {
Expand All @@ -25,13 +31,17 @@ export function resolveTargets(
targets = { ...targets, esmodules: "intersect" };
}

const { browserslistConfigFile } = options;
let configFile;
if (typeof options.browserslistConfigFile === "string") {
configFile = path.resolve(configFilePath, options.browserslistConfigFile);
let ignoreBrowserslistConfig = false;
if (typeof browserslistConfigFile === "string") {
configFile = browserslistConfigFile;
} else {
ignoreBrowserslistConfig = browserslistConfigFile === false;
}

return getTargets((targets: any), {
ignoreBrowserslistConfig: options.browserslistConfigFile === false,
ignoreBrowserslistConfig,
configFile,
configPath: root,
browserslistEnv: options.browserslistEnv,
Expand Down
27 changes: 12 additions & 15 deletions packages/babel-core/test/targets.js
Expand Up @@ -100,19 +100,6 @@ describe("browserslist", () => {
).toEqual({ chrome: "80.0.0" });
});

// TODO: browserslistConfig is currently resolved starting from the root
// rather than from the config file.
// eslint-disable-next-line jest/no-disabled-tests
it.skip("loads nested .browserslistrc files if explicitly specified", () => {
expect(
loadOptions({
cwd: join(cwd, "fixtures", "targets"),
filename: "./node_modules/dep/test.js",
babelrcRoots: ["./node_modules/dep/"],
}).targets,
).toEqual({ edge: "14.0.0" });
});

describe("browserslistConfigFile", () => {
it("can disable config loading", () => {
expect(
Expand All @@ -132,16 +119,26 @@ describe("browserslist", () => {
).toEqual({ firefox: "74.0.0" });
});

it("is relative to the project root", () => {
it("is relative to the cwd even if specifying 'root'", () => {
expect(
loadOptions({
cwd: join(cwd, "fixtures", "targets"),
root: "..",
filename: "./nested/test.js",
browserslistConfigFile: "./targets/.browserslistrc-firefox",
browserslistConfigFile: "./.browserslistrc-firefox",
}).targets,
).toEqual({ firefox: "74.0.0" });
});

it("is relative to the config files that defines it", () => {
expect(
loadOptions({
cwd: join(cwd, "fixtures", "targets"),
filename: "./node_modules/dep/test.js",
babelrcRoots: ["./node_modules/dep/"],
}).targets,
).toEqual({ edge: "14.0.0" });
});
});

describe("browserslistEnv", () => {
Expand Down