46

I've been building a project for a while using Webpack, Sass, and CSS modules. Normally in my .scss files, I define a class like:

:local(.button) {
    color: white;
}

and in my React components, in the render method, I require the styles:

render = () => {
    const styles = require('./MyStyles.scss');
    <div className={ styles.button } />
}

and all is good with the world. Everything works as expected.

Now today I was reading through the CSS Modules page and noticed that none of the selectors were encompassed by :local() like mine and furthermore that they were importing the styles like:

import styles from './MyStyles.scss';

And I thought "Wow that looks much nicer, it's easier to see where it's imported, ect. And I'd love not to use :local() and just have things local by default." So I tried that and immediately ran into several problems.

1) `import styles from './MyStyles.scss';

Because I'm using ESLint on my React files, I immediately get an error thrown that MyStyles.scss doesn't have a default export which would normally make sense but the CSS Modules page stated:

When importing the CSS Module from a JS Module, it exports an object with all mappings from local names to global names.

so I naturally expected the default export of the stylesheet to be the object they're referring too.

2) I tried import { button } from './MyStyles.scss';

This passes linting but button logs as undefined.

3) If I revert to the require method of importing my styles, anything not specified with :local is undefined.

For reference, my webpack loader (I'm also including Node-Neat and Node-Bourbon, two awesome libraries):

{ test: /.(scss|css)$/, loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap&includePaths[]=' + encodeURIComponent(require('node-bourbon').includePaths) +
'&includePaths[]=' + encodeURIComponent(require('node-neat').includePaths[1]) + '&includePaths[]=' + path.resolve(__dirname, '..', 'src/client/') }

My questions, following all of this, are:

1) When using CSS Modules with Sass, am I confined to using either :local or :global?

2) Since I'm using webpack, does that also mean I can only require my styles?

1
  • I would escape the wildcard (.) character in your loader's test property, like so: test: /\.(scss|css)$/ Commented Mar 29, 2016 at 20:29

1 Answer 1

44

Soon after posting, I figured out the solution. The problem, which I thought was quite confusing, was in my Webpack config. Originally my loader looked like:

loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap

which enabled to me to 1) require my Sass and 2) wrap my styles in :local.

However, the css loader was missing the modules option so that it looked like:

loader: 'style!css?modules&sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded&sourceMap

Now I can import my styles and I don't have to wrap them in :local (although I presume I still can if I want to).

What I found most interesting about all this is that without the modules option, one can still use CSS Modules-esque features, although somewhat limiting.

EDIT:

Something I noticed, a future warning to whomever looks at this answer, is if you're using the eslint-plugin-import to lint the imports in your javascript code, it will throw an error upon importing styles like:

import styles from './MyStyles.scss';

because of the way CSS Modules exports the resulting styles object. That does mean you'll be required to do require('./MyStyles.scss') to bypass any warnings or errors.

Sign up to request clarification or add additional context in comments.

1 Comment

When using eslint-plugin-import, you can ignore your scss files specifically. see: npmjs.com/package/eslint-plugin-import#importignore

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.