Skip to content

Commit

Permalink
Resolve all the presets before instantiating plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Jun 7, 2020
1 parent 4108524 commit d213981
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 80 deletions.
131 changes: 54 additions & 77 deletions packages/babel-core/src/config/full.js
Expand Up @@ -66,61 +66,45 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig(
const { options, context } = result;

const optionDefaults = {};
const passes = [[]];
try {
const { plugins, presets } = options;

if (!plugins || !presets) {
throw new Error("Assertion failure - plugins and presets exist");
const { plugins, presets } = options;

if (!plugins || !presets) {
throw new Error("Assertion failure - plugins and presets exist");
}

const toDescriptor = item => {
const desc = getItemDescriptor(item);
if (!desc) {
throw new Error("Assertion failure - must be config item");
}

const ignored = yield* (function* recurseDescriptors(
config: {
plugins: Array<UnloadedDescriptor>,
presets: Array<UnloadedDescriptor>,
},
pass: Array<Plugin>,
) {
const plugins = [];
for (let i = 0; i < config.plugins.length; i++) {
const descriptor = config.plugins[i];
if (descriptor.options !== false) {
try {
plugins.push(yield* 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 desc;
};

const presetsDescriptors = presets.map(toDescriptor);
const initialPluginsDescriptors = plugins.map(toDescriptor);
const pluginDescriptorsByPass = [[]];
const passes = [];

try {
const ignored = yield* (function* recursePresetDescriptors(
rawPresets: Array<UnloadedDescriptor>,
pluginDescriptorsPass: Array<UnloadedDescriptor>,
) {
const presets = [];
for (let i = 0; i < config.presets.length; i++) {
const descriptor = config.presets[i];

for (let i = 0; i < rawPresets.length; i++) {
const descriptor = rawPresets[i];
if (descriptor.options !== false) {
try {
presets.push({
preset: yield* loadPresetDescriptor(descriptor, context),
pass: descriptor.ownPass ? [] : pass,
pass: descriptor.ownPass ? [] : pluginDescriptorsPass,
});
} catch (e) {
if (i > 0 && e.code === "BABEL_UNKNOWN_OPTION") {
checkNoUnwrappedItemOptionPairs(
config.presets[i - 1],
descriptor,
"preset",
i,
e,
);
if (e.code === "BABEL_UNKNOWN_OPTION") {
checkNoUnwrappedItemOptionPairs(rawPresets, i, "preset", e);
}
throw e;
}
Expand All @@ -131,57 +115,50 @@ export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig(
if (presets.length > 0) {
// The passes are created in the same order as the preset list, but are inserted before any
// existing additional passes.
passes.splice(
pluginDescriptorsByPass.splice(
1,
0,
...presets.map(o => o.pass).filter(p => p !== pass),
...presets.map(o => o.pass).filter(p => p !== pluginDescriptorsPass),
);

for (const { preset, pass } of presets) {
if (!preset) return true;

const ignored = yield* recurseDescriptors(
{
plugins: preset.plugins,
presets: preset.presets,
},
pass,
);
pass.unshift(...preset.plugins);

const ignored = yield* recursePresetDescriptors(preset.presets, pass);
if (ignored) return true;

preset.options.forEach(opts => {
mergeOptions(optionDefaults, opts);
});
}
}
})(presetsDescriptors, pluginDescriptorsByPass[0]);

// resolve plugins
if (plugins.length > 0) {
pass.unshift(...plugins);
}
})(
{
plugins: plugins.map(item => {
const desc = getItemDescriptor(item);
if (!desc) {
throw new Error("Assertion failure - must be config item");
}
if (ignored) return null;

return desc;
}),
presets: presets.map(item => {
const desc = getItemDescriptor(item);
if (!desc) {
throw new Error("Assertion failure - must be config item");
}
pluginDescriptorsByPass[0].unshift(...initialPluginsDescriptors);

return desc;
}),
},
passes[0],
);
for (const descs of pluginDescriptorsByPass) {
const pass = [];
passes.push(pass);

if (ignored) return null;
for (let i = 0; i < descs.length; i++) {
const descriptor = descs[i];
if (descriptor.options !== false) {
try {
pass.push(yield* loadPluginDescriptor(descriptor, context));
} catch (e) {
if (e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") {
// print special message for `plugins: ["@babel/foo", { foo: "option" }]`
checkNoUnwrappedItemOptionPairs(descs, i, "plugin", e);
}
throw e;
}
}
}
}
} catch (e) {
// There are a few case where thrown errors will try to annotate themselves multiple times, so
// to keep things simple we just bail out if re-wrapping the message.
Expand Down
10 changes: 7 additions & 3 deletions packages/babel-core/src/config/validation/options.js
Expand Up @@ -446,12 +446,16 @@ function assertOverridesList(loc: OptionPath, value: mixed): OverridesList {
}

export function checkNoUnwrappedItemOptionPairs(
lastItem: UnloadedDescriptor,
thisItem: UnloadedDescriptor,
type: "plugin" | "preset",
items: Array<UnloadedDescriptor>,
index: number,
type: "plugin" | "preset",
e: Error,
): void {
if (index === 0) return;

const lastItem = items[index - 1];
const thisItem = items[index];

if (
lastItem.file &&
lastItem.options === undefined &&
Expand Down

0 comments on commit d213981

Please sign in to comment.