Skip to content
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

Purgecss webpack plugin/only filter fix #933

Merged

Conversation

mefu
Copy link
Contributor

@mefu mefu commented Jun 22, 2022

Proposed changes

Currently, when only option is used, each asset is processed again for each chunk. Reason for that is, if only option is set, code that checks if chunk contains the file is skipped. For every chunk, same files that pass through the only filter is processed again and again. This causes a massive performance hit on a big code base. You can see it in the code block below.

for (const chunk of compilation.chunks) {
const assetsToPurge = assetsFromCompilation.filter(([name]) => {
if (this.options.only) {
return this.options.only.some((only) => name.includes(only));
}
return chunk.files.has(name);
});

Types of changes

This PR changes above filter function so filter for only only returns if it is false. If a file passes only filter, it will also be checked against file list in the chunk.

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works

I did not add tests that actually tests if a file is compiled multiple times or not which is the main point of this PR. But I fixed a test that I believe was not testing what it intends to test. simple-with-exclusion test case of purgecss-webpack-plugin excluded everything from purgecss instead of excluding one part. You can see that there exists a file with name style_that_we_want_to_purge.css, yet in the expected output, unused css class is not purged at all (snippet below).

/*!****************************************************************************************************!*\
!*** css ../../../../../node_modules/css-loader/dist/cjs.js!./src/style_that_we_want_to_purge.css ***!
\****************************************************************************************************/
.hello {
color: red;
}
.unused {
color: blue;
}
.safelisted {
color: green;
}
md\:w-2\/3 {
color: red;
}

To fix this, I disabled the chunk group that merged style.css and style_that_we_want_to_purge.css into styles.css so we have two css chunks. only option specifies one of them and expected output does not have unused anymore.

  • I have added necessary documentation (if appropriate)

Docs mention only option filters by entrypoint name, but it actually filters by chunk name, because compilation assets are ultimately chunks. I think huskys pre-commit hook changed a lot of things in documentation file. I only changed 135th line. If you want, I can commit again with --no-verify.

Further comments

@Ffloriel Ffloriel self-requested a review July 4, 2022 20:29
@Ffloriel
Copy link
Member

Ffloriel commented Jul 4, 2022

Thanks a lot for looking into this!

@Ffloriel Ffloriel merged commit f8e4c2c into FullHuman:main Jul 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants