CSS modules for react

546 views Asked by At

I am trying to add a css module in the login component. For now, I have a style.css stylesheet in the folder src/styles and it is loading global styles. But now, I want to customize the login component, so I added a login.css file into componentes/login:

.button {
  background-color: black;
}

and my LoginPage.js component is:

import React from 'react';
import styles from './Login.css';

class LoginPage extends React.Component {
  render() {
    return (
      <div className="jumbotron col-md-6 col-md-offset-3">
        <div className="container">
          <form name="form">
            <div className="form-group">
              <label htmlFor="username">Username</label>
              <input type="text" name="username" className="form-control" required />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input type="password" name="password" className="form-control" required />
            </div>
            <div className="form-group">
              <button className="btn btn-primary">Login</button>
            </div>
          </form>
        </div>
      </div>
    );
  }
}

export default LoginPage;

But my webpack is showing me the following errors:

src\components\login\LoginPage.js (2/2)
  ✖  2:20  Parse errors in imported module './Login.css': Unexpected token . (1:1)  import/namespace
  ✖  2:20  Parse errors in imported module './Login.css': Unexpected token . (1:1)  import/default
  !  2:20  Parse errors in imported module './Login.css': Unexpected token . (1:1)  import/no-named-as-default
  !  2:20  Parse errors in imported module './Login.css': Unexpected token . (1:1)  import/no-named-as-default-member

This is my webpack.config.js

import webpack from 'webpack';
import path from 'path';

export default {
  debug: true,
  devtool: 'inline-source-map',
  noInfo: false,
  entry: [
    'eventsource-polyfill', // necessary for hot reloading with IE
    'webpack-hot-middleware/client?reload=true', //note that it reloads the page if hot module reloading fails.
    path.resolve(__dirname, 'src/index')
  ],
  target: 'web',
  output: {
    path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
    publicPath: '/',
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'src')
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  module: {
    loaders: [
      {test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
      {test: /(\.css)$/, loaders: ['style', 'css']},
      {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
      {test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
      {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
      {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
    ]
  }
};

for the last, I had a problem when I tried:

 <div className="form-group">
   <button className=`${styles.button}`>Login</button>
 </div>

src/components/login/LoginPage.js: JSX value should be eith
er an expression or a quoted JSX text (19:32)

How to I set up css modules for react correctly?

EDIT:

After the discussion below, I fixed the error loading the class:

<div className="form-group">
  <button className={styles.button}>Login</button>
</div>

Now, the css is loaded but webpack keeps showing the same errors and warnings.

2

There are 2 answers

0
alechill On BEST ANSWER

The problem is that you are attempting to import actual CSS into your JS without having gone through the transformation into ICSS first

Your webpack loader simply needs to be set up for CSS modules. To do this you need to add modules and optionally a template for the localised classnames.

Change your CSS loader to:

{test: /(\.css)$/, loader: 'style!css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'}

This will tell webpack to precompile the CSS into ICSS before the import, which becomes just a JS object telling it how to map your button class name into the dynamic localised class name string LoginPage__button___ab123

You should then add classNames via this imported object as you were first trying, although the interpolated string is not needed unless adding multiple classes

<button className={styles.button}>Login</button>
9
yeze322 On

According to the error hint, you can write this way:

<div className="form-group">
  <button className={styles.button}>Login</button>
</div>

Because strings quoted by `something ${var}` are treated as variables, which need extra calculation before parsed into ES5 js code (while string looks like 'rawString' or "rawString2" needn't).