diff --git a/.gitignore b/.gitignore index 9023624..32c7647 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store .eslintcache .nyc_output +.pnpm-debug.log coverage coverage.lcov node_modules diff --git a/README.md b/README.md index 0755bec..59f7e0d 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,15 @@ This plugin supports the following hooks via the `getCompilerHooks` export; `aft Returns: `{ afterEmit: SyncWaterfallHook, beforeEmit: SyncWaterfallHook }` +### `assetHookStage` + +Type: `Number` +Default: `Infinity` + +If you need to consume the output of this plugin in another plugin, it can be useful to adjust the stage at which the manifest is generated. Pass a new stage to `assetHookStage` to change when the manifest is generated. See the [docs on `processAssets`](https://webpack.js.org/api/compilation-hooks/#list-of-asset-processing-stages) for more detail. + +Note: any files added to the compilation after the stage specified will not be included in the manifest. + #### Usage ```js diff --git a/src/index.ts b/src/index.ts index e4dfc4a..37463fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ export type Manifest = Record; export interface InternalOptions { [key: string]: any; + assetHookStage: number; basePath: string; fileName: string; filter: (file: FileDescriptor) => Boolean; @@ -37,6 +38,7 @@ export interface InternalOptions { export type ManifestPluginOptions = Partial; const defaults = { + assetHookStage: Infinity, basePath: '', fileName: 'manifest.json', filter: null, @@ -84,7 +86,7 @@ class WebpackManifestPlugin implements WebpackPluginInstance { const normalModuleLoader = normalModuleLoaderHook.bind(this, { moduleAssets }); const hookOptions = { name: 'WebpackManifestPlugin', - stage: Infinity + stage: this.options.assetHookStage }; compiler.hooks.compilation.tap(hookOptions, (compilation) => { diff --git a/test/unit/options.js b/test/unit/options.js index 9c09069..1d41916 100644 --- a/test/unit/options.js +++ b/test/unit/options.js @@ -5,6 +5,8 @@ const CopyPlugin = require('copy-webpack-plugin'); const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin'); const del = require('del'); +const webpack = require('webpack'); + const { compile } = require('../helpers/unit'); const outputPath = join(__dirname, '../output/options'); @@ -141,3 +143,55 @@ test('useLegacyEmit', async (t) => { t.snapshot(manifest); }); + +test('assetHookStage', async (t) => { + const FIRST_PROCESS_ASSETS_STAGE = 0; + const SECOND_PROCESS_ASSETS_STAGE = 1; + let assets; + + class LastStagePlugin { + /* eslint-disable class-methods-use-this */ + apply(compiler) { + const isWebpack4 = webpack.version.startsWith('4'); + + const callback = (compilation) => { + // We'll check for our manifest being included in the assets of this invocation + assets = Object.keys(isWebpack4 ? compilation.assets : compilation); + }; + + const hookOptions = { + name: 'LastStagePlugin', + // Make sure our plugin is scheduled to run after the manifest plugin + stage: SECOND_PROCESS_ASSETS_STAGE + }; + + if (isWebpack4) { + compiler.hooks.emit.tap(hookOptions, callback); + } else { + compiler.hooks.thisCompilation.tap(hookOptions, (compilation) => { + compilation.hooks.processAssets.tap(hookOptions, callback); + }); + } + } + /* eslint-enable class-methods-use-this */ + } + + const config = { + context: __dirname, + entry: { + main: '../fixtures/file.js' + }, + output: { + filename: '[name].js', + path: join(outputPath, 'assetHookStage') + }, + plugins: [new LastStagePlugin()] + }; + + // Ensure we register the manifest plugin to run first. + const { manifest } = await compile(config, t, { assetHookStage: FIRST_PROCESS_ASSETS_STAGE }); + + t.snapshot(manifest); + const laterPluginHasManifest = assets.includes('manifest.json'); + t.is(laterPluginHasManifest, true); +}); diff --git a/test/unit/snapshots/options.js.md b/test/unit/snapshots/options.js.md index 6bac1d8..06b3362 100644 --- a/test/unit/snapshots/options.js.md +++ b/test/unit/snapshots/options.js.md @@ -65,3 +65,19 @@ Generated by [AVA](https://avajs.dev). 'main.js': 'main.js', 'main.json': 'main.asset.json', } + +## assetHookStage + +> Snapshot 1 + + { + 'main.js': 'main.js', + } + +## assetHookStage + +> Snapshot 1 + + { + 'main.js': 'main.js', + } diff --git a/test/unit/snapshots/options.js.snap b/test/unit/snapshots/options.js.snap index e7cd975..80093ef 100644 Binary files a/test/unit/snapshots/options.js.snap and b/test/unit/snapshots/options.js.snap differ