title: Using string class names in React with css-loader and Webpack
body: <p>I was following a few tutorials on how to set up internal sass/scss/css support for React in Webpack. I finally got something I'm happy with, using <code>HtmlWebpackPlugin</code> to generate the <code>index.html</code> based on a template, <code>sass-loader</code>, <code>typings-for-css-modules-loader</code> (a <code>css-loader</code> wrapper to deal with css modules in typescript), and <code>MiniCssExtractPlugin</code>, to create a separate css file in my built <code>dist</code> folder. My configuration works like this:</p>
  
  <pre><code>module: {
    rules: [
  
      ...
  
      { test: /\.(sa|sc|c)ss?$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {}
          },
          {
            loader: 'typings-for-css-modules-loader',
            options: {
              modules: true,
              namedExport: true,
              camelCase: true
            }
          },
          'sass-loader'
        ]
      }
    ]
  }
  </code></pre>
  
  <p>This setup works when I'm importing my css classes in my React components as objects:</p>
  
  <p><code>hello.css</code></p>
  
  <pre><code>.foo {
      color: #5df7ff;
  }
  </code></pre>
  
  <p><code>hello.tsx</code></p>
  
  <pre><code>import * as React from 'react';
  
  import { foo } from './hello.css';
  
  export interface HelloProps {
    compiler: string;
    framework: string;
  }
  
  export const Hello = (props: HelloProps) =&gt;
    &lt;h1 className={foo}&gt;Hello: {props.compiler} and {props.framework}!!!&lt;/h1&gt;; // This works: text is colored correctly
  </code></pre>
  
  <p>The problem arises when I want to use string class names in the React component, as such (same css as before):</p>
  
  <p><code>hello.tsx</code></p>
  
  <pre><code>import * as React from 'react';
  
  import './hello.css';
  
  export interface HelloProps {
    compiler: string;
    framework: string;
  }
  
  export const Hello = (props: HelloProps) =&gt;
    &lt;h1 className="foo"&gt;Hello: {props.compiler} and {props.framework}!!!&lt;/h1&gt;; // This does not work: text is not colored
  </code></pre>
  
  <p>I assume this is because the Webpack loaders aren't 'smart' enough to correctly resolve the string class names in the React DOM: the loaders do not map the string class names to the hashed ones produced by css-loader.</p>
  
  <p>I understand that using string css class names in React is not the idiomatic way to include css classes: ideally you would have one single complete css class per component using css modules which you would import as in the first example. </p>
  
  <p>The problem arises however when using external UI component libraries (e.g. Ant Design, Semantic UI) which seem to reference their own css string classes.</p>
  
  <p>This puts me off using these external libraries.</p>
  
  <p>Example from using <code>antd</code> (Ant Design):</p>
  
  <p><code>anthello.tsx</code></p>
  
  <pre><code>import React from 'react';
  import Button from 'antd/lib/button';
  import 'antd/es/button/style/index.css';
  
  export interface HelloAntProps {
    message: string;
  }
  
  export const HelloAnt = ({ message }: HelloAntProps ) =&gt; {
    return (
      &lt;div&gt;
        &lt;h1&gt;Hello {message}&lt;/h1&gt;
        &lt;Button type="primary"&gt;Test&lt;/Button&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p>generated css file using the loader stack:</p>
  
  <pre><code>._3WAJv754FZTMKDXGocE913 { /* This class corresponds to the Ant Design ant-btn class */
    line-height: 1.5;
    display: inline-block;
    font-weight: 400;
    text-align: center;
    ...
  </code></pre>
  
  <p>and the css classes which are looked for in the actual DOM:</p>
  
  <pre><code>&lt;button type="button" class="ant-btn ant-btn-primary"&gt;&lt;span&gt;Test&lt;/span&gt;&lt;/button&gt; 
  &lt;!-- This does not work, as the only classes present in the css are the hashed ones generated by css-loader --&gt;
  </code></pre>
  
  <p>I wouldn't know how else to import these libraries and pack them using Webpack into a single css bundle without getting this to work.</p>
  
  <p>Am I missing something?</p>
  
  <p><strong>tl;dr</strong></p>
  
  <p>Is there any way to get css class strings to be correctly resolved with <code>css-loader</code> in the React DOM via some Webpack loader? Is there any workaround I'm missing?</p>