https://github.com/markmur/webpack-css-tree-shaking-example
Working example of tree shaking CSS modules
https://github.com/markmur/webpack-css-tree-shaking-example
css css-modules modules tree-shaking webpack
Last synced: 9 months ago
JSON representation
Working example of tree shaking CSS modules
- Host: GitHub
- URL: https://github.com/markmur/webpack-css-tree-shaking-example
- Owner: markmur
- Created: 2019-12-05T10:53:38.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-05T02:22:34.000Z (about 3 years ago)
- Last Synced: 2025-04-06T21:05:56.037Z (10 months ago)
- Topics: css, css-modules, modules, tree-shaking, webpack
- Language: JavaScript
- Homepage:
- Size: 345 KB
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# CSS Modules with Tree Shaking
This repo shows how to use css-modules (with `css-loader`) and tree shake any used imports from _both_ the outputted CSS file as well as the js bundle.
## Quick Reference
You will need to have the following dependencies installed:
```sh
yarn add @fullhuman/postcss-purgecss \
css-loader \
cssnano \
mini-css-extract-plugin \
node-sass \
postcss-loader \
postcss-scss \
sass-loader \
style-loader
```
Here is the webpack config for quick reference:
```js
/* eslint-env node */
const path = require('path')
const glob = require('glob')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const entry = filename => [path.resolve(__dirname, filename)]
module.exports = {
mode: 'production',
entry: entry('src/index.js'),
output: {
filename: '[name].js',
path: path.resolve('dist'),
},
resolve: {
extensions: ['.js'],
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.s?css$/,
exclude: /node_modules/,
use: [
// Extract the css to file
MiniCssExtractPlugin.loader,
{
loader: require.resolve('css-loader'),
options: {
// Enable CSS modules
modules: {
// Specify format of class names
localIdentName: '[local]_[hash:base64:5]'
},
}
},
{
loader: require.resolve('postcss-loader'),
options: {
indent: 'postcss',
syntax: 'postcss-scss',
plugins: () => [
// Purge unused CSS
require('@fullhuman/postcss-purgecss')({
content: glob.sync('src/**/*.{js,jsx}', { nodir: true }),
extractors: [
{
extractor: class {
static extract(content) {
// NOTE: this regex needs work. At the moment it simply matches any keyword that matches a class name. If you were to have a class name "alert" and create a react component with a text body that has the word "alert" in it, it would result in the alert className being unnecessarily imported.
return content.match(/\w+/g) || [];
}
},
extensions: ['js', 'jsx' ]
}
]
}),
require('cssnano')
]
}
},
require.resolve('sass-loader')
],
},
],
},
plugins: [
// Extract all css into a separate file
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
}
```