Skip to content

Commit

Permalink
feat: make options hook async (#3660)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomerAberbach committed Jul 5, 2020
1 parent 0d5a017 commit 1fa9374
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/05-plugin-development.md
Expand Up @@ -124,7 +124,7 @@ You can use [`this.getModuleInfo`](guide/en/#thisgetmoduleinfomoduleid-string--m

#### `options`
Type: `(options: InputOptions) => InputOptions | null`<br>
Kind: `sync, sequential`<br>
Kind: `async, sequential`<br>
Previous Hook: This is the first hook of the build phase.<br>
Next Hook: [`buildStart`](guide/en/#buildstart)

Expand Down
15 changes: 9 additions & 6 deletions src/rollup/rollup.ts
Expand Up @@ -32,7 +32,7 @@ export async function rollupInternal(
rawInputOptions: GenericConfigObject,
watcher: RollupWatcher | null
): Promise<RollupBuild> {
const { options: inputOptions, unsetOptions: unsetInputOptions } = getInputOptions(
const { options: inputOptions, unsetOptions: unsetInputOptions } = await getInputOptions(
rawInputOptions,
watcher !== null
);
Expand Down Expand Up @@ -89,28 +89,31 @@ export async function rollupInternal(
return result;
}

function getInputOptions(
async function getInputOptions(
rawInputOptions: GenericConfigObject,
watchMode: boolean
): { options: NormalizedInputOptions; unsetOptions: Set<string> } {
): Promise<{ options: NormalizedInputOptions; unsetOptions: Set<string> }> {
if (!rawInputOptions) {
throw new Error('You must supply an options object to rollup');
}
const rawPlugins = ensureArray(rawInputOptions.plugins) as Plugin[];
const { options, unsetOptions } = normalizeInputOptions(
rawPlugins.reduce(applyOptionHook(watchMode), rawInputOptions)
await rawPlugins.reduce(applyOptionHook(watchMode), Promise.resolve(rawInputOptions))
);
normalizePlugins(options.plugins, ANONYMOUS_PLUGIN_PREFIX);
return { options, unsetOptions };
}

function applyOptionHook(watchMode: boolean) {
return (inputOptions: GenericConfigObject, plugin: Plugin): GenericConfigObject => {
return async (
inputOptions: Promise<GenericConfigObject>,
plugin: Plugin
): Promise<GenericConfigObject> => {
if (plugin.options)
return (
(plugin.options.call(
{ meta: { rollupVersion, watchMode } },
inputOptions
await inputOptions
) as GenericConfigObject) || inputOptions
);

Expand Down
33 changes: 33 additions & 0 deletions test/function/samples/options-async-hook/_config.js
@@ -0,0 +1,33 @@
const assert = require('assert');
const { promises: fs } = require('fs');

module.exports = {
description: 'resolves promises between sequential options hooks',
options: {
input: 'super-unused',
treeshake: false,
plugins: [
{
name: 'test-plugin-1',
async options(options) {
assert.deepStrictEqual(JSON.parse(JSON.stringify(options)), {
input: 'super-unused',
plugins: [{ name: 'test-plugin-1' }, { name: 'test-plugin-2' }],
strictDeprecations: true,
treeshake: false
});
return Object.assign({}, options, {
input: (await fs.readFile('file.txt', 'utf8')).trim()
});
}
},
{
name: 'test-plugin-2',
options(options) {
assert.strictEqual(options.input, 'unused');
return Object.assign({}, options, { input: 'used' });
}
}
]
}
};
1 change: 1 addition & 0 deletions test/function/samples/options-async-hook/file.txt
@@ -0,0 +1 @@
unused
1 change: 1 addition & 0 deletions test/function/samples/options-async-hook/unused.js
@@ -0,0 +1 @@
throw new Error('Not executed');
1 change: 1 addition & 0 deletions test/function/samples/options-async-hook/used.js
@@ -0,0 +1 @@
export default 42;

0 comments on commit 1fa9374

Please sign in to comment.