DEV Community

Molly Gingras
Molly Gingras

Posted on

Using custom style loaders with the Neutrino React preset

I’m trying out Neutrino to build a new React project, using its React preset.

By default, Neutrino includes everything I need except custom style loaders for tools like Sass. At first, I tried to define my custom loaders according to Neutrino’s style-loader documentation, updating my .neutrinorc.js like so:

const standard = require('@neutrinojs/standardjs');
const react = require('@neutrinojs/react');
const jest = require('@neutrinojs/jest');
const styles = require('@neutrinojs/style-loader');

module.exports = {
  options: {
    root: __dirname,
  },
  use: [
    standard(),
    react({
      html: {
        title: 'app-title'
      }
    }),
    jest(),
    styles({
      test: /\.(css|sass|scss)$/,
      modulesTest: /\.module\.(css|sass|scss)$/,
      loaders: [
        {
          loader: 'postcss-loader',
          options: {
            plugins: [require('autoprefixer')],
          },
        },
        {
          loader: 'sass-loader',
          useId: 'sass'
        },
      ],
    })
  ],
};

Unfortunately, this setup threw an error when I started my dev server:

DuplicateRuleError: @neutrinojs/style-loader has been used twice with the same ruleId of 'style', which would overwrite the existing configuration. If you are including this preset manually to customise rules configured by another preset, instead use that preset's own options to do so.

It wasn’t immediately obvious to me what was going on here, and Google led me to a couple of people with the same problem, but no solutions.

Soon enough, though, I realized that the React preset was already using style-loader under the hood. style-loader’s behavior within the React preset is configurable through a property in the preset's options object called style. I had missed that option because it's documented as part of the Web preset, and not redundantly included in the React preset's docs.

So I adjusted my module.exports accordingly:

module.exports = {
  options: {
    root: __dirname,
  },
  use: [
    standard(),
    react({
      html: {
        title: 'app-title'
      },
      style: {
        test: /\.(css|sass|scss)$/,
        loaders: [
        {
          loader: 'postcss-loader',
          options: {
            plugins: [require('autoprefixer')],
          },
        },
        {
          loader: 'sass-loader',
          useId: 'sass'
        },
      ]
      }
    }),
    jest()
  ],
};

Et voilà, it worked.

TL;DR: If you’re using Neutrino’s React preset (or presumably any of its web presets), you’ll need to configure your custom style loaders within that preset’s options object, using the style property.

I hope this helps someone who’s run into the same issue.

Top comments (0)