An open API service indexing awesome lists of open source software.

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

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',
}),
],
}

```