Configuring postcss-uncss for Laravel Mix - laravel

I am trying to remove unused css rules from one or more of my sass files.
Research led me to postcss-uncss as the best option for removing unused css if you do not use server-side rendering (see: https://www.purgecss.com/comparison)
https://github.com/uncss/postcss-uncss
Now, postcss-uncss is a wrapper for uncss: https://github.com/uncss/uncss
However, the uncss documentation is confusing to me, and the example configuration here is not useful: https://github.com/uncss/postcss-uncss#example-configuration
How does one configure postcss-uncss for Laravel Mix?
THis is what I have so far:
mix.js('resources/js/app.js', 'public/js')
.options({
processCssUrls: false,
postCss: [
require('postcss-uncss'),
tailwindcss('./tailwind.config.js')
],
})
I want to:
Tell it which laravel routes to use (or 'all' should also be fine)
Where my sass / scss files are located: /resources/sass/* (example files: /resources/sass/app.scss, /resources/sass/admin/admin.scss, etc)
Where to put the output ie the compiled (and cleaned up) css without the unused rules: /public/css/* (so as to preserve the same structure, for example: /public/app.css, /public/admin/admin.css, etc)
Thoughts would be greatly appreciated.

This is what I ended up doing (used purgecss, which turns out, is a better option than uncss, according to my conversation with Adam Wathan
let mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');
// Removes unused CSS
// According to Discord chat: Running Purge CSS as part of Post CSS is a ton faster than laravel-mix-purgecss
// But if that doesn't work use https://github.com/spatie/laravel-mix-purgecss
const purgecss = require('#fullhuman/postcss-purgecss')({
// Specify the paths to all of the template files in your project
content: [
'./resources/views/*.php',
'./resources/views/**/*.php',
'./resources/js/components/*.vue',
'./resources/js/components/**/*.vue',
],
// Include any special characters you're using in this regular expression
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
});
mix.options({
clearConsole: true, // in watch mode, clears console after every build
processCssUrls: false,
postCss: [
//require('tailwindcss'),
tailwindcss('./tailwind.config.js'),
// to enable purgecss on production only
...process.env.NODE_ENV === 'production' ? [purgecss] : []
// to enable on all environments, local and production
//purgecss
],
})
;

Perhaps you might try the Spatie package?
Let's install it.
npm i laravel-mix-purgecss
Call purgeCss() in your webpack.mix.js.
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.purgeCss({ enabled: true });

Related

Laravel vite config using separate tailwind.config files for admin and site

With Laravel Mix I'm generating two different css/js files for Admin and for the main site like this:
const mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');
mix.js('resources/js/site/app.js', 'public/js')
.postCss('resources/css/site/app.css', 'public/css', [
require('autoprefixer'),
require('postcss-import'),
tailwindcss('./tailwind.site.config.js'),
])
.options({
processCssUrls: false,
}).version();
mix.js('resources/js/admin/app.js', 'public/_admin/js')
.postCss('resources/css/admin/app.css', 'public/_admin/css', [
require('autoprefixer'),
require('postcss-import'),
tailwindcss('./tailwind.admin.config.js'),
])
.options({
processCssUrls: false,
}).version();
How can I tell vite to do the same thing ??
Thanks!!
The default vite.config.js is
import { defineConfig } from 'vite';
import laravel, { refreshPaths } from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: [
...refreshPaths,
'app/Http/Livewire/**',
],
}),
],
});
Create two vite.config.js files, and also create two tailwind.config.js files for frontend & backend.
I have already posted this solution on github with demo laravel project.
https://github.com/pkfan/setup-laravel-vite-for-multiple-tailwind.config.js
I have upload a video about it.
watch this video on youtube
See https://laravel-vite.dev/guide/extra-topics/multiple-configurations.html.
You will need to add a configuration to config/vite.php, create a new vite.back-office.config.ts file, pass the configuration name to the #vite directive and run slightly different development and build commands.
The docs are TypeScript-focused, but the same technique will work for your JS/CSS assets.
Starting with Tailwind CSS v3.2, hacky workarounds are no longer needed.
You can now define the config file to use inside of your CSS files:
https://tailwindcss.com/blog/tailwindcss-v3-2#multiple-config-files-in-one-project-using-config

Minify a CSS and HTML file to the same location using Laravel Mix

I have two files, one CSS and one HTML in these locations:
resources/js/example/file.css
resources/js/example/file.html
What I would like to do using Laravel Mix (webpack) is
Minify the CSS file into file.min.css into the same directory
Minify the HTML file into file.min.html into the same directory
I have tried:
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', [
require('cssnano')
]);
But this creates the CSS file in public/js/example/file.min.css.
I'm not sure why you don't want compiled files to be in the public directory. Regardless, you can use mix.setPublicPath() to change the output directory. This will tells Mix what you want the basic directory where all of your assets should be compiled to.
webpack.mix.js
const mix = require('laravel-mix');
mix.setPublicPath('');
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', []);
If you want to Mix and minify HTML files you can install this plugin.
npm install minify-html-webpack-plugin --save-dev
Then add to your webpack...
const MinifyHtmlWebpackPlugin = require('minify-html-webpack-plugin');
const mix = require('laravel-mix');
mix.setPublicPath('');
mix.postCss('resources/js/example/file.css', 'resources/js/example/file.min.css', []);
mix.webpackConfig({
plugins: [
new MinifyHtmlWebpackPlugin({
afterBuild: true,
src: './resources/js/example',
dest: './resources/js/example',
ignoreFileNameRegex: /\.(gitignore|php)$/,
ignoreFileContentsRegex: /(<\?xml version)|(mail::message)/,
rules: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
minifyJS: true,
}
})
]
});
And make a dev or production build. Keep in mind you will have to play around with the src and dest to get the output exactly the way you want it.

