Laravel-mix: [Question] Different Options Per File

Created on 20 Jun 2019  路  10Comments  路  Source: JeffreyWay/laravel-mix

Hi,

Is it possible to apply "options" to specific files? We effectively need 1 set of options for 1 file, and another set of options for another.

However as .options seems to be global it applies to both. e.g.

mix.sass('resources/css/frontend.scss', 'public/css') mix.sass('resources/css/backend.scss', 'public/css')

If we're using something like Tailwind we then have

tailwind.frontend.js
tailwind.backend.js

Currently if you do something like

mix.sass('resources/css/frontend.scss', 'public/css')
mix.sass('resources/css/backend.scss', 'public/css')

mix.options({
    processCssUrls: false
})

Both your frontend.css and backend.css share the same options.

Is it possible to do something like

mix.sass('resources/css/frontend.scss', 'public/css', {
    processCssUrls: true
})

mix.sass('resources/css/backend.scss', 'public/css', {
    processCssUrls: false
})

Note: Specifically we want to use 2 different postCss configs as we have a Tailwind config for the frontend, and a different config for the backend. e.g.

mix.sass('resources/css/app.scss', 'public/css', {
    postCss: [
        tailwindcss('tailwind.frontend.js'),
    ]
})
stale

Most helpful comment

You can specify postCssPlugins per file as follows:

mix.sass('resources/css/frontend.scss', 'public/css', {}, [tailwindcss('./tailwind.frontend.js')])
mix.sass('resources/css/backend.scss', 'public/css', {}, [tailwindcss('./tailwind.backend.js')])

Note that with Tailwind it still requires a global mix.options({ processCssUrls: false }) or it fails to compile.

All 10 comments

You can specify postCssPlugins per file as follows:

mix.sass('resources/css/frontend.scss', 'public/css', {}, [tailwindcss('./tailwind.frontend.js')])
mix.sass('resources/css/backend.scss', 'public/css', {}, [tailwindcss('./tailwind.backend.js')])

Note that with Tailwind it still requires a global mix.options({ processCssUrls: false }) or it fails to compile.

This seems to apply to extensions of laravel-mix, too - and I wonder how one might solve this issue in that arena, also.

See this comment in https://github.com/spatie/laravel-mix-purgecss/issues/73.

It seems weird to me that if you do a separate "mix stack", that an option applied to one becomes global.

For example, I'd expect purgeCss() to run on the second stack鈥搉ot on both鈥搘ith this configuration:

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']
            }
        ]
   });

Is there a way to modify this behavior?

Here's a truncated version of my webpack.mix.js that does indeed solve this problem. Big thanks to @r1chm8 for providing the solution:

// ***************** SETUP ********************************************************************

let mix            = require('laravel-mix');
let purgecss       = require('@fullhuman/postcss-purgecss');
let commentkill    = require('postcss-discard-comments');
let prodAppPostCss = [];

// ***************** STYLES ******************************************************************

/**
 * Compile vendor.css from `/resources/assets/sass/vendor.scss`
 *
 * There is no PostCss processing done on this CSS, since there is
 * not a great way to test the views for the classes that the JS for
 * these libraries creates.
 */
mix.sass('resources/assets/sass/vendor.scss', 'public/assets/css');

/**
 * Compile app.css from `/resources/assets/sass/app.scss`
 * 
 * Afterwards, we will run purgeCss() on the compiles CSS in order
 * to strip out unused CSS rules if NODE_ENV=production (set in the npm scripts).
 *
 * The following syntax is documented at `node_modules/laravel-mix/src/components/Sass.js`
 */
mix.sass('resources/assets/sass/app.scss', 'public/assets/css', {/* SASS Configs */}, prodAppPostCss);

// ***************** CONDITIONALS *************************************************************

if(mix.inProduction()) {
    prodAppPostCss.push(
        purgecss({
            content: [
                // Check the View files and the compiled JS files for 
                // CSS rules to keep.
                './resources/views/**/*.php',
                './public/assets/js/*.js'
            ],
            extractors: [
                {
                    extractor: class {
                        static extract(content) {
                            return content.match(/[A-Za-z0-9-_:/]+/g) || []
                        }
                    },
                    extensions: ['blade', 'js', 'php']
                }
            ]
        }),
        commentkill({
            removeAll: true
        })
    );
}

As it goes, you could define a separate array of parameters to pass to the first .sass() stack, or to any other stack. It's not the super-stripped-down mix syntax some people might love, but it does work, it is simpler than gulp, and it's pretty powerful.

Hope that helps!

It does the separate compile. But my production code for tailwind css is still 692 kb. while using laravel-mix-purgecss gives 5 kb.

Are you running it with NODE_ENV=production?

Are you running it with NODE_ENV=production?

I am using laravel-mix, obviously it must use it while running npm run prod.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

processCssUrls is showing invalid option

Can you paste the error or the situation this is happening in?

I kept getting a TypeError error when trying your solution. Turns out the the extractor just needed to be converted to function as shown here:

https://github.com/FullHuman/purgecss/issues/274

Thanks for sharing this solution!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pixieaka picture pixieaka  路  3Comments

rlewkowicz picture rlewkowicz  路  3Comments

Micaso picture Micaso  路  3Comments

amin101 picture amin101  路  3Comments

kpilard picture kpilard  路  3Comments