bootstrap
bootstrap copied to clipboard
[DRAFT] Use postcss-drop-empty-css-vars to remove empty CSS variables
Warning Heavily draft
Linked to the discussion in https://github.com/twbs/bootstrap/pull/36597 and potentially addresses https://github.com/twbs/bootstrap/issues/36595. I've tried here to create a very simple PostCSS plugin to remove empty CSS vars.
Plugin repo: https://github.com/julien-deramond/postcss-drop-empty-css-vars Plugin code (very basic just to test the idea): https://github.com/julien-deramond/postcss-drop-empty-css-vars/blob/main/index.js
The plugin is deployed in 0.0.0 version
Running npm run css
with and without this plugin gives this diff:
2801d2800
< --bs-btn-font-family: ;
3506d3504
< --bs-dropdown-box-shadow: ;
3620d3617
< --bs-nav-link-font-weight: ;
3794d3790
< --bs-nav-link-font-weight: ;
4168d4163
< --bs-card-box-shadow: ;
4173,4175d4167
< --bs-card-cap-color: ;
< --bs-card-height: ;
< --bs-card-color: ;
4482,4483d4473
< --bs-breadcrumb-bg: ;
< --bs-breadcrumb-border-radius: ;
5191d5180
< --bs-toast-color: ;
5257d5245
< --bs-modal-color: ;
5271d5258
< --bs-modal-footer-bg: ;
5549d5535
< --bs-tooltip-margin: ;
6094d6079
< --bs-offcanvas-color: ;
/CC @mdo for thoughts
A simple sidenote here: automating this would prevent us from using advanced usages based on the space toggle technique.
I don't think Bootstrap will ever use this, but that's to be mentionned on your PostCSS plugin's Doc at least 😉
Might be worth opening an issue upstream in clean-css (if there isn't any already). Maybe they could implement this there too.
Might be worth opening an issue upstream in clean-css (if there isn't any already). Maybe they could implement this there too.
Yes good idea, I need to dig into their repo. https://github.com/clean-css/clean-css/issues/1180 might give some clues (+ https://github.com/clean-css/clean-css/commit/a6da53a8ada78678ec2502ed50a4977f4e668b9e)
I love the idea of this. I attempted to implement in Webpack but after building (npm run build
), I still see the empty variables in the outputted CSS. The empty variables I see are:
bs-btn-font-family bs-dropdown-box-shadow bs-nav-link-font-weight bs-nav-link-font-weight bs-card-box-shadow bs-card-cap-color bs-card-height bs-card-color bs-breadcrumb-bg bs-breadcrumb-border-radius bs-toast-color bs-modal-color bs-modal-footer-bg bs-tooltip-margin bs-popover-header-color bs-offcanvas-color
PyCharm shows red squigglies saying "Term expected".
My webpack.config.js:
const Path = require('path');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
var dev_config = {
cache: false,
mode: 'development',
devtool: 'source-map',
devServer: {
static: Path.resolve(__dirname, 'dist'),
port: 8080,
hot: true
},
entry: {
app: Path.resolve(__dirname, 'src/app.js'),
},
output: {
path: Path.join(__dirname, 'dist'),
filename: 'js/[name].js',
clean: true,
},
optimization: {
splitChunks: {
chunks: 'all',
name: false,
},
},
plugins: [
new MiniCssExtractPlugin({filename: 'css/app.css'}),
new CopyPlugin({
patterns: [
{from: "src/index.html", to: "index.html"},
],
}),
// new HtmlWebpackPlugin({
// title: "Generated by Webpack",
// filename: 'index.html',
// inject: 'body',
// }),
],
module: {
rules: [
{
test: /\.js$/,
include: Path.resolve(__dirname, '../src'),
loader: 'babel-loader',
},
{
test: /\.(scss)$/,
use: [{
// inject CSS to page
// loader: 'style-loader'
loader: MiniCssExtractPlugin.loader
},
{
// translates CSS into CommonJS modules
loader: 'css-loader'
},
{
// Run postcss actions
loader: 'postcss-loader',
options: {
// `postcssOptions` is needed for postcss 8.x;
// if you use postcss 7.x skip the key
postcssOptions: {
// postcss plugins, can be exported to postcss.config.js
plugins: function () {
return [
require('postcss-drop-empty-css-vars'),
require('autoprefixer'),
];
}
}
}
},
{
// compiles Sass to CSS
loader: 'sass-loader'
}]
},
{
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
type: 'asset'
},
],
},
};
module.exports = dev_config;
// console.log(JSON.stringify(dev_config, null, 2));
My package.json
{
"name": "bootstrap-missing-variables",
"scripts": {
"serve": "webpack serve --mode development",
"build": "webpack --config webpack.config.js",
"nodemon": "nodemon --watch webpack.config.js --delay 500ms --exec npm run build"
},
"devDependencies": {
"autoprefixer": "^10.4.14",
"babel-loader": "^9.1.2",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"html-webpack-plugin": "^5.5.1",
"mini-css-extract-plugin": "^2.7.1",
"nodemon": "^2.0.22",
"postcss": "^8.4.23",
"postcss-drop-empty-css-vars": "^0.0.0",
"postcss-loader": "^7.3.0",
"sass": "^1.62.1",
"sass-loader": "^13.2.2",
"style-loader": "^3.3.2",
"webpack": "^5.81.0",
"webpack-cli": "^5.0.2",
"webpack-dev-server": "^4.13.3"
},
"dependencies": {
"@popperjs/core": "^2.11.7",
"bootstrap": "^5.2.3",
"jquery": "^3.6.4"
}
}
Wondering if I am doing something wrong. Apologies if this is something "a work in progress" and not yet ready to use. It seems to be exactly what I need.
@jaradc Indeed it's something WIP, the postcss-drop-empty-css-vars
package was released as a 0.0.0 as a test (IDK yet if we're going to use this package in Bootstrap, but if needed I can release a 0.1.0).
However, if you still want to test it out with Webpack and Bootstrap, the following seems to work: https://stackblitz.com/edit/github-t4mv5h.
To build it, I followed this path:
- Start from https://github.com/twbs/examples/tree/main/webpack/
- Add
"postcss-drop-empty-css-vars": "^0.0.0",
as a dep dependency in thepackage.json
- In
webpack.config.js
- Comment the
const autoprefixer = require('autoprefixer');
import - Change the
postcss-loader
approach to have the following:
{
// Loader for webpack to process CSS with PostCSS
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-drop-empty-css-vars', {}],
['autoprefixer', {}],
],
},
},
},
When you run the project, click on "Toggle offcanvas" and use the dev tools to check the CSS of the offcanvas, there's no empty --bs-offcanvas-color
.
Thank you Julien-Deramond for such a clear response. I did everything you said and did a text compare before/after to confirm that all 16 empty CSS variables were in-fact removed from the Webpack build. Worked for me!