create-react-app: Non module css doesn't work with :local() in CRA 3.0

Is this a bug report?

Yes

Did you try recovering your dependencies?

Yes

Environment

Environment Info:

  System:
    OS: Linux 4.14 Manjaro Linux
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
  Binaries:
    Node: 10.15.1 - ~/.nvm/versions/node/v10.15.1/bin/node
    Yarn: 1.15.2 - /usr/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v10.15.1/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    react: ^16.8.6 => 16.8.6 
    react-dom: ^16.8.6 => 16.8.6 
    react-scripts: 3.0.0 => 3.0.0 
  npmGlobalPackages:
    create-react-app: Not Found

Steps to Reproduce

(Write your steps here:)

  1. Have a non module css-file, e.g. MyStyle.css
  2. Have a class in said file as a :local scoped class, e.g. :local(.myClass) { ... }
  3. Import CSS file in a React-component, e.g. import css from './MyStyle.css'
  4. Observe that the classname is not exported

Expected Behavior

That the css class has been given a random name and is available as a property on the css object, e.g. { myClass: "_2uhJkdnDbAceZ0gQC-r3vz" }

Actual Behavior

Object was empty: {}

Reproducible Demo

Source: https://github.com/almyy/local-classname-repro

Deployed example: https://almyy.github.io/local-classname-repro/

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 6
  • Comments: 15

Most upvoted comments

@Maxou44 That is the approach they have recommended since CRA 2.0 but there is a very important distinction when using SCSS, it might not be applicable to you but to anyone else ending up here when googling. When you have a module.scss everythin is exported, even nested selectors.

Consider this component:

import style from './MyComponent.scss`

const MyComponent = ({ highlight }) => (
  <div className={style.myComponent}>
      <div className={highlight ? 'someSubClass' : undefined}></div>
  </div>
)

With this SCSS (the old way):

:local(.myComponent) {
  background-color: red;

  .someSubClass {
    background-color: blue;
  }
}

With ``.module.scss` this would be identical to:

.myComponent {
  background-color: red;

  :global(.someSubClass) {
    background-color: blue;
  }
}

Which of course is pretty poor form, as you might have CSS leakage further down in your component tree if you ever use .someSubClass, but for us this is how most of the older CSS was written, making the migration a bit heavy.

The “correct” way of doing the SCSS with sub-classes from the React component would look like this:

import style from './MyComponent.module.scss`

const MyComponent = ({ highlight }) => (
  <div className={style.myComponent}>
      <div className={highlight ? style.someSubClass : undefined}></div>
  </div>
)

Which doesn’t look to bad, but if you use classnames you have to do this when working with conditional classes:

import classNames from 'classnames'
import style from './MyComponent.module.scss`

const MyComponent = ({ highlight }) => (
  <div className={style.myComponent}>
      <div className={classNames({ [style.someSubClass]: hightlight })}></div>
  </div>
)

Not stale.