diff --git a/src/rollup/index.ts b/src/rollup/index.ts index dc47b79ba88..6f9e6365d5d 100644 --- a/src/rollup/index.ts +++ b/src/rollup/index.ts @@ -251,7 +251,7 @@ export default async function rollup(rawInputOptions: GenericConfigObject): Prom let outputBundle; try { - await outputPluginDriver.hookParallel('renderStart', []); + await outputPluginDriver.hookParallel('renderStart', [outputOptions, inputOptions]); const addons = await createAddons(outputOptions, outputPluginDriver); for (const chunk of chunks) { if (!inputOptions.preserveModules) chunk.generateInternalExports(outputOptions); @@ -472,7 +472,6 @@ function normalizeOutputOptions( const mergedOutputOptions = mergedOptions.outputOptions[0]; const outputOptionsReducer = (outputOptions: OutputOptions, result: OutputOptions) => result || outputOptions; - // TODO Lukas add inputOptions to hook const outputOptions = outputPluginDriver.hookReduceArg0Sync( 'outputOptions', [mergedOutputOptions], diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 32c3e5e237c..343491308f0 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -332,17 +332,14 @@ interface OnWriteOptions extends OutputOptions { bundle: RollupBuild; } -export interface PluginHooks { +interface OutputPluginHooks { augmentChunkHash: (this: PluginContext, chunk: PreRenderedChunk) => string | void; - buildEnd: (this: PluginContext, err?: Error) => Promise | void; - buildStart: (this: PluginContext, options: InputOptions) => Promise | void; generateBundle: ( this: PluginContext, options: OutputOptions, bundle: OutputBundle, isWrite: boolean ) => void | Promise; - load: LoadHook; /** @deprecated Use `generateBundle` instead */ ongenerate: ( this: PluginContext, @@ -355,33 +352,50 @@ export interface PluginHooks { options: OnWriteOptions, chunk: OutputChunk ) => void | Promise; - options: (this: MinimalPluginContext, options: InputOptions) => InputOptions | null | undefined; outputOptions: (this: PluginContext, options: OutputOptions) => OutputOptions | null | undefined; renderChunk: RenderChunkHook; renderError: (this: PluginContext, err?: Error) => Promise | void; - renderStart: (this: PluginContext) => Promise | void; + renderStart: ( + this: PluginContext, + outputOptions: OutputOptions, + inputOptions: InputOptions + ) => Promise | void; /** @deprecated Use `resolveFileUrl` instead */ resolveAssetUrl: ResolveAssetUrlHook; resolveDynamicImport: ResolveDynamicImportHook; resolveFileUrl: ResolveFileUrlHook; - resolveId: ResolveIdHook; - resolveImportMeta: ResolveImportMetaHook; - transform: TransformHook; /** @deprecated Use `renderChunk` instead */ transformBundle: TransformChunkHook; /** @deprecated Use `renderChunk` instead */ transformChunk: TransformChunkHook; - watchChange: (id: string) => void; writeBundle: (this: PluginContext, bundle: OutputBundle) => void | Promise; } -export interface Plugin extends Partial { - banner?: AddonHook; - cacheKey?: string; - footer?: AddonHook; - intro?: AddonHook; +export interface PluginHooks extends OutputPluginHooks { + buildEnd: (this: PluginContext, err?: Error) => Promise | void; + buildStart: (this: PluginContext, options: InputOptions) => Promise | void; + load: LoadHook; + options: (this: MinimalPluginContext, options: InputOptions) => InputOptions | null | undefined; + resolveId: ResolveIdHook; + resolveImportMeta: ResolveImportMetaHook; + transform: TransformHook; + watchChange: (id: string) => void; +} + +interface OutputPluginValueHooks { + banner: AddonHook; + cacheKey: string; + footer: AddonHook; + intro: AddonHook; + outro: AddonHook; +} + +export interface Plugin extends Partial, Partial { + name: string; +} + +export interface OutputPlugin extends Partial, Partial { name: string; - outro?: AddonHook; } export interface TreeshakingOptions { @@ -475,6 +489,7 @@ export interface OutputOptions { noConflict?: boolean; outro?: string | (() => string | Promise); paths?: OptionsPaths; + plugins?: OutputPlugin[]; preferConst?: boolean; sourcemap?: boolean | 'inline' | 'hidden'; sourcemapExcludeSources?: boolean; @@ -553,6 +568,7 @@ export interface RollupBuild { } export interface RollupOptions extends InputOptions { + // This is included for compatibility with config files but ignored by rollup.rollup output?: OutputOptions | OutputOptions[]; } diff --git a/test/function/samples/options-in-renderstart/_config.js b/test/function/samples/options-in-renderstart/_config.js new file mode 100644 index 00000000000..3129a8b36ea --- /dev/null +++ b/test/function/samples/options-in-renderstart/_config.js @@ -0,0 +1,33 @@ +const assert = require('assert'); +const checkedOptions = []; + +module.exports = { + description: 'makes input and output options available in renderStart', + options: { + context: 'global', + plugins: { + name: 'input-plugin', + renderStart(outputOptions, inputOptions) { + checkedOptions.push('input-plugin', outputOptions.format, inputOptions.context); + } + }, + output: { + plugins: { + name: 'output-plugin', + renderStart(outputOptions, inputOptions) { + checkedOptions.push('output-plugin', outputOptions.format, inputOptions.context); + } + } + } + }, + exports: () => { + assert.deepStrictEqual(checkedOptions, [ + 'output-plugin', + 'cjs', + 'global', + 'input-plugin', + 'cjs', + 'global' + ]); + } +}; diff --git a/test/function/samples/options-in-renderstart/main.js b/test/function/samples/options-in-renderstart/main.js new file mode 100644 index 00000000000..5dff5e2ec72 --- /dev/null +++ b/test/function/samples/options-in-renderstart/main.js @@ -0,0 +1 @@ +assert.ok(this);