Gatsby: Support CSS Modules

Created on 14 Mar 2016  路  15Comments  路  Source: gatsbyjs/gatsby

CSS Modules are cool. Gatsby should ship with support for them as well as demonstrate how to use them in official starters.

Most helpful comment

I think targeting *.module.css is a great idea for backwards compatibility with global CSS :+1:

All 15 comments

I love CSS Modules!

Hi! That's an awesome idea. I managed to make css modules work (tested for scss file) with the following snippet in /gatsby-node.js.

import ExtractTextPlugin from 'extract-text-webpack-plugin'

exports.modifyWebpackConfig = (config, env) => {
  if (env === 'develop') {
    config.removeLoader('css')
    config.removeLoader('less')
    config.removeLoader('sass')
    config.loader('css', {
      test: /\.css$/,
      loaders: ['style', 'css?modules', 'postcss'],
    })
    config.loader('less', {
      test: /\.less$/,
      loaders: ['style', 'css?modules', 'less'],
    })
    config.loader('sass', {
      test: /\.(sass|scss$)/,
      loaders: ['style', 'css?modules', 'sass'],
    })
  } else {
    config.removeLoader('css')
    config.removeLoader('less')
    config.removeLoader('sass')

    config.loader('css', {
      test: /\.css$/,
      loader: ExtractTextPlugin.extract('style', ['css?modules', 'postcss']),
    })
    config.loader('less', {
      test: /\.less$/,
      loader: ExtractTextPlugin.extract('style', ['css?modules', 'less']),
    })
    config.loader('sass', {
      test: /\.(sass|scss)$/,
      loader: ExtractTextPlugin.extract('style', ['css?modules', 'sass']),
    })
  }

  return config.merge({
    plugins: [new ExtractTextPlugin('styles.css')],
  })
}

If you find it worth adding to the gatsby webpack config I can create an appropriate PR

@jakubrohleder so the reason I didn't add support for them is isn't turning on CSS Modules an all-or-nothing decision? Once they're enabled you have to use them? Or does the css module transformation only happen if you import a css file?

Assuming it is a binary choice, we need to wait until Gatsby has a plugin system w/ the ability to configure the css plugin.

@KyleAMathews you are totally right, this change isn't backward compatible (at least according to my knowledge). It is possible thought to use global classes in modules (their names are not processed):

:global .my-awesome-class {
  color: red;
}

or enable css module processing only for certain extensions (it's not standard, but why not .mcss?).

As you said: this change can wait for some time, nevertheless this snippet will help those who desire this kind of functionality.

or enable css module processing only for certain extensions (it's not standard, but why not .mcss?).

That's what I do too, by enabling ?modules for *.module.css. Seems like a safe choice.

*.module.* makes a lot of sense actually. Even if you're using CSS Modules, you probably would want to be able to drop in some 3rd-party css and have it just work. Is there any sort of standard yet around this? I don't use CSS modules myself so don't really know. Also Sass/Less can be used with CSS Modules so any sort of special processing rules would need to account for that.

@markdalgleish what do you suggest?

I think targeting *.module.css is a great idea for backwards compatibility with global CSS :+1:

The convention ive seen actually has been the opposite, using .global. Either works fine though, just depends on what you want to take priority as "default"

@NogsMPLS some of the packages on npm can require CSS from JS: require('./styles.css'), that's why relying only on :global isn't safe.

Sorry on phone, i mean filename. name.global.css as compared to name.module.css. And letting webpack handle the rest.

EDIT: My comment was just in answer to Kyle's 'convention' question. Just wanted to chime in and say I've seen and also used *.global.css in projects. Coming at it from the other direction with *.module.css would work and make sense also, depending on app priorities. I suppose it would just depend if CSS Modules is seen as the exception or the rule in any given app.

Thanks @markdalgleish!

I think *.module is safest. There'll be a lot of people using Gatsby who don't know what CSS Modules are so it's better that modules are opt-in vs. opt-out if we're going to turn them on for everyone.

If someone wants to work on a PR for this, let us know and I'll assign it to you.

Great discussion here! Enabling css modules for *.module.css seems a reasonable compromise. I can handle the PR by the weekend.

@jakubrohleder thanks! 馃挴 Looking forward to your PR.

Oh weird, I can't assign you I guess unless you're a team member of Gatsbyjs. So I just added you and will assign you once you accept :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

3CordGuy picture 3CordGuy  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

signalwerk picture signalwerk  路  3Comments

hobochild picture hobochild  路  3Comments