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'),
]
})
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!
Most helpful comment
You can specify postCssPlugins per file as follows:
Note that with Tailwind it still requires a global
mix.options({ processCssUrls: false })or it fails to compile.