mdmb
mdmb

Reputation: 5283

NextJS with CSS/ SCSS loaders

I'm completely new to NextJS, trying out its SSR features. I want to setup loaders where I can load 4 types of files into the app:

  1. *.module.css;
  2. *.module.scss;
  3. *.css;
  4. *.scss;

1 and 2 are loaded with CSS modules and 3 and 4 just as regular CSS/SCSS. How can I do this with @zeit/next-css and @zeit/next-sass?

Upvotes: 1

Views: 3680

Answers (2)

Hamid
Hamid

Reputation: 81

just wondering whether you've managed to get this working?

I managed to come close with something similar to Felix's answer to get .module.scss and .scss files working with .css only working in @imports within a .scss/.module.scss file. Really would like to be able to get .css files working whilst imported from a component.

My next.config.js file for reference below

const withSass = require('@zeit/next-sass');
const withPlugins = require('next-compose-plugins');
const withSourceMaps = require('@zeit/next-source-maps');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const sassConfig = {
  cssModules: true,
  cssLoaderOptions: {
    importLoaders: 2,
    localIdentName: '[local]___[hash:base64:5]',
  },
  webpack: config => {
    config.module.rules.forEach(rule => {
      if (rule.test && rule.test.toString().match(/\.(sa|sc)ss$/)) {
        rule.rules = rule.use.map(useRule => {
          if (typeof useRule === 'string') {
            return { loader: useRule };
          }

          if (useRule.loader.startsWith('css-loader')) {
            return {
              oneOf: [
                {
                  test: new RegExp(/\module.(sa|sc)ss$/),
                  exclude: new RegExp(/\.css$/),
                  loader: useRule.loader,
                  options: useRule.options,
                },
                {
                  loader: useRule.loader,
                  options: {},
                },
              ],
            };
          }
          return useRule;
        });
        delete rule.use;
      }
    });

    return config;
  },
};

module.exports = withPlugins(
  [[withSourceMaps], [withSass, sassConfig]]
);

Upvotes: 2

felixmosh
felixmosh

Reputation: 35573

Currently next-css / next-sass are not supporting this feature, but you can add it by your self to the webpack config.

I've similar but the opposite option, I'm enabling module: true for all imports and for all files that I want to be treated as regular css in (ie. global), I need to add, .global suffix.

This is my modification to the webpack config:

// next.config.js
config.module.rules.forEach(rule => {
  if (rule.test && rule.test.toString().includes('.scss')) {
    rule.rules = rule.use.map(useRule => {
      if (typeof useRule === 'string') {
        return {
          loader: useRule,
        };
      }
      if (useRule.loader.startsWith('css-loader')) {
        return {
          oneOf: [
            {
              test: /\.global\.scss$/,
              loader: useRule.loader,
              options: {
                ...useRule.options,
                modules: false,
              },
            },
            {
              loader: useRule.loader,
              options: useRule.options,
            },
          ],
        };
      }

      return useRule;
    });

    delete rule.use;
  }
});

This piece of code looks for the css-loader config and modifies it to support .global.scss suffix.

BTW, you can get updated by following this PR

EDIT

Next version ^9.2.0 has now a native support for css imports with some restrictions.

Upvotes: 2

Related Questions