Pietro Coelho
Pietro Coelho

Reputation: 2072

CSS Modules composes not working

I'm trying to setup css modules with postcss + cssnext. It all seems to be working fine, except that the composes keyword is simply not working. The rule vanishes when the bundle is compiled.

Here's my webpack config file:

'use strict'

const path = require('path')
const webpack = require('webpack')
const HtmlPlugin = require('html-webpack-plugin')

module.exports = {
    devtool: 'inline-source-map',
    entry: [
        'react-hot-loader/patch',
        'webpack-dev-server/client?http://localhost:3000',
        'webpack/hot/only-dev-server',
        path.join(__dirname, 'src', 'index')
    ],
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name]-[hash].js',
        publicPath: ''
    },
    plugins: [
        // new DashboardPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(),
        new HtmlPlugin({
            title: 'Github App',
            template: path.join(__dirname, 'src', 'html', 'template-dev.html')
        })
    ],
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            include: /src/,
            use: 'babel-loader'
        }, {
            test: /\.css$/,
            exclude: /node_modules/,
            include: /src/,
            use: ['style-loader', {
                loader: 'css-loader',
                options: {
                    modules: true,
                    importLoaders: 1,
                    localIdentName: '[local]--[hash:base64:5]'
                }
            }, {
                loader: 'postcss-loader',
                options: {
                    ident: 'postcss'
                }
            }]
        }]
    },
    resolve: {
        alias: {
            Src: path.join(__dirname, 'src'),
            Components: path.join(__dirname, 'src', 'components')
        }
    }
}

I'm using style-loader for this dev environment so I can use hot reloading. The css file is being imported like this: import './app.css' app.css:

:global{
    .app {
        float: left;
        padding: 10px;
        width: 100%;
    }
}

.className {
    color: green;
    background: red;
}

.otherClassName{
    composes: className;
    color: yellow;
}

this results in:

enter image description here

My postcss.config.js file:

module.exports = {
    plugins: {
        'postcss-import': {},
        'postcss-cssnext': {
            browsers: ['last 2 versions', '> 5%']
        },
        'postcss-nested': {}
    }
}

Am I missing something to get composes to work?

Upvotes: 2

Views: 7110

Answers (1)

smallbutton
smallbutton

Reputation: 3437

Looks like this is fine: The implementation of webpack's css_loader is to add both classes when exporting the styles (see https://github.com/webpack-contrib/css-loader#composing)

This also makes more sense, since it will ultimately render out less CSS code. Try importing the styles and apply them to an HTML node and you will see it should receive both classes.

In your example it would have done something like:

exports.locals = {
  className: 'className-2yqlI',
  otherClassName: 'className-2yqlI otherClassName-1qAvb'
}

So when you do:

import styles from '../app.css'

// ...

<div className={styles.otherClassName} />

The div gets both classes.

Upvotes: 1

Related Questions