Add SugarSS To Gatsby

April 02, 2019

Sugarss Diving into the Gatsby Pipeline

It took me a while to figure out how to integrate SugarSS into the Gatsby build pipeline. I couldn’t find an example of anyone else doing it online. So, I decided to quickly write this up.

Install dependencies

First, install the appropriate node modules.

npm i gatsby-plugin-postcss postcss-preset-env sugarss

Add to the Gatsby configuration

Next, add the module to the Gatsby configuration by adding it to the plugins array.

gatsby-config.js

module.exports = {
  plugins: [
    `gatsby-plugin-postcss`,
  ]
}

Add the Webpack configuration

Since Gatsby has its own byzantine Webpack setup, we can’t just write our own. Thankfully, Gatsby provides a hook to modify the Webpack configuration. Even that, though, is complicated and I frankly have no idea how to debug it. I got this working by piecing together a couple parts of the documentation and a little trial and error.

Here is the whole incantation.

gatsby-node.js

const postCssPlugins = [require(`postcss-modules-values`)];

exports.onCreateWebpackConfig = (
  { actions, stage, loaders },
  { cssLoaderOptions = {}, postCssLoaderOptions = {} }
) => {
  const { setWebpackConfig } = actions;
  const isSSR = stage.includes(`html`);

  const sssRule = {
    test: /\.sss$/,
    use: isSSR
      ? [loaders.null()]
      : [
          loaders.miniCssExtract(),
          loaders.css({ ...cssLoaderOptions, importLoaders: 1 }),
          loaders.postcss({
            ...postCssLoaderOptions,
            plugins: postCssPlugins,
            parser: `sugarss`
          })
        ]
  };

  const sssRuleModules = {
    test: /\.module\.sss$/,
    use: [
      !isSSR && loaders.miniCssExtract({ hmr: false }),
      loaders.css({ ...cssLoaderOptions, modules: true, importLoaders: 1 }),
      loaders.postcss({
        ...postCssLoaderOptions,
        plugins: postCssPlugins,
        parser: `sugarss`
      })
    ].filter(Boolean)
  };

  let configRules = [];

  switch (stage) {
    case `develop`:
    case `build-javascript`:
    case `build-html`:
    case `develop-html`:
      configRules = configRules.concat([
        {
          oneOf: [sssRuleModules, sssRule]
        }
      ]);
      break;
  }

  setWebpackConfig({
    module: {
      rules: configRules
    }
  });
};