Search code examples
sassbulmapostcsscss-modulesparceljs

Importing external stylesheets globally with CSS modules


I'm struggling to add SASS with an external stylesheet (Bulma) to my React application. So far I have set up Parcel with CSS modules via postcss. This is my .postcssrc config:

{
  "modules": true,
  "plugins": {
    "autoprefixer": {
      "grid": true
    },
    "postcss-modules": {
      "generateScopedName": "[name]_[local]_[hash:base64:5]"
    }
  }
}

I have installed node-sass and successfully added a .scss file to one of my components. External (Bulma) styles are added via @import "~bulma/bulma"; and are correctly resolved.

Unfortunately, imported styles are not applied globally and instead the class names are modified similarly to local definitions, e.g.:

/*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */
@-webkit-keyframes container_spinAround_28_Bz {
  from {
    transform: rotate(0deg); }
  to {
    transform: rotate(359deg); } }
@keyframes container_spinAround_28_Bz {
  from {
    transform: rotate(0deg); }
  to {
    transform: rotate(359deg); } }

Note the added prefixes and suffixes.

Ideally, I would like to import the stylesheet globally and do not modify their names. I'd like to continue using CSS modules and I think I also have to use SASS in order to globally modify Bulma stylesheet by overriding SASS variables.

Anyway, things I've tried so far:

  • Using postcss-nested and wrapping the import with :global block:
:global {
  @import "~bulma/bulma";
}

However, this throws an exception:

main.scss:5018:5: Missing whitespace before :global
  • Creating a separate scss file included directly in HTML file via <link> rather than imported in a jsx/tsx file to avoid using CSS modules.

This seems to break Parcel entirely, as it fails to link correct files in the compiled HTML files, i.e. <LONG-HASH>.css instead of generated main.<HASH>.css.

  • Using postcss-import.

Either my setup is incorrect or it has no effect on SASS files.


Solution

  • You can define regular expressions to mark matched files as global stylesheets with the globalModulePaths setting.

        "postcss-modules": {
          "globalModulePaths": [
            ".*\\.global\\..*"
          ]
        }
    

    The example above would mark all files with .global. in their name, e.g. main.global.css.

    Managed to figure it out while writing the question.