0

I've been using css modules with sass in a react library that I want to be consumed by other libraries.

I have the following code for a component:

import React, { Component } from 'react';
import styles from './FormInput.scss';
import cs from 'classnames';
import { Input, Label } from '../..';

export const FormInput = ({ invalid, required }) =>
    <div
      className={styles['form-input']}
    >
      <Label htmlFor={this.id} invalid={invalid} required={required}>
        {label}
      </Label>
    </div>

In development the css module classes are there in the rendered markup:

<div class="form-group FormInput__form-input___2PK4N">
  <label for="ctrl1" class="">Form Input</label>
</div>

But when I import the library, they are not there:

<div class="form-group">
  <label for="ctrl1" class="">label</label>
</div>

If I log the styles variable from import styles from './FormInput.scss';

It is /static/media/Banner.ee4182d1.scss which seems wrong.

I am using webpack and in my webpack.dev.config.js my loader looks like this:

  {
    test: /\.css$/,
    exclude: /node_modules/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      // Could also be write as follow:
      // use: 'css-loader?modules&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
      use: [
        {
          loader: 'css-loader',
          query: {
            modules: true,
            localIdentName: '[name]__[local]___[hash:base64:5]'
          }
        },
        'postcss-loader'
      ]
    })
  },
  {
    test: /\.scss$/,
    exclude: /node_modules/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',

      // Could also be write as follow:
      // use: 'css-loader?modules&importLoader=2&sourceMap&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader'
      use: [
        {
          loader: 'css-loader',
          query: {
            modules: true,
            sourceMap: true,
            importLoaders: 2,
            localIdentName: '[name]__[local]___[hash:base64:5]'
          }
        },
        'sass-loader'
      ]
    })
  }

And in webpack.prod.config.js looks like this:

  {
    test: /\.css$/,
    loader: ExtractTextPlugin.extract(
      Object.assign(
        {
          fallback: require.resolve('style-loader'),
          use: [
            {
              loader: require.resolve('css-loader'),
              options: {
                importLoaders: 1,
                minimize: true,
                sourceMap: true
              }
            },
            {
              loader: require.resolve('postcss-loader'),
              options: {
                ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                plugins: () => [
                  require('postcss-flexbugs-fixes'),
                  autoprefixer({
                    browsers: [
                      '>1%',
                      'last 4 versions',
                      'Firefox ESR',
                      'not ie < 9' // React doesn't support IE8 anyway
                    ],
                    flexbox: 'no-2009'
                  })
                ]
              }
            }
          ]
        },
        extractTextPluginOptions
      )
    )
    // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
  },
  {
    test:/\.scss$/,
    use:ExtractTextPlugin.extract({
      fallback: 'style-loader',
      use: [
        {
          loader:'css-loader',
          options:{
            modules: true,
            importLoaders: 1,
            minimize: true,
            sourceMap: true
          }
        },
        {
          loader:  'sass-loader',
        },
        {
          loader:  'postcss-loader',
          options:{
            plugins:function(){
              return [autoprefixer]
            }
          }
        }
      ]
    })
  }

I can see that there are scsss files generated as part of the output but why have the classes been stripped?

dagda1
  • 26,856
  • 59
  • 237
  • 450

1 Answers1

1

You dont have modules enabled in your prod css-loader

        {
          loader: require.resolve('css-loader'),
          options: {
            importLoaders: 1,
            minimize: true,
            sourceMap: true,
            modules: true // NEED TO ADD THIS
          }
        },
alechill
  • 4,274
  • 18
  • 23
  • Not here in the first rule of the whereas you have them enabled in the dev version for this same rule... `{ test: /\.css$/, loader: ExtractTextPlugin.extract( Object.assign( { fallback: require.resolve('style-loader'), use: [ { loader: require.resolve('css-loader'), options: { importLoaders: 1, minimize: true, sourceMap: true } },` – alechill Jul 06 '17 at 14:42
  • No probs. There also used to be a bug in ExtractTextPlugin when webpack 2 was launched that would not accept loaders in the `use` that specified `options` instead of `query` as loader options. You appear to be mixing these in the various configs - it should be sorted now as it was fixed, but it may be worth making sure all these are consistent across your configs (options is the up to date version an query is deprecated), and that the plugin is up to date – alechill Jul 06 '17 at 14:56
  • ok I have everything working in as far as the classes are now on the object, e.g. FormInput now has a class `FormInput__form-input___2PK4N` but the styles themselves are not there. Is there something else I need to do? – dagda1 Jul 06 '17 at 16:05