Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instructions to switch from react-css-modules #108

Closed
apennell opened this issue Jul 5, 2017 · 10 comments
Closed

Instructions to switch from react-css-modules #108

apennell opened this issue Jul 5, 2017 · 10 comments
Labels

Comments

@apennell
Copy link

apennell commented Jul 5, 2017

It would be great if there was a section with the steps required to switch from using react-css-modules to babel-plugin-css-modules, since this is now recommended over that package.

I built out an app using create-react-app and successfully implemented react-css-modules. There's a note in the react-css-modules Readme about using babel-plugin-react-css-modules instead, but it wasn't clear that it's no longer maintained or recommended by @gajus so I went with the original. After running into problems with Jest testing, I learned in the issue addressing my problem that @gajus doesn't recommend using it, so I'm trying to switch to this one.

I figured that I could just change the setup of my components that worked with react-css-modules, but it doesn't work.

My React components:

// App.js
import './App.css';
import Button from './components/Elements/Button/Button.jsx';

class App extends Component {
    render() {
        return (
            <Button size="large">
                Working Button!
            </Button>
        );
    }
}

export default App;
// src/components/Elements/Button/Button.jsx
import './Button.css';

export const Button = ({children, size, isFullWidth}) => {
    return (
        <button styleName={`${size}Size ${isFullWidth ? "block" : ""}`} >
 	    {children}
 	</button>
    );
}

export default Button;

To enable react-css-modules in my create-react-app, I modified my webpack.config to have:

...
{
    test: /\.(js|jsx)$/,
    include: paths.appSrc,
    loader: require.resolve('babel-loader'),
    options: {
        cacheDirectory: true,
        plugins: [
            'react-css-modules'
        ]
    },
},
{
    test: /\.css$/,
    use: [
        require.resolve('style-loader'),
        {
            loader: require.resolve('css-loader'),
            options: {
                importLoaders: 1,
                modules: true,
                localIdentName: '[name]__[local]___[hash:base64:5]&sourceMap&-minimize',
            },
        },
        ...
    ]
}
...

I've looked at several issues related to this, including issue #5 and issue #82 , and it looks like babel settings need to be updated, but I've been unsuccessful in my attempts so far.

@gajus gajus added the question label Jul 5, 2017
@apennell
Copy link
Author

I should have been more clear about what's not working. The CSS stylesheets aren't being used when rendered. The styleNames are correctly translating to classes with the additional scope text on the generated name, it compiles with a success message when I make a change to the CSS and save it, and there are no error messages. However, my stylesheets are nowhere to be found in the browser and it uses the user agent stylesheet instead.

What am I missing from my configuration?

@gajus
Copy link
Owner

gajus commented Jul 13, 2017

However, my stylesheets are nowhere to be found in the browser and it uses the user agent stylesheet instead.

Assuming that you are not using styles-loader (which I don't recommend in production), you need to <link /> your generated CSS in the HTML. By the sound of it, you have not done it.

@apennell
Copy link
Author

@gajus Doesn't HTML Webpack Plugin cover that? It wasn't a problem when I was using React CSS Modules or CSS Modules, only when I tried to switch to babel-plugin.

@apennell
Copy link
Author

apennell commented Jul 13, 2017

I followed the configuration in this tutorial, which seems quite comprehensive: https://clever.ly/blog/2017/06/16/css-modules-in-react/

I added a .babelrc, which solved a missing prop styleName in div issue that I had in one place but didn't resolve the CSS problem

{
  "presets": [
    "react-app"
  ],
  "plugins": [
    "transform-react-jsx",
    "transform-runtime",
    "babel-plugin-react-css-modules"
  ]
}

With my setup matching that one and, as far as I can tell, the demos in this project, the stylesheets aren't being fetched. This is a screen shot that should have basic styling (looks pretty much like the initial create react app does). You can see that the classes are being generated but not the styles.
screen shot 2017-07-13 at 1 52 34 pm

Is there a specific reason that you don't recommend using style-loader with babel-plugin-react-css-modules, or is that a general practice? I'm using an ejected create-react-app, which has a webpack.config.dev.jsand webpack.config.prod.js. This is the css part of the prod config with comments they wrote:
screen shot 2017-07-13 at 1 55 12 pm

I don't see a link to the CSS in the demo HTML file. I don't think this is really an option for me anyway, as I'm building a component library package to use in a separate application.

@angelikatyborska
Copy link

@apennell I was using your example as a hint on how to configure style-loader to work with this plugin and I noticed a small issue with your configuration. Namely:

localIdentName: '[name]__[local]___[hash:base64:5]&sourceMap&-minimize',

But the default GenerateScopedNameConfigurationType used by this project is equal to [path]___[name]__[local]___[hash:base64:5], so the part [path]___ is missing in your configuration.

@robwierzbowski
Copy link

robwierzbowski commented Oct 5, 2017

I'm having the same issue — my generated styles aren't linked anywhere. @apennell, did you ever figure out your issue?

[edit/solved] Turns out the styles were being injected into the head of the document, but I hadn't configured css-loader fully. My working Webpack 3 config looks like:

{
  test: /\.css$/,
  exclude: /node_modules/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        modules: true,
        // This matches the babel plugin's setting
        localIdentName: '[path]___[name]__[local]___[hash:base64:5]', 
      },
    },
  ],
},

@domehead100
Copy link
Contributor

In my experience, it's important that babel-plugin-react-css modules comes first in the list of plugins.

I noticed a comment that I left for myself in the past in my .babelrc. This has been working great for months when using .js/.jsx and babel (don't have it working with typescript):

// the react-css-modules plugin should be first in the list of plugins
{
"presets": [["env", { modules: false}]],
"plugins": [
["react-css-modules", { "generateScopedName": "[name]__[local]" }],
... other plugins ...
]
}

@apennell
Copy link
Author

apennell commented Oct 5, 2017

Thanks for the input and potential fixes @angelikatyborska @robwierzbowski @domehead100! I wasn't able to get it working back when I was building this and, if I recall correctly, I ended up going back to just using the basic css-modules. I'm no longer working at the company I was using this for so I can't try these fixes out now, but I'll revisit this thread if I get a chance to implement css modules at my new company! 😁

@HofmeisterAn
Copy link

@robwierzbowski Thanks, it looks like the localIdentName must match the generated name from babel-plugin-react-css-modules. The documentation didn't help me there.

@gajus gajus closed this as completed Mar 10, 2018
tau9 pushed a commit to tau9/babel-plugin-react-css-modules that referenced this issue May 18, 2018
Adding documentation as requested in gajus#108 (comment)
gajus pushed a commit that referenced this issue May 18, 2018
@davidalejandroaguilar
Copy link

If anyone is looking to use this in a create-react-app application, this is what I needed to add to make it work:

          // Process JS with Babel.
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
              plugins: ['babel-plugin-react-css-modules'] // Important
            }
          },

// ...

{
            test: /\.css$/,
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                  modules: true,
                  localIdentName: '[path]___[name]__[local]___[hash:base64:5]' // Important
                }
              },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants