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
(feat): add output.clean #11561
(feat): add output.clean #11561
Conversation
|
For maintainers only:
|
Can we add hooks? Why?
Some plugins may copy assets without using compilation.assets, so we could add additional files to delete, so we don't need extra option(s) to achieve behavior as clean-webpack-plugin
As @sokra said before |
|
Yep, I known, just idea how we can solve this without problems, sometimes you real need to copy files in dist directory without extra plugins, i.e. manifests/config files for env/etc, adding hook(s) should not be hard and provide flexibility solution |
|
I may add ignore regexp |
|
something like |
|
@smelukov Maybe this will be a good solution too, but most often plugins know what they are adding, which means they can form ignored files on their side (why I think hook(s) is good idea) |
|
@evilebottnawi Ok, I think this is a good idea |
|
@evilebottnawi look at the PR description to see some updates ;) |
|
Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon. |
Reviewed that a few commits ago but forgot to submit. Hopefully it's still up to date
schemas/WebpackOptions.json
Outdated
| "type": "boolean" | ||
| }, | ||
| { | ||
| "tsType": "(import('../declarations/plugins/CleanPlugin').CleanPluginArgument)" |
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.
Missing schema. Type info only doesn't work for validation
schemas/WebpackOptions.json
Outdated
| @@ -2037,6 +2048,10 @@ | |||
| "chunkLoadingGlobal": { | |||
| "$ref": "#/definitions/ChunkLoadingGlobal" | |||
| }, | |||
| "clean": { | |||
| "description": "Remove non-webpack assets from the output directory.", | |||
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.
The description is a bit unclear to me
| directories: collectedDirectories | ||
| }; | ||
| } | ||
|
|
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.
Whole plugin should use async fs methods.
On incremental build it should not read from filesystem, but assume old state
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.
On incremental build it should not read from filesystem, but assume old state
There is emittedOnce-flag for that
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.
There is
emittedOnce-flag for that
ah I see. The flag causes the plugin to do nothing on incremental compilation, but instead it should e.g. remove assets from the first compilation that are no longer part of the second compilation.
I would solve that by storing the filesystem state after the first compilation (which directories now contain which files) and use that instead of reading the filesystem in the second compilation. As said we assume that nothing expect webpack changes the output directory while webpack is running. This should be pretty efficient, no fs calls should be done expect for removing old assets, when they are no longer referenced.
lib/CleanPlugin.js
Outdated
| }, ""); | ||
| } | ||
|
|
||
| const collected = readDir(compiler.outputFileSystem, outputPath); |
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.
It's unnecessary to read the whole fs structure. It should be enough to read only the assetDirectories to know what to do.
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.
It's unnecessary to read the whole fs structure
Then how we know about files and directories that not a webpack-assets? assetsDirectories contains directories only from compilation.assets
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.
assetsDirectoriescontains directories only fromcompilation.assets
Yep that is perfect. You only need to read these directories to have full information what need to be done.
Read any other directory that's not in assetsDirectories would be wasted as it would be completely deleted anyway as the folder is extraneous in some directory of assetsDirectories anyway.
lib/CleanPlugin.js
Outdated
|
|
||
| if ( | ||
| !compiler.outputFileSystem || | ||
| !compiler.outputFileSystem.existsSync(outputPath) |
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.
Unnecessary, we can check for ENOENT error when reading.
lib/CleanPlugin.js
Outdated
| const assetsDirectories = new Set(); | ||
|
|
||
| for (const asset in compilation.assets) { | ||
| const parts = asset.split(path.sep).slice(0, -1); |
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.
Asset filename need to be normalized. Asset filename might be outside of the output directory.
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.
are you about path.resolve?
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.
Usually asset contains always / as it's considered as filename (it's not an absolute path), but we accept \ too just in case. So at least you need to split(/[\\\/]+/), remove any . and handle any ... As this could get tricky it might make sense to path.resolve the asset in the output.path and work with absolute paths only.
| this.logger = compiler.getInfrastructureLogger("webpack.Clean"); | ||
| this.fs = compiler.outputFileSystem; | ||
|
|
||
| compiler.hooks.emit.tapAsync( |
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.
Not sure it is safe to use emit, because I see a lot of plugins with stage: 99999/any number and using emit, maybe better introduce new hook, but let's wait @sokra answer
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.
I think that a new hook will not solve this problem, because any 3-rd party plugin may use this new hook too )
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.
We can implement hook cleanEmittedAssets, so nobody will use it for emitting
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.
But they can )))
|
Is this feature gonna be released for webpack 5 soon? I'm facing problems with the Clean Webpack Plugin and typescript in webpack 5. This option would make this plugin no longer required. Thanks for working on this! |
|
@sokra can you review, please? |
handle errors rename "ignore" to "keep"
|
Thanks |
|
I've created an issue to document this in webpack/webpack.js.org. |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

What kind of change does this PR introduce?
feature
closes https://github.com/webpack/webpack/projects/5#card-40756723
usage
or
dry-run
Not to delete the assets, just console.log about
ignore
by property
or
by hook
Did you add tests for your changes?
yes
Does this PR introduce a breaking change?
no
What needs to be documented once your changes are merged?
about output.clean
The text was updated successfully, but these errors were encountered: