Merge pull request #6435 from loganfsmyth/always-options

Always pass an options object to presets and plugins.
This commit is contained in:
Logan Smyth 2017-10-05 22:26:01 -04:00 committed by GitHub
commit 841e8e9c80
2 changed files with 61 additions and 44 deletions

View File

@ -214,7 +214,15 @@ class OptionManager {
type BasicDescriptor = { type BasicDescriptor = {
value: {} | Function, value: {} | Function,
options: ?{}, options: {} | void,
dirname: string,
alias: string,
loc: string,
};
type LoadedDescriptor = {
value: {},
options: {},
dirname: string, dirname: string,
alias: string, alias: string,
loc: string, loc: string,
@ -282,38 +290,41 @@ const loadConfig = makeWeakCache((config): {
/** /**
* Load a generic plugin/preset from the given descriptor loaded from the config object. * Load a generic plugin/preset from the given descriptor loaded from the config object.
*/ */
const loadDescriptor = makeWeakCache((descriptor, cache) => { const loadDescriptor = makeWeakCache(
if (typeof descriptor.value !== "function") { (descriptor: BasicDescriptor, cache): LoadedDescriptor => {
return { value: descriptor.value, descriptor }; const { value, options = {}, dirname, alias, loc } = descriptor;
}
const { value, options } = descriptor;
let item = value;
if (typeof value === "function") {
const api = Object.assign(Object.create(context), { const api = Object.assign(Object.create(context), {
cache, cache,
env: () => cache.using(() => getEnv()), env: () => cache.using(() => getEnv()),
}); });
let item;
try { try {
item = value(api, options, { dirname: descriptor.dirname }); item = value(api, options, { dirname: descriptor.dirname });
} catch (e) { } catch (e) {
if (descriptor.alias) { if (descriptor.alias) {
e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`; e.message += ` (While processing: ${JSON.stringify(
descriptor.alias,
)})`;
} }
throw e; throw e;
} }
}
if (!item || typeof item !== "object") { if (!item || typeof item !== "object") {
throw new Error("Plugin/Preset did not return an object."); throw new Error("Plugin/Preset did not return an object.");
} }
return { value: item, descriptor }; return { value: item, options, descriptor, dirname, alias, loc };
}); },
);
/** /**
* Instantiate a plugin for the given descriptor, returning the plugin/options pair. * Instantiate a plugin for the given descriptor, returning the plugin/options pair.
*/ */
function loadPluginDescriptor(descriptor: BasicDescriptor) { function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin {
if (descriptor.value instanceof Plugin) { if (descriptor.value instanceof Plugin) {
if (descriptor.options) { if (descriptor.options) {
throw new Error( throw new Error(
@ -328,11 +339,14 @@ function loadPluginDescriptor(descriptor: BasicDescriptor) {
} }
const instantiatePlugin = makeWeakCache( const instantiatePlugin = makeWeakCache(
({ value: pluginObj, descriptor }, cache) => { (
{ value: pluginObj, options, dirname, alias, loc }: LoadedDescriptor,
cache,
): Plugin => {
Object.keys(pluginObj).forEach(key => { Object.keys(pluginObj).forEach(key => {
if (!ALLOWED_PLUGIN_KEYS.has(key)) { if (!ALLOWED_PLUGIN_KEYS.has(key)) {
throw new Error( throw new Error(
`Plugin ${descriptor.alias} provided an invalid property of ${key}`, `Plugin ${alias} provided an invalid property of ${key}`,
); );
} }
}); });
@ -356,11 +370,11 @@ const instantiatePlugin = makeWeakCache(
let inherits; let inherits;
if (plugin.inherits) { if (plugin.inherits) {
inheritsDescriptor = { inheritsDescriptor = {
alias: `${descriptor.loc}$inherits`, alias: `${loc}$inherits`,
loc: descriptor.loc, loc,
value: plugin.inherits, value: plugin.inherits,
options: descriptor.options, options,
dirname: descriptor.dirname, dirname,
}; };
// If the inherited plugin changes, reinstantiate this plugin. // If the inherited plugin changes, reinstantiate this plugin.
@ -380,7 +394,7 @@ const instantiatePlugin = makeWeakCache(
]); ]);
} }
return new Plugin(plugin, descriptor.options, descriptor.alias); return new Plugin(plugin, options, alias);
}, },
); );
@ -391,15 +405,17 @@ const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => {
return instantiatePreset(loadDescriptor(descriptor)); return instantiatePreset(loadDescriptor(descriptor));
}; };
const instantiatePreset = makeWeakCache(({ value, descriptor }) => { const instantiatePreset = makeWeakCache(
({ value, dirname, alias, loc }: LoadedDescriptor): MergeOptions => {
return { return {
type: "preset", type: "preset",
options: value, options: value,
alias: descriptor.alias, alias,
loc: descriptor.loc, loc,
dirname: descriptor.dirname, dirname,
}; };
}); },
);
/** /**
* Validate and return the options object for the config. * Validate and return the options object for the config.
@ -504,7 +520,7 @@ function normalizePair(
): { ): {
filepath: string | null, filepath: string | null,
value: {} | Function, value: {} | Function,
options: ?{}, options: {} | void,
} { } {
let options; let options;
let value = pair; let value = pair;
@ -546,6 +562,7 @@ function normalizePair(
"Plugin/Preset options must be an object, null, or undefined", "Plugin/Preset options must be an object, null, or undefined",
); );
} }
options = options || undefined;
return { filepath, value, options }; return { filepath, value, options };
} }

View File

@ -7,9 +7,9 @@ export default class Plugin {
pre: ?Function; pre: ?Function;
visitor: ?{}; visitor: ?{};
options: {} | void; options: {};
constructor(plugin: {}, options: ?{}, key?: string) { constructor(plugin: {}, options: {}, key?: string) {
if (plugin.name != null && typeof plugin.name !== "string") { if (plugin.name != null && typeof plugin.name !== "string") {
throw new Error("Plugin .name must be a string, null, or undefined"); throw new Error("Plugin .name must be a string, null, or undefined");
} }
@ -37,6 +37,6 @@ export default class Plugin {
this.post = plugin.post; this.post = plugin.post;
this.pre = plugin.pre; this.pre = plugin.pre;
this.visitor = plugin.visitor; this.visitor = plugin.visitor;
this.options = options || undefined; this.options = options;
} }
} }