From 1fa937468fd6033f8d8ec10e800d671fc1d01f7e Mon Sep 17 00:00:00 2001 From: Tomer Aberbach Date: Sun, 5 Jul 2020 01:18:23 -0400 Subject: [PATCH] feat: make options hook async (#3660) --- docs/05-plugin-development.md | 2 +- src/rollup/rollup.ts | 15 +++++---- .../samples/options-async-hook/_config.js | 33 +++++++++++++++++++ .../samples/options-async-hook/file.txt | 1 + .../samples/options-async-hook/unused.js | 1 + .../samples/options-async-hook/used.js | 1 + 6 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 test/function/samples/options-async-hook/_config.js create mode 100644 test/function/samples/options-async-hook/file.txt create mode 100644 test/function/samples/options-async-hook/unused.js create mode 100644 test/function/samples/options-async-hook/used.js diff --git a/docs/05-plugin-development.md b/docs/05-plugin-development.md index 4cf9ec6e0ff..2610c7f119c 100644 --- a/docs/05-plugin-development.md +++ b/docs/05-plugin-development.md @@ -124,7 +124,7 @@ You can use [`this.getModuleInfo`](guide/en/#thisgetmoduleinfomoduleid-string--m #### `options` Type: `(options: InputOptions) => InputOptions | null`
-Kind: `sync, sequential`
+Kind: `async, sequential`
Previous Hook: This is the first hook of the build phase.
Next Hook: [`buildStart`](guide/en/#buildstart) diff --git a/src/rollup/rollup.ts b/src/rollup/rollup.ts index fa732647c43..7224d24a389 100644 --- a/src/rollup/rollup.ts +++ b/src/rollup/rollup.ts @@ -32,7 +32,7 @@ export async function rollupInternal( rawInputOptions: GenericConfigObject, watcher: RollupWatcher | null ): Promise { - const { options: inputOptions, unsetOptions: unsetInputOptions } = getInputOptions( + const { options: inputOptions, unsetOptions: unsetInputOptions } = await getInputOptions( rawInputOptions, watcher !== null ); @@ -89,28 +89,31 @@ export async function rollupInternal( return result; } -function getInputOptions( +async function getInputOptions( rawInputOptions: GenericConfigObject, watchMode: boolean -): { options: NormalizedInputOptions; unsetOptions: Set } { +): Promise<{ options: NormalizedInputOptions; unsetOptions: Set }> { 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, + plugin: Plugin + ): Promise => { if (plugin.options) return ( (plugin.options.call( { meta: { rollupVersion, watchMode } }, - inputOptions + await inputOptions ) as GenericConfigObject) || inputOptions ); diff --git a/test/function/samples/options-async-hook/_config.js b/test/function/samples/options-async-hook/_config.js new file mode 100644 index 00000000000..07426baa8ed --- /dev/null +++ b/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' }); + } + } + ] + } +}; diff --git a/test/function/samples/options-async-hook/file.txt b/test/function/samples/options-async-hook/file.txt new file mode 100644 index 00000000000..b2c475fedd4 --- /dev/null +++ b/test/function/samples/options-async-hook/file.txt @@ -0,0 +1 @@ +unused diff --git a/test/function/samples/options-async-hook/unused.js b/test/function/samples/options-async-hook/unused.js new file mode 100644 index 00000000000..a9244a453fb --- /dev/null +++ b/test/function/samples/options-async-hook/unused.js @@ -0,0 +1 @@ +throw new Error('Not executed'); diff --git a/test/function/samples/options-async-hook/used.js b/test/function/samples/options-async-hook/used.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/test/function/samples/options-async-hook/used.js @@ -0,0 +1 @@ +export default 42;