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

fix: @babel/node repl and enable no-use-before-define rule #15124

Merged
merged 2 commits into from Nov 4, 2022
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
8 changes: 8 additions & 0 deletions .eslintrc.cjs
Expand Up @@ -53,6 +53,14 @@ module.exports = {
"error",
{ disallowTypeAnnotations: false },
],
"@typescript-eslint/no-use-before-define": [
"error",
{
functions: false,
classes: false,
allowNamedExports: true,
},
],
},
},
{
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-core/src/config/config-chain.ts
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-use-before-define */

import path from "path";
import buildDebug from "debug";
import type { Handler } from "gensync";
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-core/src/config/config-descriptors.ts
Expand Up @@ -101,11 +101,13 @@ export function createCachedDescriptors(
plugins: plugins
? () =>
// @ts-expect-error todo(flow->ts) ts complains about incorrect arguments
// eslint-disable-next-line @typescript-eslint/no-use-before-define
createCachedPluginDescriptors(plugins, dirname)(alias)
: () => handlerOf([]),
presets: presets
? () =>
// @ts-expect-error todo(flow->ts) ts complains about incorrect arguments
// eslint-disable-next-line @typescript-eslint/no-use-before-define
createCachedPresetDescriptors(presets, dirname)(alias)(
!!passPerPreset,
)
Expand Down
254 changes: 127 additions & 127 deletions packages/babel-core/src/config/files/configuration.ts
Expand Up @@ -39,133 +39,6 @@ const RELATIVE_CONFIG_FILENAMES = [

const BABELIGNORE_FILENAME = ".babelignore";

export function findConfigUpwards(rootDir: string): string | null {
let dirname = rootDir;
for (;;) {
for (const filename of ROOT_CONFIG_FILENAMES) {
if (nodeFs.existsSync(path.join(dirname, filename))) {
return dirname;
}
}

const nextDir = path.dirname(dirname);
if (dirname === nextDir) break;
dirname = nextDir;
}

return null;
}

export function* findRelativeConfig(
packageData: FilePackageData,
envName: string,
caller: CallerMetadata | undefined,
): Handler<RelativeConfig> {
let config = null;
let ignore = null;

const dirname = path.dirname(packageData.filepath);

for (const loc of packageData.directories) {
if (!config) {
config = yield* loadOneConfig(
RELATIVE_CONFIG_FILENAMES,
loc,
envName,
caller,
packageData.pkg?.dirname === loc
? packageToBabelConfig(packageData.pkg as ConfigFile)
: null,
);
}

if (!ignore) {
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
ignore = yield* readIgnoreConfig(ignoreLoc);

if (ignore) {
debug("Found ignore %o from %o.", ignore.filepath, dirname);
}
}
}

return { config, ignore };
}

export function findRootConfig(
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile | null> {
return loadOneConfig(ROOT_CONFIG_FILENAMES, dirname, envName, caller);
}

function* loadOneConfig(
names: string[],
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
previousConfig: ConfigFile | null = null,
): Handler<ConfigFile | null> {
const configs = yield* gensync.all(
names.map(filename =>
readConfig(path.join(dirname, filename), envName, caller),
),
);
const config = configs.reduce((previousConfig: ConfigFile | null, config) => {
if (config && previousConfig) {
throw new ConfigError(
`Multiple configuration files found. Please remove one:\n` +
` - ${path.basename(previousConfig.filepath)}\n` +
` - ${config.filepath}\n` +
`from ${dirname}`,
);
}

return config || previousConfig;
}, previousConfig);

if (config) {
debug("Found configuration %o from %o.", config.filepath, dirname);
}
return config;
}

export function* loadConfig(
name: string,
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile> {
const filepath = require.resolve(name, { paths: [dirname] });

const conf = yield* readConfig(filepath, envName, caller);
if (!conf) {
throw new ConfigError(
`Config file contains no configuration data`,
filepath,
);
}

debug("Loaded config %o from %o.", name, dirname);
return conf;
}

/**
* Read the given config file, returning the result. Returns null if no config was found, but will
* throw if there are parsing errors while loading a config.
*/
function readConfig(
filepath: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile | null> {
const ext = path.extname(filepath);
return ext === ".js" || ext === ".cjs" || ext === ".mjs"
? readConfigJS(filepath, { envName, caller })
: readConfigJSON5(filepath);
}

const LOADING_CONFIGS = new Set();

const readConfigJS = makeStrongCache(function* readConfigJS(
Expand Down Expand Up @@ -318,6 +191,133 @@ const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
};
});

export function findConfigUpwards(rootDir: string): string | null {
let dirname = rootDir;
for (;;) {
for (const filename of ROOT_CONFIG_FILENAMES) {
if (nodeFs.existsSync(path.join(dirname, filename))) {
return dirname;
}
}

const nextDir = path.dirname(dirname);
if (dirname === nextDir) break;
dirname = nextDir;
}

return null;
}

export function* findRelativeConfig(
packageData: FilePackageData,
envName: string,
caller: CallerMetadata | undefined,
): Handler<RelativeConfig> {
let config = null;
let ignore = null;

const dirname = path.dirname(packageData.filepath);

for (const loc of packageData.directories) {
if (!config) {
config = yield* loadOneConfig(
RELATIVE_CONFIG_FILENAMES,
loc,
envName,
caller,
packageData.pkg?.dirname === loc
? packageToBabelConfig(packageData.pkg as ConfigFile)
: null,
);
}

if (!ignore) {
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
ignore = yield* readIgnoreConfig(ignoreLoc);

if (ignore) {
debug("Found ignore %o from %o.", ignore.filepath, dirname);
}
}
}

return { config, ignore };
}

export function findRootConfig(
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile | null> {
return loadOneConfig(ROOT_CONFIG_FILENAMES, dirname, envName, caller);
}

function* loadOneConfig(
names: string[],
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
previousConfig: ConfigFile | null = null,
): Handler<ConfigFile | null> {
const configs = yield* gensync.all(
names.map(filename =>
readConfig(path.join(dirname, filename), envName, caller),
),
);
const config = configs.reduce((previousConfig: ConfigFile | null, config) => {
if (config && previousConfig) {
throw new ConfigError(
`Multiple configuration files found. Please remove one:\n` +
` - ${path.basename(previousConfig.filepath)}\n` +
` - ${config.filepath}\n` +
`from ${dirname}`,
);
}

return config || previousConfig;
}, previousConfig);

if (config) {
debug("Found configuration %o from %o.", config.filepath, dirname);
}
return config;
}

export function* loadConfig(
name: string,
dirname: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile> {
const filepath = require.resolve(name, { paths: [dirname] });

const conf = yield* readConfig(filepath, envName, caller);
if (!conf) {
throw new ConfigError(
`Config file contains no configuration data`,
filepath,
);
}

debug("Loaded config %o from %o.", name, dirname);
return conf;
}

/**
* Read the given config file, returning the result. Returns null if no config was found, but will
* throw if there are parsing errors while loading a config.
*/
function readConfig(
filepath: string,
envName: string,
caller: CallerMetadata | undefined,
): Handler<ConfigFile | null> {
const ext = path.extname(filepath);
return ext === ".js" || ext === ".cjs" || ext === ".mjs"
? readConfigJS(filepath, { envName, caller })
: readConfigJSON5(filepath);
}

export function* resolveShowConfigPath(
dirname: string,
): Handler<string | null> {
Expand Down
54 changes: 27 additions & 27 deletions packages/babel-core/src/config/files/package.ts
Expand Up @@ -8,33 +8,6 @@ import ConfigError from "../../errors/config-error";

const PACKAGE_FILENAME = "package.json";

/**
* Find metadata about the package that this file is inside of. Resolution
* of Babel's config requires general package information to decide when to
* search for .babelrc files
*/
export function* findPackageData(filepath: string): Handler<FilePackageData> {
let pkg = null;
const directories = [];
let isPackage = true;

let dirname = path.dirname(filepath);
while (!pkg && path.basename(dirname) !== "node_modules") {
directories.push(dirname);

pkg = yield* readConfigPackage(path.join(dirname, PACKAGE_FILENAME));

const nextLoc = path.dirname(dirname);
if (dirname === nextLoc) {
isPackage = false;
break;
}
dirname = nextLoc;
}

return { filepath, directories, pkg, isPackage };
}

const readConfigPackage = makeStaticFileCache(
(filepath, content): ConfigFile => {
let options;
Expand Down Expand Up @@ -66,3 +39,30 @@ const readConfigPackage = makeStaticFileCache(
};
},
);

/**
* Find metadata about the package that this file is inside of. Resolution
* of Babel's config requires general package information to decide when to
* search for .babelrc files
*/
export function* findPackageData(filepath: string): Handler<FilePackageData> {
let pkg = null;
const directories = [];
let isPackage = true;

let dirname = path.dirname(filepath);
while (!pkg && path.basename(dirname) !== "node_modules") {
directories.push(dirname);

pkg = yield* readConfigPackage(path.join(dirname, PACKAGE_FILENAME));

const nextLoc = path.dirname(dirname);
if (dirname === nextLoc) {
isPackage = false;
break;
}
dirname = nextLoc;
}

return { filepath, directories, pkg, isPackage };
}
2 changes: 2 additions & 0 deletions packages/babel-core/src/config/files/plugins.ts
Expand Up @@ -28,10 +28,12 @@ const OTHER_PRESET_ORG_RE =
const OTHER_ORG_DEFAULT_RE = /^(@(?!babel$)[^/]+)$/;

export function* resolvePlugin(name: string, dirname: string): Handler<string> {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return yield* resolveStandardizedName("plugin", name, dirname);
}

export function* resolvePreset(name: string, dirname: string): Handler<string> {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return yield* resolveStandardizedName("preset", name, dirname);
}

Expand Down