spatie / laravel-mix-purgecss

Zero-config Purgecss for Laravel Mix
https://spatie.be/en/opensource
MIT License
874 stars 38 forks source link

Scan files with .css extension #70

Closed bakerkretzmar closed 5 years ago

bakerkretzmar commented 5 years ago

Love this package, thanks so much! This is a different question from #67 (I am sending my css through postCSS, and I'm trying to not purge certain classes).

Maybe I'm missing something, but is there a way to scan for classes defined in my own .css files? Very minimal reproduction of my setup:

// webpack.mix.js

mix.postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
])

if (mix.inProduction()) {
    mix.purgeCss({
        extensions: ['html', 'js', 'php', 'vue', 'css']
    })
}
/* resources/css/app.css */
@import 'custom';
/* resources/css/custom.css */
.special-snowflake-class {
    @apply .block .bg-blue-500;
    height: 42px;
}

I would have thought that because I listed css in the extensions to scan, any of my own classes in my css files would be included, that's not happening. I need .special-snowflake-class included in my build even if it doesn't appear anywhere else in my project besides where it's defined in custom.css. Is that possible?

Thanks!

spatie-bot commented 5 years ago

Dear contributor,

because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.

btumbleson commented 5 years ago

Can this be re-opened? I'm facing a similar issue wherein vanilla CSS files don't appear to be processed.

sebastiandedeyne commented 5 years ago

This used to not be possible with Purgecss, if someone can confirm this has changed, this can be reopened.

bakerkretzmar commented 5 years ago

I'm pretty sure it still isn't, I ended up solving this by just whitelisting all the selectors I needed to keep:

mix.sourceMaps()
  .purgeCss({
    whitelistPatterns: [
      /brand-(blue|teal|yellow|orange|pink)/,
      /^bg/,
      /^text/,
      /^grid-time/,
      /^mapboxgl/,
    ],
    whitelistPatternsChildren: [/^markdown$/, /^ais-[\S]*/],
  })
btumbleson commented 5 years ago

Forgive the ignorance, but your own package here has an example app.css in an "example" folder, using vanilla CSS: image

What am I missing?

bakerkretzmar commented 5 years ago

@btumbleson if I understand correctly, Purgecss only scans files where you're using the selectors, like in your HTML, and removes the ones that it doesn't find there. The option I actually needed, which doesn't exist in Purgecss, is to ignore selectors from certain specific CSS files. Basically I want to purge Tailwind's imported classes, but not the ones that I defined myself in resources/css/app.css, but I don't think there's a way to do that.

btumbleson commented 5 years ago

@bakerkretzmar thanks for the response. I must have another issue then. I joined a bunch of vanilla CSS files into a single one using mix's .styles option. I then use .purgeCss in the chain and haven't seen any level of compression (though I expected much of an old Bootstrap 3 library to get dropped). I must not have my folders/ globs set correctly.

sebastiandedeyne commented 5 years ago

Iirc mix.styles only concatenates css files, it doesn’t do any processing. You’ll need to use mix.postCss instead.

btumbleson commented 5 years ago

@sebastiandedeyne yep that makes sense. Going to hijack this issue once more... I can't seem to find any mix-method to join multiple postCss files. I've resorted to having each of my vanilla CSS files process to standalone files (via PostCSS so I can run PurgeCSS on them), then, I just use the existing .styles method to combine all those files to a final file. It ain't pretty, but it works. Any other thoughts? mix.postCss doesn't accept an array of input files, unfortunately.

Here's what I mean:

mix.js('resources/assets/js/app.js', 'public/js')
    .postCss('resources/assets/css/client/bootstrap.css','../resources/assets/css/compile/1.css')
    .postCss('resources/assets/css/client/font-imports.css', '../resources/assets/css/compile/2.css')
    .postCss('resources/assets/css/client/style.css', '../resources/assets/css/compile/3.css')
    .purgeCss()
    .options({
        processCssUrls: false,
    })
    .styles([
        'resources/assets/css/compile/1.css',
        'resources/assets/css/compile/2.css',
        'resources/assets/css/compile/3.css',
    ], 'public/css/client-app.css'); 
bakerkretzmar commented 5 years ago

@btumbleson use postcss-import and point PostCSS at one main css file that just imports all the others. The Tailwind docs recommend this too and have a good example here.

btumbleson commented 5 years ago

@bakerkretzmar Surprisingly painless and disappointed I didn't figure that out myself. Thanks for pointing me in the right direction. In case anyone else lands here, Baker has the right approach from his comment:

mix.js('resources/assets/js/app.js', 'public/js')
    .options({
        processCssUrls: false,
        postCss: [
            require('postcss-import'),
        ]
    });

mix.postCss('resources/assets/css/client/combined.css','public/css/client-app.css')
    .purgeCss();