Allow users to choose how the configuration root is selected. (#8660)
This commit is contained in:
parent
aac8118b7f
commit
bd0c62dc0c
@ -28,6 +28,11 @@ commander.option(
|
||||
"The name of the 'env' to use when loading configs and plugins. " +
|
||||
"Defaults to the value of BABEL_ENV, or else NODE_ENV, or else 'development'.",
|
||||
);
|
||||
commander.option(
|
||||
"--root-mode [mode]",
|
||||
"The project-root resolution mode. " +
|
||||
"One of 'root' (the default), 'upward', or 'upward-optional'.",
|
||||
);
|
||||
|
||||
// Basic file input configuration.
|
||||
commander.option("--source-type [script|module]", "");
|
||||
@ -220,6 +225,7 @@ export default function parseArgv(args: Array<string>) {
|
||||
babelOptions: {
|
||||
presets: opts.presets,
|
||||
plugins: opts.plugins,
|
||||
rootMode: opts.rootMode,
|
||||
configFile: opts.configFile,
|
||||
envName: opts.envName,
|
||||
sourceType: opts.sourceType,
|
||||
|
||||
@ -24,6 +24,21 @@ const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
export function findConfigUpwards(rootDir: string): string | null {
|
||||
let dirname = rootDir;
|
||||
while (true) {
|
||||
if (fs.existsSync(path.join(dirname, BABEL_CONFIG_JS_FILENAME))) {
|
||||
return dirname;
|
||||
}
|
||||
|
||||
const nextDir = path.dirname(dirname);
|
||||
if (dirname === nextDir) break;
|
||||
dirname = nextDir;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findRelativeConfig(
|
||||
packageData: FilePackageData,
|
||||
envName: string,
|
||||
|
||||
@ -11,6 +11,12 @@ import type { CallerMetadata } from "../validation/options";
|
||||
|
||||
export type { ConfigFile, IgnoreFile, RelativeConfig, FilePackageData };
|
||||
|
||||
export function findConfigUpwards(
|
||||
rootDir: string, // eslint-disable-line no-unused-vars
|
||||
): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findPackageData(filepath: string): FilePackageData {
|
||||
return {
|
||||
filepath,
|
||||
|
||||
@ -10,6 +10,7 @@ import typeof * as indexType from "./index";
|
||||
export { findPackageData } from "./package";
|
||||
|
||||
export {
|
||||
findConfigUpwards,
|
||||
findRelativeConfig,
|
||||
findRootConfig,
|
||||
loadConfig,
|
||||
|
||||
@ -6,9 +6,43 @@ import { mergeOptions } from "./util";
|
||||
import { createItemFromDescriptor } from "./item";
|
||||
import { buildRootChain, type ConfigContext } from "./config-chain";
|
||||
import { getEnv } from "./helpers/environment";
|
||||
import { validate, type ValidatedOptions } from "./validation/options";
|
||||
import {
|
||||
validate,
|
||||
type ValidatedOptions,
|
||||
type RootMode,
|
||||
} from "./validation/options";
|
||||
|
||||
import type { ConfigFile, IgnoreFile } from "./files";
|
||||
import { findConfigUpwards, type ConfigFile, type IgnoreFile } from "./files";
|
||||
|
||||
function resolveRootMode(rootDir: string, rootMode: RootMode): string {
|
||||
switch (rootMode) {
|
||||
case "root":
|
||||
return rootDir;
|
||||
|
||||
case "upward-optional": {
|
||||
const upwardRootDir = findConfigUpwards(rootDir);
|
||||
return upwardRootDir === null ? rootDir : upwardRootDir;
|
||||
}
|
||||
|
||||
case "upward": {
|
||||
const upwardRootDir = findConfigUpwards(rootDir);
|
||||
if (upwardRootDir !== null) return upwardRootDir;
|
||||
|
||||
throw Object.assign(
|
||||
(new Error(
|
||||
`Babel was run with rootMode:"upward" but a root could not ` +
|
||||
`be found when searching upward from "${rootDir}"`,
|
||||
): any),
|
||||
{
|
||||
code: "BABEL_ROOT_NOT_FOUND",
|
||||
dirname: rootDir,
|
||||
},
|
||||
);
|
||||
}
|
||||
default:
|
||||
throw new Error(`Assertion failure - unknown rootMode value`);
|
||||
}
|
||||
}
|
||||
|
||||
export default function loadPrivatePartialConfig(
|
||||
inputOpts: mixed,
|
||||
@ -28,9 +62,18 @@ export default function loadPrivatePartialConfig(
|
||||
|
||||
const args = inputOpts ? validate("arguments", inputOpts) : {};
|
||||
|
||||
const { envName = getEnv(), cwd = ".", root: rootDir = ".", caller } = args;
|
||||
const {
|
||||
envName = getEnv(),
|
||||
cwd = ".",
|
||||
root: rootDir = ".",
|
||||
rootMode = "root",
|
||||
caller,
|
||||
} = args;
|
||||
const absoluteCwd = path.resolve(cwd);
|
||||
const absoluteRootDir = path.resolve(absoluteCwd, rootDir);
|
||||
const absoluteRootDir = resolveRootMode(
|
||||
path.resolve(absoluteCwd, rootDir),
|
||||
rootMode,
|
||||
);
|
||||
|
||||
const context: ConfigContext = {
|
||||
filename:
|
||||
|
||||
@ -15,6 +15,7 @@ import type {
|
||||
RootInputSourceMapOption,
|
||||
NestingPath,
|
||||
CallerMetadata,
|
||||
RootMode,
|
||||
} from "./options";
|
||||
|
||||
export type ValidatorSet = {
|
||||
@ -60,6 +61,20 @@ type AccessPath = $ReadOnly<{
|
||||
}>;
|
||||
type GeneralPath = OptionPath | AccessPath;
|
||||
|
||||
export function assertRootMode(loc: OptionPath, value: mixed): RootMode | void {
|
||||
if (
|
||||
value !== undefined &&
|
||||
value !== "root" &&
|
||||
value !== "upward" &&
|
||||
value !== "upward-optional"
|
||||
) {
|
||||
throw new Error(
|
||||
`${msg(loc)} must be a "root", "upward", "upward-optional" or undefined`,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertSourceMaps(
|
||||
loc: OptionPath,
|
||||
value: mixed,
|
||||
|
||||
@ -19,6 +19,7 @@ import {
|
||||
assertConfigFileSearch,
|
||||
assertBabelrcSearch,
|
||||
assertFunction,
|
||||
assertRootMode,
|
||||
assertSourceMaps,
|
||||
assertCompact,
|
||||
assertSourceType,
|
||||
@ -30,6 +31,9 @@ import {
|
||||
const ROOT_VALIDATORS: ValidatorSet = {
|
||||
cwd: (assertString: Validator<$PropertyType<ValidatedOptions, "cwd">>),
|
||||
root: (assertString: Validator<$PropertyType<ValidatedOptions, "root">>),
|
||||
rootMode: (assertRootMode: Validator<
|
||||
$PropertyType<ValidatedOptions, "rootMode">,
|
||||
>),
|
||||
configFile: (assertConfigFileSearch: Validator<
|
||||
$PropertyType<ValidatedOptions, "configFile">,
|
||||
>),
|
||||
@ -176,6 +180,7 @@ export type ValidatedOptions = {
|
||||
babelrcRoots?: BabelrcSearch,
|
||||
configFile?: ConfigFileSearch,
|
||||
root?: string,
|
||||
rootMode?: RootMode,
|
||||
code?: boolean,
|
||||
ast?: boolean,
|
||||
inputSourceMap?: RootInputSourceMapOption,
|
||||
@ -260,6 +265,7 @@ export type SourceMapsOption = boolean | "inline" | "both";
|
||||
export type SourceTypeOption = "module" | "script" | "unambiguous";
|
||||
export type CompactOption = boolean | "auto";
|
||||
export type RootInputSourceMapOption = {} | boolean;
|
||||
export type RootMode = "root" | "upward" | "upward-optional";
|
||||
|
||||
export type OptionsSource =
|
||||
| "arguments"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user