Skip to content
This repository has been archived by the owner on Feb 1, 2020. It is now read-only.

Cannot detect class names in React / JSX with {...} syntax #7

Closed
qodesmith opened this issue Dec 17, 2017 · 7 comments
Closed

Cannot detect class names in React / JSX with {...} syntax #7

qodesmith opened this issue Dec 17, 2017 · 7 comments

Comments

@qodesmith
Copy link

qodesmith commented Dec 17, 2017

First off, let me just say you guys rule! I was struggling with Purifycss for a while. Seems like its not getting the TLC it deserves. But then I found you guys. Purgecss to the rescue! The bundles it spits out are so tiny and it works with classes that end with numbers too! Bravo. But I digress...

TL;DR

Purgecss strips used class names in React w/JSX using template literals. Here's a repo that reproduces the issue.

The Details

Thing Version
Node 9.2.0
purgecss-webpack-plugin 0.15.0
webpack 3.10.0

The issue is Purgecss will not detect some class names being used. It then strips those styles out of the produced bundle.

Example

const Test = () => {
  const bg = 'bg-blue';

  /*
    NOTE: Remove this comment before running the code.
    Purgecss will pick up the word 'purple' in this comment and not reproduce the error.
    ----------------------------------------------------------------------------
    The 'purple' class is clearly used here but Purgecss will strip it out.
    The issue seems to be the combination of {` characters.
    If you put a space before 'purple', Purgecss will detect it and leave it in.
  */
  return (
    <h1 className={`purple ${bg}`}>Hello world!</h1>
  );
}
@Ffloriel
Copy link
Member

Thank you for the feedback 😊
I will investigate this issue

@jsnanigans
Copy link
Collaborator

jsnanigans commented Dec 17, 2017

I started using purgecss for the same reason :)

It looks like the default extractor sees "`purple" as one word (with the template quote). This is very unexpected, apparently the regex expression [A-z] includes "`" you could fix this my making your own extractor like this:

{
  extractor: class {
    static extract(content) {
      return content.match(/[A-Za-z0-9_-]+/g) || []
    }
  },
  extensions: ['jsx'] // file extensions
}

@qodesmith
Copy link
Author

qodesmith commented Dec 18, 2017

@jsnanigans Thank you very much for this. I see in the docs they show something just like your suggestion. Pardon my ignorance, but what syntax is this? I've not seen anonymous classes before. I had to make it a named class in order to not break the syntax highlighting in Sublime.

In any case, I too am shocked that [A-z] includes the backtick character. I just had to tweak your solution to read extensions: ['js'] and thing are working as expected for me. Thank you again!

@SebastianS90
Copy link
Contributor

I just created FullHuman/purgecss#37 for that.
A-z is the ascii range from 65 to 122, which also includes these special characters: [ \ ] ^ _ `

@Ffloriel
Copy link
Member

Ffloriel commented Jan 2, 2018

@qodesmith I learned this syntax recently too. It's called class expression.

I'm closing the issue as FullHuman/purgecss#37 is open. The default extractor will be modified in the next version.

@xelaz
Copy link

xelaz commented Nov 22, 2018

   {
          extractor: class {
            static extract(content) {
              return content.match(/[A-Za-z0-9-_:\\/]+/g) || [];
            }
          },
          extensions: ['js', 'jsx'], // file extensions
    },

You need capture Class Names with Responsible Utility Classes with : like md:* sm:* focus:*

@Arttse
Copy link

Arttse commented Dec 28, 2018

How about code like this?

const Test = () => {
  const block = 'some-block';

  return (
    <h1 className={`${block}__item ${block}_bg-blue purple`}>Hello world!</h1>
  );
}
.purple {
  color: purple;
}

.some-block__item {
  padding: 15px;
}

.some-block_bg-blue {
  background: blue;
}

PurgeCSS strips some-block__item and some-block_bg-blue

How to avoid it? Thank you.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants