How to stop purging tailwind components - javascript

I am using TailwindCSS and Laravel Mix. I am trying to setup PurgeCSS and I have got it reading my template files (working with WordPress) and purge any CSS not within the template files.
However, as part of Tailwind, I am using #apply in my scss files and those utilities I am applying are also being purged which leaves me with a non functioning site.
My sass files are in css/dev and there is an app.scss and then directories with more files within them (base, utilities, custom, components).
My webpack.mix.js file configuration is as follows:
mix.scripts(['js/dev/app.js', 'js/dev/navigation.js', 'js/dev/skip-link-focus-fix.js'],
'js/build/app.js')
.sass('css/dev/app.scss', 'css/build')
.options({
processCssUrls: false,
postCss: [tailwindcss('./tailwind.config.js')],
})
.purgeCss({
enabled: mix.inProduction(),
// Your custom globs are merged with the default globs. If you need to
// fully replace the globs, use the underlying `paths` option instead.
globs: [
path.join(__dirname, 'template-parts/*.php'),
path.join(__dirname, '*.php'),
path.join(__dirname, 'css/dev/*.scss'),
path.join(__dirname, 'css/dev/**/*.scss'),
],
extensions: ['html', 'js', 'php', 'scss', 'css'],
});
As you can see, I tried setting the paths for purgeCss to look inside the css paths but that has not worked.
Does anyone know how to achieve this?

You are compiling your scss to css before Purge runs, so there should be no need to purge your .scss files only your main.css (or whatever the output is called).
Do your compiled class names actually exist in full in your template files? If they are not a 100% match for the classes in your templates then they will, quite correctly, be purged.

The issue was with WordPress classes not being included in the template files and then being purged. The solution was switching to using UnCSS which allowed me to setup URLS for UnCSS to visit and it won't purge any classes used on those pages. I also included some standard WordPress classes which I found a list of online.
My final config is:
const uncss = require('postcss-uncss');
mix.js('js/dev/app.js', 'js/build/app.js')
.sass('css/dev/app.scss', 'css/build')
.options({
processCssUrls: false,
postCss: [
tailwindcss('./tailwind.config.js'),
...process.env.NODE_ENV === 'production' ? [uncss({
html: [
'./*.php',
'./template-parts/*.php',
'https://www.example.com',
'https://www.example.com/work/',
'https://www.example.com/work/example-project/',
'https://www.example.com/contact/',
'https://www.example.com/blog/',
'https://www.example.com/blog/laravel-php-framework/',
],
ignore: [
'.rtl',
'.home',
'.blog',
'.archive',
'.date',
'.error404',
'.logged-in',
'.admin-bar',
'.no-customize-support',
'.custom-background',
'.wp-custom-logo',
'.alignnone',
'.alignright',
'.alignleft',
'.wp-caption',
'.wp-caption-text',
'.screen-reader-text',
'.comment-list',
'.grecaptcha-badge',
/^search(-.*)?$/,
/^(.*)-template(-.*)?$/,
/^(.*)?-?single(-.*)?$/,
/^postid-(.*)?$/,
/^attachmentid-(.*)?$/,
/^attachment(-.*)?$/,
/^page(-.*)?$/,
/^(post-type-)?archive(-.*)?$/,
/^author(-.*)?$/,
/^category(-.*)?$/,
/^tag(-.*)?$/,
/^tax-(.*)?$/,
/^term-(.*)?$/,
/^(.*)?-?paged(-.*)?$/,
'.animate',
'.animated',
'.bounce',
'.fadeInDown',
'.fadeIn',
'.fadeInUp',
'.jackInTheBox',
]
})] : [],
]
});
I also made use of the UnCSS exclude from purge CSS comments:
/* uncss:ignore start */
my css goes here
/* uncss:ignore end */
I ended up using this on all my custom sass files except for the tailwind files so that the only selectors that are purged are tailwind utilities, which saved me about 300 KB.

Related

Webpack leaves JS in cache file when compiling multiple JS libraries

I'm trying to configure Webpack so that it compiles multiple JS files. But when I do this the majority of JS is left in a cache file, the contents of which isn't included in my files.
Generated files:
js
-- theme--01.js (134kb)
-- theme--02.js (134kb)
-- theme--03.js (134kb)
-- theme--04.js (134kb)
-- themevendors-lib_common_scripts_global_libraries_js-lib_common_scripts_global_smoothscroll_min_js--8bace3.js (753kb)
When I generate one file it works correctly:
js
-- theme--01.js (879kb)
How my entry points are configured:
entry: {
"--01": path.resolve(process.cwd(), 'src', 'theme--01.ts'),
"--02": path.resolve(process.cwd(), 'src', 'theme--02.ts'),
"--03": path.resolve(process.cwd(), 'src', 'theme--03.ts'),
"--04": path.resolve(process.cwd(), 'src', 'theme--04.ts'),
},
Here's my complete Webpack config on JSfiddle as StackOverflow won't let me paste the whole thing here: https://jsfiddle.net/charlievaughan/rpeztbLj/
I need to generate multiple files from the same codebase for different locales and to optimise page-load speeds / Lighthouse scores.
Using Webpack v5.62.1
I fixed this issue by removing the following from my Webpack config:
splitChunks: {
chunks: 'all'
}

How can I purge CSS based on the HTML output?

I'm currently working on a project in Next.js where we use custom SCSS combined with Bootstrap SCSS and React-Bootstrap. We noticed our main.scss file (where our custom SCSS and Bootstrap SCSS is bundled) is getting too heavy.
When I checked in the coverage tab in Chrome, I noticed 95% of the CSS is not being used. So I want to get rid of all the CSS which is in the Bootstrap SCSS files and which is not being used.
I found that you can purge CSS by adding a postcss.config.js file in Next.js and then adding purgeCSS there (https://purgecss.com/guides/next.html).
The problem is that this is based on the source code (JS,JSX,TS,TSX files).
In the source file we use react-bootstrap components, which use some of the CSS in the Bootstrap SCSS files too. This is not picked up by purgeCSS because the classes are not literally in the source code.
This is why I want the purgeCSS to run on the output HTML from Next.js.
For this I adapted the build task in my package.json to this:
"build": "next build && purgecss --css ./.next/static/**/*.css --content ./.next/server/**/*.html --output ./.next/static/css",
This works fine, the CSS output is exactly what I want. But I don't know how to make it so Next.js actually uses this new CSS file on the website instead of the unoptimized CSS. Any ideas?
If you use regex with the safelist attribute in your postcss.config.js file, then purgecss will work correctly. We had the same problem with bootstrap-react, purgecss, and next.js. Here's our postcss.config.js:
module.exports = {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: { flexbox: "no-2009" },
stage: 3,
features: { "custom-properties": false }
}
],
[
"#fullhuman/postcss-purgecss",
{
content: ['./components/**/*.{js,jsx,ts,tsx}', "./pages/**/*.{js,jsx,ts,tsx}"],
css: ['./styles/**/*.{css,scss}'],
defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: {
standard: ["html", "body", "btn" ],
deep: [/^col/, /^navbar/, /^nav/]
}
}
]
]};
Basically, I've added the regex expressions to safelist any classes that start with "col", "navbar", and "nav". Just inspect any of the classes that aren't getting picked up and add the corresponding regex expression.

webpack: How to inject the JS chunks in the a YAML file

I'm using webpack to modernize a legacy MVC application (symfony 1.4)
I would like to inject the JS chunks and the CSS file in a YAML file that contains several other settings.
Here is an example:
default:
foo: bar
.
.
stylesheets: [ style.db80006f5e14f38456ef.css ]
javascripts: [ runtime.d8969ec83f67a36c8877.js, npm.material.db07856eff6817abe7f2.js, main.db80006f5e14f38456ef.js ]
.
.
The html-webpack-plugin supports plugin as well. I was wondering if it would be possible with my own plugin for the html-webpack-plugin to inject the CSS files and JS files in a YAML file instead of an HTML template. I'm not sure if the html-webpack-plugin is the way to go since I don't want to manipulate an HTML file.
Maybe there is another possibility to get the names and the order of the JS chunks, plus the CSS file.
Thanks a lot in advance!
html-webpack-plugin is the way to go, you can provide your "base" yaml file as a template, and provide a templateContent function that will generate your yaml content.
Something like this:
new HtmlWebpackPlugin({
templateContent: function(params) {
return `
default:
stylesheets: [ ${params.htmlWebpackPlugin.files.css.join(',')} ]
javascripts: [ ${params.htmlWebpackPlugin.files.js.join(',')} ]
`;
},
filename: 'path-to/where/to/save/your.yaml',
inject: false, // prevents from the plugin to auto-inject html tags
});

vuejs - how to add vue-material theme

I am starting a vuejs project using vue-cli.
I want to use vue-material as the main look and feel but I am not sure how to change the theme color.
from vue-material:
To use custom themes you'll need SCSS/SASS support in your project.
Read more about Pre-Processors. In the near future you'll be able to
use themes with Plain CSS and Stylus too.
and provide with this code:
#import "~vue-material/dist/theme/engine"; // Import the theme engine
#include md-register-theme("default", (
primary: md-get-palette-color(green, A200), // The primary color of your application
accent: md-get-palette-color(pink, 500) // The accent or secondary color
));
#import "~vue-material/dist/theme/all"; // Apply the theme
which I created a style.scss to include them.
and from vuejs come with this code:
module.exports = {
module: {
rules: [
// ... other rules omitted
// this will apply to both plain `.scss` files
// AND `<style lang="scss">` blocks in `.vue` files
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
// plugin omitted
}
First of all, there isn't any webpack.config.js. but there is a babel.config.js. So i created webpack.config.js and include the code too.
When I run npm run serve, nothing seems to happen. there isn't any error or warning too.
I am new with webpack and I really not sure how this all work.
vue-cli doesn't have a webpack.config.js file. You don't need to make one. Instead, you can put your options inside build/webpack.base.conf.js.

Webpack to simply compile a bunch of Pug templates to HTML

Im getting started with webpack but one thing I cannot for the life of me work out is how to take a folder (with possible nested folders), full of .pug templates, and simply compile them to static html and put them in the output folder, maintaining any nested folder structure for each output html file that was in the source templates folder...
I dont want to have to manually specify each individual .pug file, and I definitely dont want webpack to try and parse the .pugs into JS and then attempt to require/import any of the imgs/fonts etc in the pug files and then complain about it, Im just after a basic, static 1:1 compile, pug file in, html file out. Why is it so hard to do that?
Use pug-html-loader to convert .pug to .html file. Use file-loader to copy the file to desired location. Don't use html-loader as you don't want to process resources used by the generated file.
You will end up something like this in your loader rules (untested, webpack 1 syntax, you may need to tweak it for webpack 2)
{
test: /\.pug$/,
loaders: ['file-loader?name=[path][name].html', 'pug-html-loader?pretty&exports=false']
}
Next you need to require all your pug files in your entry file
function requireAll (r) { r.keys().forEach(r); }
requireAll(require.context('./', true, /\.pug$/));
This can be done very simply with only html-webpack-plugin and pug-loader.
webpack.config.js
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// No javascript entrypoint to evaluate. Let the plugin do the heavy lifting
entry: {},
// Translate Pug to HTML
module: { rules: [ { test: /\.pug$/, use: 'pug-loader' } ] },
// Save HTML to file
plugins: [ new HTMLWebpackPlugin({ template: './src/index.pug' }) ]
};
./src/index.pug
doctype html
html(land="en")
head
include path/to/another.pug
...
Got this information from https://extri.co/2017/05/23/using-htmlwebpackplugin-and-pug/ and you can also go further to import css and javascript as normally done with html-webpack-plugin.

Categories

Resources