Add dependency cycle handing for plugins and config files.
This commit is contained in:
parent
beff7809ea
commit
2846e06db1
@ -99,14 +99,31 @@ function readConfig(filepath) {
|
||||
: readConfigFile(filepath);
|
||||
}
|
||||
|
||||
const LOADING_CONFIGS = new Set();
|
||||
const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
if (!fs.existsSync(filepath)) {
|
||||
cache.forever();
|
||||
return null;
|
||||
}
|
||||
|
||||
// The `require()` call below can make this code reentrant if a require hook like babel-register has been
|
||||
// loaded into the system. That would cause Babel to attempt to compile the `.babelrc.js` file as it loads
|
||||
// below. To cover this case, we auto-ignore re-entrant config processing.
|
||||
if (LOADING_CONFIGS.has(filepath)) {
|
||||
cache.never();
|
||||
|
||||
debug("Auto-ignoring usage of config %o.", filepath);
|
||||
return {
|
||||
filepath,
|
||||
dirname: path.dirname(filepath),
|
||||
options: {},
|
||||
};
|
||||
}
|
||||
|
||||
let options;
|
||||
try {
|
||||
LOADING_CONFIGS.add(filepath);
|
||||
|
||||
// $FlowIssue
|
||||
const configModule = (require(filepath): mixed);
|
||||
options =
|
||||
@ -116,6 +133,8 @@ const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
||||
throw err;
|
||||
} finally {
|
||||
LOADING_CONFIGS.delete(filepath);
|
||||
}
|
||||
|
||||
if (typeof options === "function") {
|
||||
|
||||
@ -35,7 +35,7 @@ export function loadPlugin(
|
||||
throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
||||
}
|
||||
|
||||
const value = requireModule(filepath);
|
||||
const value = requireModule("plugin", filepath);
|
||||
debug("Loaded plugin %o from %o.", name, dirname);
|
||||
|
||||
return { filepath, value };
|
||||
@ -50,7 +50,7 @@ export function loadPreset(
|
||||
throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
||||
}
|
||||
|
||||
const value = requireModule(filepath);
|
||||
const value = requireModule("preset", filepath);
|
||||
|
||||
debug("Loaded preset %o from %o.", name, dirname);
|
||||
|
||||
@ -63,7 +63,7 @@ export function loadParser(
|
||||
): { filepath: string, value: Function } {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
const mod = requireModule("parser", filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(
|
||||
@ -91,7 +91,7 @@ export function loadGenerator(
|
||||
): { filepath: string, value: Function } {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
const mod = requireModule("generator", filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(
|
||||
@ -195,7 +195,20 @@ function resolveStandardizedName(
|
||||
}
|
||||
}
|
||||
|
||||
function requireModule(name: string): mixed {
|
||||
// $FlowIssue
|
||||
return require(name);
|
||||
const LOADING_MODULES = new Set();
|
||||
function requireModule(type: string, name: string): mixed {
|
||||
if (LOADING_MODULES.has(name)) {
|
||||
throw new Error(
|
||||
// eslint-disable-next-line max-len
|
||||
`Reentrant ${type} detected trying to load "${name}". This module is not ignored and is trying to load itself while compiling itself, leading to a dependency cycle. We recommend adding it to your "ignore" list in your babelrc, or to a .babelignore.`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
LOADING_MODULES.add(name);
|
||||
// $FlowIssue
|
||||
return require(name);
|
||||
} finally {
|
||||
LOADING_MODULES.delete(name);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user