spatie / laravel-mix-purgecss

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

Purge only specific file #73

Closed MatusBoa closed 5 years ago

MatusBoa commented 5 years ago

Hey,

I tried to find any issue, or something in wiki but no luck there. I will try to describe my problem best I can.

Given I have files app.less

admin.less

File admin.less contains styles for admin theme, so I do not want to purge admin.less. I will provide path to templates, where purgeCss can scan for classes, and I want to purge only app.less, totally ignoring admin.less. Is it somehow possible?

Regards.

ethanbeyer commented 5 years ago

I'm having this issue, too - but I think it must be a laravel-mix problem more than this library.

If I add a .purgeCss() call to a mix.sass() stack, I'd expect it to only apply itself to that stack, but it seems to affect all of them.

Here are some tests I ran:

Dev Baseline

mix.sass('resources/assets/sass/vendor.scss', 'public/assets/css');
mix.sass('resources/assets/sass/app.scss', 'public/assets/css');

command: $ npm run dev expanded: $ cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --config=node_modules/laravel-mix/setup/webpack.config.js --progress

Output:

                 Asset      Size  Chunks             Chunk Names
   /assets/css/app.css   328 KiB     mix  [emitted]  mix
/assets/css/vendor.css  43.4 KiB     mix  [emitted]  mix

Production, without PurgeCSS

mix.sass('resources/assets/sass/vendor.scss', 'public/assets/css');
mix.sass('resources/assets/sass/app.scss', 'public/assets/css');

command: $ npm run production expanded: $ cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --config=node_modules/laravel-mix/setup/webpack.config.js --no-progress

Output:

                 Asset      Size  Chunks                    Chunk Names
   /assets/css/app.css   267 KiB       0  [emitted]  [big]  mix
/assets/css/vendor.css  34.6 KiB       0  [emitted]         mix

Production, with PurgeCSS

mix.sass('resources/assets/sass/vendor.scss', 'public/assets/css');
mix.sass('resources/assets/sass/app.scss', 'public/assets/css')
   .purgeCss({
        content: ['./resources/views/**/*.php', './public/assets/js/*.js'],
        css: ['./public/assets/css/app.css'],
        extractors: [
            {
                extractor: class {
                    static extract(content) {
                        return content.match(/[A-Za-z0-9-_:/]+/g) || []
                    }
                },
                extensions: ['blade', 'js', 'php']
            }
        ]
   });

command: $ npm run production expanded: $ cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --config=node_modules/laravel-mix/setup/webpack.config.js --no-progress

Output:

                 Asset      Size  Chunks             Chunk Names
   /assets/css/app.css   160 KiB       0  [emitted]  mix
/assets/css/vendor.css  2.25 KiB       0  [emitted]  mix

I think the only way to do this is to use the mix.postCss() stack to affect a single file - but I haven't fully tested that yet.

r1chm8 commented 5 years ago

I actually managed to solve this issue using the original purgecss package, instead of Spatie's package.

const mix = require('laravel-mix');
const purgecss = require('@fullhuman/postcss-purgecss');

mix.sass('resources/sass/front.scss', 'front/css')
mix.sass(
    'resources/sass/back.scss',
    'back/css',
    {},
    [ purgecss({ ... }) ]
);
ethanbeyer commented 5 years ago

@r1chm8 were you able to make sure that purgeCss was only applied when NODE_ENV=production?

r1chm8 commented 5 years ago

Yeah, I made that possible by doing the following:

let options = [];

if (mix.inProduction()) {
    options.push(
        purgecss({ ... })
    );

    mix.version();
}

// ...

mix.sass(
    'resources/sass/back.scss',
    'back/css',
    {},
    options,
);
ethanbeyer commented 5 years ago

@r1chm8 you are the man!

OwenMelbz commented 5 years ago

We're also having this problem - the plugin binds itself to the global mix namespace, ideally it should be compatible with both the global methods, and the individual methods (the 4th param of sass for example)

ethanbeyer commented 5 years ago

@OwenMelbz check out my full comment here: https://github.com/JeffreyWay/laravel-mix/issues/2143#issuecomment-524368071

MatusBoa commented 5 years ago

Issue solved thanks to @r1chm8 with this sample code

let options = [];

if (mix.inProduction()) {
    options.push(
        purgecss({ ... })
    );

    mix.version();
}

// ...

mix.sass(
    'resources/sass/back.scss',
    'back/css',
    {},
    options,
);

Thanks :slightly_smiling_face:

recoverjp commented 3 years ago

@r1chm8 you are the man! Thanks so much!!! ❤️