Skip to content

Commit 4072bfa

Browse files
feat: Added ability to adjust plugin processAssets hook stage (#262) (#263)
* feat: Added ability to adjust plugin processAssets hook stage (#262) * test: update snapshots Co-authored-by: shellscape <andrew@shellscape.org>
1 parent 8866d0f commit 4072bfa

File tree

6 files changed

+83
-1
lines changed

6 files changed

+83
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.DS_Store
22
.eslintcache
33
.nyc_output
4+
.pnpm-debug.log
45
coverage
56
coverage.lcov
67
node_modules

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ This plugin supports the following hooks via the `getCompilerHooks` export; `aft
230230

231231
Returns: `{ afterEmit: SyncWaterfallHook, beforeEmit: SyncWaterfallHook }`
232232

233+
### `assetHookStage`
234+
235+
Type: `Number`
236+
Default: `Infinity`
237+
238+
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.
239+
240+
Note: any files added to the compilation after the stage specified will not be included in the manifest.
241+
233242
#### Usage
234243

235244
```js

src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type Manifest = Record<string, any>;
1414

1515
export interface InternalOptions {
1616
[key: string]: any;
17+
assetHookStage: number;
1718
basePath: string;
1819
fileName: string;
1920
filter: (file: FileDescriptor) => Boolean;
@@ -37,6 +38,7 @@ export interface InternalOptions {
3738
export type ManifestPluginOptions = Partial<InternalOptions>;
3839

3940
const defaults = {
41+
assetHookStage: Infinity,
4042
basePath: '',
4143
fileName: 'manifest.json',
4244
filter: null,
@@ -84,7 +86,7 @@ class WebpackManifestPlugin implements WebpackPluginInstance {
8486
const normalModuleLoader = normalModuleLoaderHook.bind(this, { moduleAssets });
8587
const hookOptions = {
8688
name: 'WebpackManifestPlugin',
87-
stage: Infinity
89+
stage: this.options.assetHookStage
8890
};
8991

9092
compiler.hooks.compilation.tap(hookOptions, (compilation) => {

test/unit/options.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const CopyPlugin = require('copy-webpack-plugin');
55
const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin');
66
const del = require('del');
77

8+
const webpack = require('webpack');
9+
810
const { compile } = require('../helpers/unit');
911

1012
const outputPath = join(__dirname, '../output/options');
@@ -141,3 +143,55 @@ test('useLegacyEmit', async (t) => {
141143

142144
t.snapshot(manifest);
143145
});
146+
147+
test('assetHookStage', async (t) => {
148+
const FIRST_PROCESS_ASSETS_STAGE = 0;
149+
const SECOND_PROCESS_ASSETS_STAGE = 1;
150+
let assets;
151+
152+
class LastStagePlugin {
153+
/* eslint-disable class-methods-use-this */
154+
apply(compiler) {
155+
const isWebpack4 = webpack.version.startsWith('4');
156+
157+
const callback = (compilation) => {
158+
// We'll check for our manifest being included in the assets of this invocation
159+
assets = Object.keys(isWebpack4 ? compilation.assets : compilation);
160+
};
161+
162+
const hookOptions = {
163+
name: 'LastStagePlugin',
164+
// Make sure our plugin is scheduled to run after the manifest plugin
165+
stage: SECOND_PROCESS_ASSETS_STAGE
166+
};
167+
168+
if (isWebpack4) {
169+
compiler.hooks.emit.tap(hookOptions, callback);
170+
} else {
171+
compiler.hooks.thisCompilation.tap(hookOptions, (compilation) => {
172+
compilation.hooks.processAssets.tap(hookOptions, callback);
173+
});
174+
}
175+
}
176+
/* eslint-enable class-methods-use-this */
177+
}
178+
179+
const config = {
180+
context: __dirname,
181+
entry: {
182+
main: '../fixtures/file.js'
183+
},
184+
output: {
185+
filename: '[name].js',
186+
path: join(outputPath, 'assetHookStage')
187+
},
188+
plugins: [new LastStagePlugin()]
189+
};
190+
191+
// Ensure we register the manifest plugin to run first.
192+
const { manifest } = await compile(config, t, { assetHookStage: FIRST_PROCESS_ASSETS_STAGE });
193+
194+
t.snapshot(manifest);
195+
const laterPluginHasManifest = assets.includes('manifest.json');
196+
t.is(laterPluginHasManifest, true);
197+
});

test/unit/snapshots/options.js.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,19 @@ Generated by [AVA](https://avajs.dev).
6565
'main.js': 'main.js',
6666
'main.json': 'main.asset.json',
6767
}
68+
69+
## assetHookStage
70+
71+
> Snapshot 1
72+
73+
{
74+
'main.js': 'main.js',
75+
}
76+
77+
## assetHookStage
78+
79+
> Snapshot 1
80+
81+
{
82+
'main.js': 'main.js',
83+
}
29 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)