React + Reactstrap + CSS Modules + Webpack
Asked Answered
P

2

14

I've been looking how I can combine the following : ReactJS + ReactStrap and CSS-Modules (react-css-modules and/or boostrap-css-modules), however, I can't seem to piece the three modules together to achieve the desired effect (or find any help online).

The idea behind this is to have the ReactStrap elements available, i.e. :

import React from 'react';
import { Button } from 'reactstrap';

export default (props) => {
  return (
    <Button color="danger">Danger!</Button>
  );
};

but also allow me to use CSS-Modules for the end result being something similar to :

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './mybutton.css';

class Test extends React.Component {
    render () {
        return <Button color='danger' styleName='myButton'>Danger</div>;
    }
}

export default CSSModules(Table, styles);

where mybutton.css could be something like :

.myButton {
  composes: btnPrimary from "bootstrap-css-modules/css/buttons.css";
  background-color: dodgerblue;
  border-color: dodgerblue;
}

I'm also using Webpack so I don't even know where to begin with regards to using it with Webpack.

Edit :

The way I am using this is as follows :

npm install --save [email protected]

npm install --save reactstrap react-addons-transition-group react-addons-css-transition-group react react-dom

npm install --save bootstrap-css-modules

Here is my webpack config

const webpack = require('webpack');

const path = require('path');
const HtmlwebpackPlugin = require('html-webpack-plugin');

const ROOT_PATH = path.resolve(__dirname);

module.exports = {
    devtool: process.env.NODE_ENV === 'production' ? '' : 'source-map',
    entry: [
        path.resolve(ROOT_PATH, 'app/src/index'),
    ],
    module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.jsx?$/,
                loader: process.env.NODE_ENV === 'production' ? [] : ['eslint-loader'],
                include: path.resolve(ROOT_PATH, 'app'),
            },
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                query: {
                    presets: ['react'],
                },
            },
            {
                test: /\.scss$/,
                loaders: ['style-loader', 'css-loader', 'sass-loader'],
            }],
    },
    resolve: {
        extensions: ['.js', '.jsx'],
    },
    output: {
        path: process.env.NODE_ENV === 'production' ? path.resolve(ROOT_PATH, 'app/dist') : path.resolve(ROOT_PATH, 'app/build'),
        publicPath: '/',
        filename: 'bundle.js',
    },
    devServer: {
        contentBase: path.resolve(ROOT_PATH, 'app/dist'),
        historyApiFallback: true,
        hot: true,
        inline: true,
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlwebpackPlugin({
            title: 'testapp',
        }),
    ],
};

Thanks

Paschal answered 30/7, 2017 at 19:15 Comment(3)
I tested the code, it works for me, could you show you webpack configuration of css-loader?Oulman
I use similar setup webpack, react-css-modules, css-modules, react-toolbox thus I think that I could help here because probably I've had to solve the same problems. Please describe what's your main problem is and share your webpack configuration if it's possible.Asyut
I am having the exact problem as explained here: #47521196 @hinok Can you please have a look into mine if possible? Thank you!Instrument
W
5

@tehOwner ...phew this question was a doozy. I think I accomplished what you were trying to do.

I created a sandbox that can be found here.

DEMO

Basically, you need this npm module in your project to be able to assign multiple CSS classes to a react component using the className property.

And setup your component with a structure that resembles the below

import React, { Component } from 'react';
import { Button } from 'reactstrap';
import CSSModules from 'react-css-modules';
import styles from './MyDangerButton.css';
import cn from 'classnames';

class MyDangerButton extends Component {
  render() {
    const myFancyDangerButton = cn({
      btn: true,
      'btn-danger': true,
      MyDangerButton: true
    });

    return (
      <div>
        <h1>My Fancy Danger Button!</h1>
        <Button className={myFancyDangerButton}>Danger Button</Button>
      </div>
    );
  }
}

export default CSSModules(MyDangerButton, styles);

🍺 cheers Chris

Wonderstricken answered 10/12, 2017 at 9:17 Comment(0)
C
1

The newest solution is to upgrade the react-script by using:

 npm upgrade --latest react-scripts

It supports the CSS module so you don't need to config anything. What need to do is add .module to the CSS file: from './mybutton.css' to './mybutton.module.css'. And change the import as well:

import styles from './mybutton.module.css';

Using this, we don't need to perform

npm run eject 

any more.

Candide answered 15/12, 2018 at 8:11 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.