-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
docs(plugin): add watch mode plugin example with modifiedFiles and fileDependencies #8125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
c8cb8e2
2426064
3eda621
b895e37
3427ea4
e23fa02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -300,6 +300,82 @@ T> We are using synchronous `tap()` method to tap into the `processAssets` hook | |
|
|
||
| T> The [`processAssets`](/api/compilation-hooks/#processassets) hook also supports the `additionalAssets` property, that allows your plugin to intercept not only assets that were added by other plugins prior to the execution of the specified stage, but also for assets that were added on a later stages. This allows to intercept absolutely all the assets which are part of the compilation. However, in our example we are fine with using the `SUMMARIZE` stage to capture all the assets generated on previous stages (this should account for all assets in general case). | ||
|
|
||
| ## Watching for file changes | ||
|
|
||
| When webpack runs in watch mode (`webpack --watch` or `devServer`), | ||
| Webpack creates a new compilation for each rebuild triggered by file changes. | ||
|
|
||
| The `compiler.modifiedFiles` Set lets your plugin know **which specific | ||
| files triggered the rebuild**, so you can skip expensive work for unrelated files. | ||
|
|
||
| This is useful for plugins that need to react only to specific file changes | ||
| (e.g., regenerating assets, reprocessing templates, or invalidating caches). | ||
|
|
||
| ```js | ||
| class WatchNotifierPlugin { | ||
| apply(compiler) { | ||
| compiler.hooks.watchRun.tap("WatchNotifierPlugin", (compiler) => { | ||
| if (compiler.modifiedFiles) { | ||
| const changedFiles = [...compiler.modifiedFiles] | ||
| .map((file) => ` • ${file}`) | ||
| .join("\n"); | ||
|
|
||
| console.log(`\nFiles changed:\n${changedFiles}`); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| module.exports = WatchNotifierPlugin; | ||
| ``` | ||
|
|
||
| > **Note**: | ||
| > | ||
| > - `compiler.modifiedFiles` is a `Set`, not an array | ||
| > - It is `undefined` on the first (cold) build | ||
| > - It is only populated during watch rebuilds | ||
|
|
||
| ### Adding custom file dependencies | ||
|
|
||
| If your plugin reads external files (config files, templates, etc.) | ||
| that webpack does not track by default, you must tell webpack to watch them. | ||
|
|
||
| The `compilation.fileDependencies` set allows you to add files that your plugin depends on, so webpack can trigger a rebuild when those files change. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the same pattern for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the feedback! |
||
|
|
||
| You can also extend this behavior to other types of dependencies: | ||
|
|
||
| - `compilation.contextDependencies` is used to watch directories, so any change inside them triggers a rebuild | ||
|
|
||
| - `compilation.missingDependencies` is used to track files that are currently missing, so webpack can trigger a rebuild when they are created | ||
|
|
||
| ```js | ||
| import path from "node:path"; | ||
|
|
||
| class TemplateWatchPlugin { | ||
| apply(compiler) { | ||
| compiler.hooks.compilation.tap("TemplateWatchPlugin", (compilation) => { | ||
| const templatePath = path.resolve(__dirname, "my-template.html"); | ||
|
|
||
| // Ensure webpack watches this file | ||
| compilation.fileDependencies.add(templatePath); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add example how to add context and missing dependencies too
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve added examples for contextDependencies and missingDependencies as suggested. Let me know if anything else is needed. |
||
|
|
||
| // Watch a directory (context dependency) | ||
| const templatesDir = path.resolve(__dirname, "templates"); | ||
| compilation.contextDependencies.add(templatesDir); | ||
|
|
||
| // Example: mark a missing dependency | ||
| const missingFile = path.resolve(__dirname, "missing-file.txt"); | ||
| compilation.missingDependencies.add(missingFile); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| export default TemplateWatchPlugin; | ||
| ``` | ||
|
|
||
| Without calling `fileDependencies.add()`, webpack will not trigger | ||
| a rebuild when the file changes — even if your plugin depends on it. | ||
|
|
||
| ## Different Plugin Shapes | ||
|
|
||
| A plugin can be classified into types based on the event hooks it taps into. Every event hook is pre-defined as synchronous or asynchronous or waterfall or parallel hook and hook is called internally using call/callAsync method. The list of hooks that are supported or can be tapped into is generally specified in `this.hooks` property. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
webpack watchorwebpack serve