Suitable library/plugin that removes unused CSS in React - css

I have been doing some research to find the most suitable CSS library for my React app that would remove (the 96% of my bundle.css) unused CSS.
I realized that most libraries need specific paths to the CSS files to be removed and maybe a whitelist of what should be kept. However, it's trickier in a React app, because there is:
an SCSS file for each custom component
a 3rd party CSS library (antd)
CSS that is runtime-generated
Are there any libraries that allow to do this (hopefully without going through a headache to configure them)?
P.S: I use webpack and mini-css-extract-plugin

Related

Using multiple tailwind stylesheets

I have three tailwind stylesheets that may be included on a single page. Due to the way they're included, it's not possible to set the import order to manage precedence. Is it possible to tell tailwind or postcss to include another stylesheet, from another package, and produce just one "main" stylesheet?
My project is in a monorepo split into three different packages:
my-app
┕ tailwind.css
account-profile
┕ tailwind.css
ui
┕ tailwind.css
The my-app package is the main application, written in Remix, and it imports the others. The account-profile package provides an interface inside the application to handle account management. The ui package is a component library used by both my-app and account-profile. When you navigate to the account profile in the application, it would load all three tailwind.css stylesheets.
Here's a gist to help explain why including multiple tailwind stylesheets causes problems: https://gist.github.com/WriteLock/10d2f632c9fa66e0d9dedfa291ed2f3a
The div with the lg:block class does not appear as it should because of the order that the stylesheets are imported.
The only solutions I've come up with either do not work or are not sustainable:
#fullhuman/postcss-purgecss - Does not work across packages.
Scoped CSS is experimental and tricky to use. Since the UI library will be used in various places, it wouldn't work for that case.
Manually add any necessary tailwind classes to the safelist in the tailwind config in one of the packages, and skip importing the other two.
Add the content paths for account-profile and ui packages to the tailwind config in my-app, i.e.:
content: [
...,
"../account-profile/**/*.{ts,tsx}$",
"../ui/**/*.{ts,tsx}$"
]

How to transform global css into css modules?

I am using react-bootstrap and bootstrap in my nextjs project, thus I have to include the global css:
// _app.js
import 'bootstrap/dist/css/bootstrap.min.css';
The problem is that I load a lot of unused css in every page, thus google lighthouse diminishes my score.
I have tried to purge the unused css, and even thought the score increases, there are still unused styles. I do not need an alert, or a button everywhere. I would like to import only the styles I need in every specific page.
Is there a way to transform global css into css modules so I only import what I need? Maybe some webpack configuration or similar?
I can do it by myself manually splitting the bootstrap code into components. But I would like to know if there is any automatic way of doing it. So I do not have to go through this procedure for all my node_modules that need stylyng.
This is one of Bootstrap's cons — outside of eliminating modules from the core bootstrap.scss file and recompiling a unique version, there isn't a way to do this out of the box. (e.g., remove #import "accordion"; from bootstrap.scss to eliminate accordion styles)
In theory, you could compile each import as a separate .scss file and load the .css only when it's needed but there are some nuance interdependencies and would need consideration to ensure some code doesn't duplicate (e.g., variables, reboot, functions)
Inversely, you most likely are only using a few modules (grid.scss, spacing.scss, buttons.scss) and can eliminate all others.

Tree shaking bootstrap css for specific angular bootstrap modules

Is it possible to specify the css rules for only the angular-bootstrap modules that I'm using in my application? For example I'm only using the dropdown, datepicker and tooltip modules from angular bootstrap. However the entire bootstrap css file is required for these three modules. I'm not using bootstraps css in the rest of my application so I think importing the entire css file is overkill.
Webpack has a built in treeshaking function, which will be the easiest option if your project is already done or way ahead in development.
I have also found this treeshaking that manually compiles Bootstrap and uses Gulp to do the treeshaking in the mean time. I found it to be way harder and possibly outputing the same result, but make yourself comfortable.

How to distribute CSS via NPM

I'm trying to break up my monolithic React app into reusable parts that can be shared with other projects.
I want to extract some generic components (e.g. Button, Header, Dropdown, etc.) into my own little UI library. The problem I'm running into is how to manage the CSS. Right now, my app just has a single stylesheet that takes care of everything.
These are the solutions I have seen:
Embed the CSS styles for each component in the JS for the component itself (CSS in JS).
import or require the CSS files in the JS for the component and use webpack to bundle the CSS file for you.
I really don't love either option. I understand the appeal of co-locating the styles with the component, but I feel like: a) it clutters the component definition, and b) it fights with how CSS works (no more taking advantage of cascading styles since everything is so tightly scoped to the individual component).
And, I can't bring myself to import a CSS file. That just feels so wrong. We're not even writing javascript anymore at that point.
I realize that these aren't exactly popular opinions, but is there a 3rd option that I'm missing for getting a good old fashioned CSS file from an NPM module that I can just drop in my HTML and use? Ideally one that doesn't involve copy/pasting it from node_modules. :)
Thanks to the tip from #EmileBergeron I found the PostCSS import plugin. It can find and inline stylesheets in node_modules and in your own code.
So, my workflow will be:
npm install my-ui-library
Import the React components you want to use into your JS files import { Button } from 'my-ui-library'
Import the corresponding stylesheets into your CSS files #import 'my-ui-library/Button.css'
That way I'm importing CSS into CSS and JS into JS which feels a lot more natural to me. It might also make sense to just have one stylesheet for all components instead of breaking it up per-component, but that's a detail I can figure out later.
Then, I just need to add PostCSS into my build system to inline everything which has been pretty simple in testing.

AngularJS With Multiple Components and CSS

As I become more familiar with Angular, and the vast number of modules out there for making an application really shine, I am also becoming overwhelmed at understanding the basic logic of CSS overloading, and how to manage the imports to get the desired behavior.
For instance, I have pulled the following libraries into my Angular application; Boostrap, Bootcards, boostrap-select, font-awesome, and some custom bootstrap-wizard libraries for a modal tab-based wizard.
All of these libraries require being defined in the index.html page of my Angular app (both the CSS files the JS files). How do you manage the desired behaviors so that one components styles don't override another components styles? What are the best practices around bringing in multiple components and using them in an Angular app, without negatively affecting the applications previous behaviors?
You have 3 choices:
Place more important CSS files AFTER less important ones so the more important override when both have same attribute names.
Manually go in stylesheet and change attribute names.
Instead of including the stylesheet in index, include it in your html file

Resources