Webpack Laravel-Mix Chunk error TypeError: "e[r] is undefined"

Am building a web application with Vue and Laravel.
Am utilizing code splitting and versioning with Laravel mix and Webpack under the hood.
However, whenever i make changes to my code, run npm run production and upload on the live server, on frequent occations i receive TypeError: "e[r] is undefined"
I have to manually clear browser cache before the page loads correctly.
I already have versioning enabled and thus cache busting should be automated.
Below is my webpack.mix.js file
const mix = require('laravel-mix');
const webpack = require('webpack');
mix.webpackConfig({
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
})
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
plugins: [new CompressionPlugin()],
optimization: {
minimize: true,
namedModules: true,
namedChunks: true,
removeAvailableModules: true,
flagIncludedChunks: true,
occurrenceOrder: false,
usedExports: true,
concatenateModules: true,
sideEffects: false, // <----- in prod defaults to true if left blank
}
};
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/main/main.js', 'public/v1.4.0/js')
.sass('resources/sass/app.scss', 'public/css')
.extract(['vue'])
.version();
I had a similar problem and I found a solution that wasn't quite good but it worked: set in webpack config options optimization.concatenateModules and optimization.minimize to false.
After a lot of hustle,
my best approach was to control cache from the server software itself.
Ex: you can prevent JS and CSS caching from nginx / apache/http configurations

How to Use PurifyCSS in Laravel Mix?

I want to use PurifyCSS in Laravel but I can't get it to work.
Stack
Laravel: 5.5.4
NPM: 6.0.0
Node.js: 8.10
Code
mix.styles([
'resources/assets/css/panel/a.css',
'resources/assets/css/panel/b.css',
'resources/assets/css/panel/c.css',
'resources/assets/css/panel/d.css',
], 'public/css/panel.css').options({
purifyCss: {
purifyOptions: {
info: true,
rejected: true,
minify: true
},
paths: ['resources/views/admin-layout.blade.php'],
verbose: true
},
});
I searched on the internet but couldn't find anything. I want to strip unused CSS from all Blade pages. Even on this link, nobody answered with the correct answer. Even if PurifyCSS is first, it's not working.
Thanks for the help.
Relatively simple as you can declare the mix variable and then set your options.
const mix = require('laravel-mix');
mix.options({
purifyCss: true
});
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');

Compiling ES6 (ReactJS) code to work with IE >=9

So I have been building an application in React JS and have been taking advantage of some of the syntax that ES6 provides such as:
using let and const
class components
arrow functions (componentWillMount = () => {})
constructorless state declaration (state = {someProperty: true})
I am running into some issues when compiling though. My code seems to work with most chromes as far as I can tell but the whole thing breaks down around IE9 or IE10. What is the proper way to set up my .babelrc file? (below is what I have right now)
{
"presets": [
["es2016"],
"react"
],
"plugins": [
"babel-plugin-transform-class-properties"
]
}
Also bonus points to anyone who knows how to set this up for Laravel-mix as the components I have built live within a laravel 5.5 env. (here is how my webpack.mix.js file looks as of right now)
mix.react('resources/assets/js/app.js', 'public/js/app.js')
.js('resources/assets/js/cross-brand-nav.js', 'public/js/app.js')
.js('resources/assets/js/FullWidthTabs.js', 'public/js/app.js')
.js('resources/assets/js/universal-nav.js', 'public/js/app.js')
.version()
.combine([
'resources/assets/bower_assets/jquery/dist/jquery.min.js',
'resources/assets/bower_assets/moment/min/moment.min.js',
'resources/assets/bower_assets/bootstrap/dist/js/bootstrap.js',
'resources/assets/bower_assets/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js',
'resources/assets/js/admin.js'
], 'public/js/admin.js').version()
.sass('resources/assets/sass/app.scss', 'public/css')
.sass('resources/assets/bower_assets/components-font-awesome/scss/font-awesome.scss', 'public/css').version()
.styles([
'resources/assets/css/FullWidthTabs.css'
], 'public/css/pf.css')
.styles([
'resources/assets/bower_assets/bootstrap/dist/css/bootstrap.min.css',
'resources/assets/bower_assets/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css'
], 'public/css/admin.css').version();
Try https://babeljs.io/repl/ to convert your code to work with whatever browser you want , it has lot of options for conversion , try that and if you have any question post it here we will help

Resources