Skip to content

Commit e68f2ce

Browse files
Correctly handle relative browserslistConfigFile paths (#13031)
* Correctly handle relative `browserslistConfigFile` * Fix flow
1 parent 16d8300 commit e68f2ce

5 files changed

Lines changed: 53 additions & 24 deletions

File tree

packages/babel-core/src/config/config-descriptors.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import type {
1919
PluginItem,
2020
} from "./validation/options";
2121

22+
import { resolveBrowserslistConfigFile } from "./resolve-targets";
23+
2224
// Represents a config object and functions to lazily load the descriptors
2325
// for the plugins and presets so we don't load the plugins/presets unless
2426
// the options object actually ends up being applicable.
@@ -71,6 +73,19 @@ function* handlerOf<T>(value: T): Handler<T> {
7173
return value;
7274
}
7375

76+
function optionsWithResolvedBrowserslistConfigFile(
77+
options: ValidatedOptions,
78+
dirname: string,
79+
): ValidatedOptions {
80+
if (typeof options.browserslistConfigFile === "string") {
81+
options.browserslistConfigFile = resolveBrowserslistConfigFile(
82+
options.browserslistConfigFile,
83+
dirname,
84+
);
85+
}
86+
return options;
87+
}
88+
7489
/**
7590
* Create a set of descriptors from a given options object, preserving
7691
* descriptor identity based on the identity of the plugin/preset arrays
@@ -83,7 +98,7 @@ export function createCachedDescriptors(
8398
): OptionsAndDescriptors {
8499
const { plugins, presets, passPerPreset } = options;
85100
return {
86-
options,
101+
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
87102
plugins: plugins
88103
? () => createCachedPluginDescriptors(plugins, dirname)(alias)
89104
: () => handlerOf([]),
@@ -112,7 +127,7 @@ export function createUncachedDescriptors(
112127
let presets;
113128

114129
return {
115-
options,
130+
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
116131
*plugins() {
117132
if (!plugins) {
118133
plugins = yield* createPluginDescriptors(

packages/babel-core/src/config/partial.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export default function* loadPrivatePartialConfig(
126126

127127
const options: NormalizedOptions = {
128128
...merged,
129-
targets: resolveTargets(merged, absoluteRootDir, absoluteRootDir),
129+
targets: resolveTargets(merged, absoluteRootDir),
130130

131131
// Tack the passes onto the object itself so that, if this object is
132132
// passed back to Babel a second time, it will be in the right structure

packages/babel-core/src/config/resolve-targets-browser.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
import type { ValidatedOptions } from "./validation/options";
44
import getTargets, { type Targets } from "@babel/helper-compilation-targets";
55

6+
export function resolveBrowserslistConfigFile(
7+
// eslint-disable-next-line no-unused-vars
8+
browserslistConfigFile: string,
9+
// eslint-disable-next-line no-unused-vars
10+
configFilePath: string,
11+
): string | void {
12+
return undefined;
13+
}
14+
615
export function resolveTargets(
716
options: ValidatedOptions,
817
// eslint-disable-next-line no-unused-vars
918
root: string,
10-
// eslint-disable-next-line no-unused-vars
11-
configFilePath: string | void,
1219
): Targets {
1320
let { targets } = options;
1421
if (typeof targets === "string" || Array.isArray(targets)) {

packages/babel-core/src/config/resolve-targets.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@ import type { ValidatedOptions } from "./validation/options";
1111
import path from "path";
1212
import getTargets, { type Targets } from "@babel/helper-compilation-targets";
1313

14+
export function resolveBrowserslistConfigFile(
15+
browserslistConfigFile: string,
16+
configFileDir: string,
17+
): string | void {
18+
return path.resolve(configFileDir, browserslistConfigFile);
19+
}
20+
1421
export function resolveTargets(
1522
options: ValidatedOptions,
1623
root: string,
17-
configFilePath: string = root,
1824
): Targets {
1925
let { targets } = options;
2026
if (typeof targets === "string" || Array.isArray(targets)) {
@@ -25,13 +31,17 @@ export function resolveTargets(
2531
targets = { ...targets, esmodules: "intersect" };
2632
}
2733

34+
const { browserslistConfigFile } = options;
2835
let configFile;
29-
if (typeof options.browserslistConfigFile === "string") {
30-
configFile = path.resolve(configFilePath, options.browserslistConfigFile);
36+
let ignoreBrowserslistConfig = false;
37+
if (typeof browserslistConfigFile === "string") {
38+
configFile = browserslistConfigFile;
39+
} else {
40+
ignoreBrowserslistConfig = browserslistConfigFile === false;
3141
}
3242

3343
return getTargets((targets: any), {
34-
ignoreBrowserslistConfig: options.browserslistConfigFile === false,
44+
ignoreBrowserslistConfig,
3545
configFile,
3646
configPath: root,
3747
browserslistEnv: options.browserslistEnv,

packages/babel-core/test/targets.js

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,6 @@ describe("browserslist", () => {
100100
).toEqual({ chrome: "80.0.0" });
101101
});
102102

103-
// TODO: browserslistConfig is currently resolved starting from the root
104-
// rather than from the config file.
105-
// eslint-disable-next-line jest/no-disabled-tests
106-
it.skip("loads nested .browserslistrc files if explicitly specified", () => {
107-
expect(
108-
loadOptions({
109-
cwd: join(cwd, "fixtures", "targets"),
110-
filename: "./node_modules/dep/test.js",
111-
babelrcRoots: ["./node_modules/dep/"],
112-
}).targets,
113-
).toEqual({ edge: "14.0.0" });
114-
});
115-
116103
describe("browserslistConfigFile", () => {
117104
it("can disable config loading", () => {
118105
expect(
@@ -132,16 +119,26 @@ describe("browserslist", () => {
132119
).toEqual({ firefox: "74.0.0" });
133120
});
134121

135-
it("is relative to the project root", () => {
122+
it("is relative to the cwd even if specifying 'root'", () => {
136123
expect(
137124
loadOptions({
138125
cwd: join(cwd, "fixtures", "targets"),
139126
root: "..",
140127
filename: "./nested/test.js",
141-
browserslistConfigFile: "./targets/.browserslistrc-firefox",
128+
browserslistConfigFile: "./.browserslistrc-firefox",
142129
}).targets,
143130
).toEqual({ firefox: "74.0.0" });
144131
});
132+
133+
it("is relative to the config files that defines it", () => {
134+
expect(
135+
loadOptions({
136+
cwd: join(cwd, "fixtures", "targets"),
137+
filename: "./node_modules/dep/test.js",
138+
babelrcRoots: ["./node_modules/dep/"],
139+
}).targets,
140+
).toEqual({ edge: "14.0.0" });
141+
});
145142
});
146143

147144
describe("browserslistEnv", () => {

0 commit comments

Comments
 (0)