How to remove unused CSS Loader mappings?
I want to reduce the bloat caused by css loader className mapping when used with SASS @import statement.
Let me explain with an example:
_common.scss
.smallSpacing {
margin: 0 10px;
}
.largeSpacing {
margin: 0 20px;
}
App.scss
@import 'common';
.app {
@extend .largeSpacing;
}
App.js
import styles from './App.scss';
export default const App = () => <div className={styles.app}>Hello!</div>;
As expected, I created the App component and used .app CSS class to style it. Styles are extended from _common.scss. This works fine, but there's an unneeded code bloat.
Because I imported _common.scss, the bundle will include mappings for .smallSpacing and .largeSpacing, even though .smallSpacing was never really used in the component.
This is not a big deal for small apps, but with huge apps that have large sets of common styles, the mappings significantly increase application size.
Is there a way to reduce this overhead?
I'm not sure if I should be asking here or in the CSS-Loader repo. I appreciate your help.
So this was mostly a question for Webpack's CSS Loader. There isn't a dead code elimination algorithm available for CSS modules as of now, but I was still able to reduce the file size significantly
All of the classnames that are meant to be extended should start with % instead of .. The percentage sign means SASS will render it only if it's used.
So in my example above, I would change it to be:
_common.scss
%smallSpacing {
margin: 0 10px;
}
%largeSpacing {
margin: 0 20px;
}
App.scss
@import 'common';
.app {
@extend %largeSpacing;
}
This isn't the definitive solution as some dead code css mappings can still get into your bundle. However this approach will surely help reduce much of your unused mappings.
FTR, this reduced the bundle size of one of my chunks by more than 70%.