How to transform global css into css modules? - css

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.

Related

Suitable library/plugin that removes unused CSS in React

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

Using two style.css for the same react app

I am trying to use two snippets as components from bootsnipp, and each snippet has its own css. i tried to put them both in the style.css, but it ended up damaging one component for the other to look fine.
I'm thinking about how to use both these styles.css, since in the index.js i can only import style.css.
can i use router to use multiple pages, and import style.css in the second page? but wouldn't that mean i'll have to use the second page as app.js, which is called only once in react? this is kind of confusing me.
EDIT: can I put the css of one component in another css file, and then import it INSIDE that component instead of index.js?
it doesn't bother me by the way whether i put that component inside index.js or not; in fact, I'm not going to use it there.
I would say you need to deal with the global namespace issue. You could create two components with its own css file.
Then add a unique className to stop collisions.
The benefit here is that you could also enable code spitting, so you would only load html/css/js when you need it (see React.lazy).
—-
By trying to load two styles in different times or manners you will still have the same issue of conflicting styles.

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.

How to use less mixins in meteor with #import and not get multiple definitions

in my current meteor app I have split the less declarations in one file per Controller (iron-router). I have a common file - where I have defined some mixins - which is imported in each less file. My problem is that the classes are imported multiple times in each route.
The file structure is:
mixins.import.less (new names, reference http://docs.meteor.com/#less)
.grid-container {
// something
}
postList.less
#import (once) url('/client/views/mixins.import.less');
postDetail.less
#import (once) url('/client/views/mixins.import.less');
Then in the Chrome inspector I found duplicated everything I have written in mixins.import.less. Is it possible to avoid this double import?
Assuming you want the mixin code at least once in your compiled css (perhaps not, some just want them as mixins, not classes in the css code), then make sure you set it to bring in the "mixins.import.less" file all by itself. Then for all your dependent files using it, do this:
"postList.less", "postDetail.less", etc.
#import (reference) url('/client/views/mixins.import.less');
The (reference) option has been available since LESS 1.5, and will only bring in the code for reference purposes to be used in the LESS file, but will not itself output any css.
Meteor bundles css and js/html resources all together as a single css and a single js file in production.
In development, they are individually served, but still at the same time, during initial page load (first ever request to server)
For less files, a css file is created for each (during development). Since you are importing, what Meteor basically does is create each corresponding css file that each contain the import individually.
And when they are served to the client all together (take a look at the head section of the generated html), you end up with that many copies of the imported style declarations.
Therefore, due to this bundling behaviour of Meteor, you can just keep one copy of your less mixins in a less file, and not import at all, since they are going to be served to the client in CSS form anyway.
Also, it is possible to trick Meteor into bypassing as described in the unofficial meteor faq:
... you can change the extension of the less files to be imported from .less to .lessimport and then change your #import file.less to #import file.lessimport. This will prevent the less compiler from automatically trying to compile all your import files independently, yet still let you use them ...

How to modularize one LESS stylesheet into multiple stylesheets?

I am looking to take my styles.less file (which currently contains 3000 lines of stylesheet code for my entire site) and break it apart into multiple stylesheets, i.e. navigation.less, buttons.less, footer.less, etc.
I suppose I would then #import all of these individual stylesheets into a master stylesheet, such as all.less which would compile/minify down to all.css
One issue I am experiencing with breaking this styles up into individual sheets is that variable references are broken. So for example, if I port over my buttons CSS to buttons.less, my buttons CSS contains references to LESS variables that are defined in styles.less. How do I fix this issue?
Is there a better approach to modularizing my CSS code with LESS? 3000 lines of LESS code is getting completely unmanageable for one file and I need to break it up.
Most people handle this by having two particular files, something like variables.less and mixins.less.
Then if these are needed in the modules, you use import-once instead of just import (for versions prior to the at present upcoming 1.4; at which time import by default will act as import-once). You use this in both the module files and in your all.less. That way when they are all brought together inside the all.less file, the imports only occurs once at the top of the final file, and not for each individual module file loaded.

Resources