Skip to content

Commit

Permalink
refactor: move to loadDescriptor catch clause
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Jan 9, 2020
1 parent f98bc26 commit 798043c
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 43 deletions.
2 changes: 0 additions & 2 deletions packages/babel-core/src/config/config-descriptors.js
Expand Up @@ -15,7 +15,6 @@ import type {
PluginList,
PluginItem,
} from "./validation/options";
import { assertNoUnwrappedItemOptionPairs } from "./validation/options";

// 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
Expand Down Expand Up @@ -230,7 +229,6 @@ function createDescriptors(
alias: string,
ownPass?: boolean,
): Array<UnloadedDescriptor> {
assertNoUnwrappedItemOptionPairs(items, type);
const descriptors = items.map((item, index) =>
createDescriptor(item, dirname, {
type,
Expand Down
69 changes: 53 additions & 16 deletions packages/babel-core/src/config/full.js
Expand Up @@ -13,7 +13,11 @@ import {
import type { UnloadedDescriptor } from "./config-descriptors";
import traverse from "@babel/traverse";
import { makeWeakCache, type CacheConfigurator } from "./caching";
import { validate, type CallerMetadata } from "./validation/options";
import {
validate,
type CallerMetadata,
checkNoUnwrappedItemOptionPairs,
} from "./validation/options";
import { validatePluginObject } from "./validation/plugins";
import makeAPI from "./helpers/config-api";

Expand Down Expand Up @@ -70,21 +74,54 @@ export default function loadFullConfig(
},
pass: Array<Plugin>,
) {
const plugins = config.plugins.reduce((acc, descriptor) => {
if (descriptor.options !== false) {
acc.push(loadPluginDescriptor(descriptor, context));
}
return acc;
}, []);
const presets = config.presets.reduce((acc, descriptor) => {
if (descriptor.options !== false) {
acc.push({
preset: loadPresetDescriptor(descriptor, context),
pass: descriptor.ownPass ? [] : pass,
});
}
return acc;
}, []);
const plugins = config.plugins.reduce(
(acc: Plugin[], descriptor: UnloadedDescriptor, i) => {
if (descriptor.options !== false) {
try {
acc.push(loadPluginDescriptor(descriptor, context));
} catch (e) {
// print special message for `plugins: ["@babel/foo", { foo: "option" }]`
if (i > 0 && e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") {
checkNoUnwrappedItemOptionPairs(
config.plugins[i - 1],
descriptor,
"plugin",
i,
e,
);
}
throw e;
}
}
return acc;
},
[],
);
const presets = config.presets.reduce(
(acc, descriptor: UnloadedDescriptor, i) => {
if (descriptor.options !== false) {
try {
acc.push({
preset: loadPresetDescriptor(descriptor, context),
pass: descriptor.ownPass ? [] : pass,
});
} catch (e) {
if (i > 0 && e.code === "BABEL_UNKNOWN_OPTION") {
checkNoUnwrappedItemOptionPairs(
config.presets[i - 1],
descriptor,
"preset",
i,
e,
);
}
throw e;
}
}
return acc;
},
[],
);

// resolve presets
if (presets.length > 0) {
Expand Down
46 changes: 24 additions & 22 deletions packages/babel-core/src/config/validation/options.js
Expand Up @@ -27,7 +27,7 @@ import {
type Validator,
type OptionPath,
} from "./option-assertions";
import { validatePluginObject } from "./plugins";
import type { UnloadedDescriptor } from "../config-descriptors";

const ROOT_VALIDATORS: ValidatorSet = {
cwd: (assertString: Validator<$PropertyType<ValidatedOptions, "cwd">>),
Expand Down Expand Up @@ -371,11 +371,14 @@ function throwUnknownError(loc: OptionPath) {
);
} else {
// eslint-disable-next-line max-len
const unknownOptErr = `Unknown option: ${msg(
loc,
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`;
const unknownOptErr = new ReferenceError(
`Unknown option: ${msg(
loc,
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`,
);
unknownOptErr.code = "BABEL_UNKNOWN_OPTION";

throw new ReferenceError(unknownOptErr);
throw unknownOptErr;
}
}

Expand Down Expand Up @@ -441,26 +444,25 @@ function assertOverridesList(loc: OptionPath, value: mixed): OverridesList {
return (arr: any);
}

export function assertNoUnwrappedItemOptionPairs(
items: PluginList,
export function checkNoUnwrappedItemOptionPairs(
lastItem: UnloadedDescriptor,
thisItem: UnloadedDescriptor,
type: "plugin" | "preset",
index: number,
e: Error,
): void {
if (
items.length === 2 &&
typeof items[0] === "string" &&
typeof items[1] === "object" &&
!Array.isArray(items[1])
lastItem.file &&
lastItem.options === undefined &&
typeof thisItem.value === "object"
) {
try {
type === "preset"
? validate(type, items[1])
: validatePluginObject(items[1]);
} catch (e) {
throw new Error(
`.${type}[1] is not a valid ${type}. Maybe you meant to use\n` +
`"${type}": [\n ["${items[0]}", ${JSON.stringify(items[1])}]\n]\n` +
`To be a valid ${type}, its name and options should be wrapped in a pair of brackets`,
);
}
e.message +=
`\n- Maybe you meant to use\n` +
`"${type}": [\n ["${lastItem.file.request}", ${JSON.stringify(
thisItem.value,
undefined,
2,
)}]\n]\n` +
`To be a valid ${type}, its name and options should be wrapped in a pair of brackets`;
}
}
8 changes: 7 additions & 1 deletion packages/babel-core/src/config/validation/plugins.js
Expand Up @@ -97,7 +97,13 @@ export function validatePluginObject(obj: {}): PluginObject {
};

if (validator) validator(optLoc, obj[key]);
else throw new Error(`.${key} is not a valid Plugin property`);
else {
const invalidPluginPropertyError = new Error(
`.${key} is not a valid Plugin property`,
);
invalidPluginPropertyError.code = "BABEL_UNKNOWN_PLUGIN_PROPERTY";
throw invalidPluginPropertyError;
}
});

return (obj: any);
Expand Down
6 changes: 4 additions & 2 deletions packages/babel-core/test/__snapshots__/option-manager.js.snap
@@ -1,7 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`option-manager config plugin/preset flattening and overriding should throw when an option is provided as a plugin 1`] = `
"[BABEL] unknown: .plugin[1] is not a valid plugin. Maybe you meant to use
"[BABEL] unknown: .useSpread is not a valid Plugin property
- Maybe you meant to use
\\"plugin\\": [
[\\"./fixtures/option-manager/babel-plugin-foo\\", {
\\"useSpread\\": true
Expand All @@ -11,7 +12,8 @@ To be a valid plugin, its name and options should be wrapped in a pair of bracke
`;

exports[`option-manager config plugin/preset flattening and overriding should throw when an option is provided as a preset 1`] = `
"[BABEL] unknown: .preset[1] is not a valid preset. Maybe you meant to use
"[BABEL] unknown: Unknown option: .useBuiltIns. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.
- Maybe you meant to use
\\"preset\\": [
[\\"./fixtures/option-manager/babel-preset-bar\\", {
\\"useBuiltIns\\": \\"entry\\"
Expand Down

0 comments on commit 798043c

Please sign in to comment.