babel-plugin-react-css-modules icon indicating copy to clipboard operation
babel-plugin-react-css-modules copied to clipboard

Trouble using dynamic/generated scss class names in styleName (Could not resolve the styleName)

Open jesperjohansson opened this issue 6 years ago • 13 comments

I use the plugin postcss-scss together with sass-loader in Webpack 4. It works if the css class names are global and i use the normal className prop instead of styleName. I import the .scss file at the top of my component.

The error I get is: Could not resolve the styleName 'tablet-6'.

SCSS code (Column.scss):

@import '../../../utils.scss';

.column {
  width: 100%;
}

@each $breakpoint, $value in $breakpoints {
  @for $i from 1 through $gridColumns {
    .#{$breakpoint}-#{$i} {
      width: #{$i * $gridColumnsWidth + %};
    }
  }
}

JS code (Column.js)

import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import './Column.scss'

const Column = props => (
  <div
    styleName={classNames(
      'column',
      Object.keys({
        mobile: props.mobile,
        tablet: props.tablet,
        desktop: props.desktop,
      }).map(key => props[key] && `${key}-${Number(props[key])}`),
    )}
  >
    {props.children}
  </div>
)

Column.propTypes = {
  children: PropTypes.node.isRequired,
  mobile: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  tablet: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  desktop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
}

Column.defaultProps = {
  mobile: undefined,
  tablet: undefined,
  desktop: undefined,
}

export default Column

jesperjohansson avatar Mar 04 '18 18:03 jesperjohansson

Im having the same problem on Webpack 3. This is how my .babelrc looks like.

.babelrc

{
  ...
  "plugins": [
    ...
    ["react-css-modules", {
      "filetypes": {
        ".scss": {
          "syntax": "postcss-scss",
          "plugins": [
            "postcss-at-rules-variables",
            "postcss-each",            
            "postcss-nested"
          ]
        }
      },
      "removeImport": true,
      "webpackHotModuleReloading": true,
      "generateScopedName": "[local]__[hash]"
    }]
  ]
}

My project has SSR, which might be the problem.

Weird thing is when I console.log the scss file, it shows that I apparently have a class that I want to use but when I use styleName in a component, I get the same error.

jiyonghong avatar Mar 05 '18 14:03 jiyonghong

We have the same problem in a Next.js project

Any ideas how to fix this?

pixelkritzel avatar Apr 03 '18 12:04 pixelkritzel

I get the same error

vxow avatar Apr 27 '18 05:04 vxow

I have the same issue. Although I don't fully understand why, but this (https://github.com/postcss/postcss-nested#preserveempty) worked for me.

            "plugins": [
              [
                "postcss-nested", {
                  "preserveEmpty": true
                }
              ]
            ]

And the previous "lost" nested selector was NOT empty at all.

t47io avatar Jun 02 '18 05:06 t47io

I think that it's related to https://github.com/postcss/postcss-scss/issues/90 so I suspect that postcss-scss cannot handle things like .#{$breakpoint}-#{$i} {.

hinok avatar Jun 04 '18 10:06 hinok

@hinok postcss-scss handles interpolation in selector. That issue is about much more complex cases (string in interpolation in string). Also, that issue should throw a syntax error. Here is a logical error, not parsing error.

ai avatar Jun 21 '18 19:06 ai

i have the same issue with a sass generated grid system and webpack 4

Error: "Could not resolve the styleName 'aco-grid-col-12'."

module.exports = {
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                include: path.resolve(__dirname, 'src'),
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            plugins: [
                                ['react-css-modules', {
                                    generateScopedName: '[name]-[local]',
                                    filetypes: {
                                        '.scss': {
                                            syntax: 'postcss-scss',
                                        },
                                    },
                                }],
                            ],
                        },
                    },
                    'eslint-loader',
                ],
            },
$total-columns: 12;

@for $i from 1 through $total-columns {
  $width: ($i * 100% / $total-columns);

  .aco-grid-col-#{$i} {
    flex-basis: $width;
    max-width: $width;
    @extend .aco-grid-col;
  }
}

jzilg avatar Jul 10 '18 10:07 jzilg

i have the same error and be blocked

lsner avatar Oct 22 '19 09:10 lsner

+1 ,scss Interpolation is not working,but className is work

$a: '.container__inner4';

.container {
  color: red;

  & > .test {
    color: white;

    @include ellipsis();
  }

  &__inner {
    font-size: 30px;
  }
}

#{$a} {
  color: red;
}
import Style from './index.module.scss'

console.log(Style)

class AX2 extends React.Component {
  render () {
    const { message } = this.props

    return (
      <div styleName="container">
        {message}
        <span styleName="test container__inner" className={Style.container__inner4}>aaa</span>
      </div>
    )
  }
}

SzHeJason avatar Nov 28 '19 06:11 SzHeJason

I ran into this issue when using the classnames module, and I solved it by storing the value in a variable and using it in styleName property.

This worked:

const classes = classnames('edit-location', {
      'edit-location--editing': isEditing,
 });

...

<div styleName={classes}>...</div>

This didn't:

<div styleName={classnames('edit-location', {
      'edit-location--editing': isEditing,
 })}>...</div>

It's a manageable workaround until the transpiler gets fixed.

jenshedqvist avatar May 04 '20 17:05 jenshedqvist

@jenshedqvist This issue is about a bit different problem.

In your case, use this code

<div styleName={classnames('edit-location', {
      'edit-location--editing': isEditing,
 })}>...</div>

and before starting dev server remove the .cache folder

rm -rf ./node_modules/.cache
npm start # or however you start dev server

It should work.

hinok avatar May 04 '20 17:05 hinok

It did @hinok

jenshedqvist avatar May 07 '20 12:05 jenshedqvist

I ran into this issue when using the classnames module, and I solved it by storing the value in a variable and using it in styleName property.

This worked:

const classes = classnames('edit-location', {
      'edit-location--editing': isEditing,
 });

...

<div styleName={classes}>...</div>

This didn't:

<div styleName={classnames('edit-location', {
      'edit-location--editing': isEditing,
 })}>...</div>

It's a manageable workaround until the transpiler gets fixed.

I am using Gatsby v3 with babel-plugin-react-css-modules. My problem is that it not work after build, but works fine in dev.

I tried same way as you, however it still does not work.

xyy94813 avatar Jun 01 '21 03:06 xyy94813