Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possibility to pass options to css-loader and sass-loader when using (s)css modules #10339

Closed
joafeldmann opened this issue Jan 30, 2020 · 5 comments · Fixed by #11063
Closed

Comments

@joafeldmann
Copy link

joafeldmann commented Jan 30, 2020

Feature request

Is your feature request related to a problem? Please describe.

I'd like to pass further options (like includePaths or localIdentName) to sass-loader/css-loader when using the new built in css modules.

Additional context

Maybe hashing the css classnames via localIdentName: [hash:base64] in production mode could be a default.

@StarpTech
Copy link
Contributor

We need includePaths because we have a monorepo and we don't want to deal with long relative paths.

@alejalapeno
Copy link
Contributor

I'm not part of the Next team but I've been putting some thought into the best way to handle this.

Some options:
A) Simply brute force in another option that can be used inside next.config.js. Pass through the value to sass-loader options object.
Pros:

  • Easy to implement into the codebase
  • Easy to implement as a user

Cons:

  • It's not really a configuration for Next specifically
  • Increases the Next config footprint

B) Build in config detection for .sassrc.js .sassrc.json sass.config.js and/or a sass option in package.json.
Pros:

  • Follows the industry set convention
  • Separates the settings from next.config.js

Cons:

  • Is not built-in convention for Webpack Sass (Parcel has this convention built in)
  • Adds a lot of complexity to Next for the sake of loading a separate config

C) Build the above config detection upstream for sass-loader.
Pros:

  • Follows convention of postcss-loader which uses postcss-load-config
  • Keeps maintenance out of Next
  • Improves cross-project support of sass-loader

Cons:

  • Will take longest to implement/merge
  • Might not be accepted route by sass-loader maintainers

My personal opinion is that C is the best way forward, but maybe there's a half-step that can be taken in the meantime? I'd just like to see .sassrc.json and such accepted out-of-box for all Webpack projects than try to shim the customization into Next.

@joafeldmann
Copy link
Author

I would go with A) since people might be used to it from the old next-plugins, e.g. https://github.com/zeit/next-plugins/blob/master/packages/next-sass/readme.md

Something like:

// next.config.js

const isProd = process.env.NODE_ENV === 'production'

module.exports = {

  sassLoaderOptions: { 
    includePaths: ['absolute/path/a', 'absolute/path/b'] 
  },

  cssLoaderOptions: {  
    modules: {
      // This could be a next.js default?
      localIdentName: isProd ? '[hash:base64]' : '[path][name]__[local]--[hash:base64:5]',
    },
  }

}

@OscarBarrett
Copy link

As a workaround for now, you can do the following to get your custom options in there. It's not pretty but it works...

let rule, moduleRules, cssLoader, scssRules, sassLoader;
if (rule = config.module.rules.find(rule => Object.keys(rule).includes('oneOf'))) {
  // Locate css-loader config for css modules
  if (moduleRules = rule.oneOf.filter(r => ('test.module.scss'.match(r.test) || 'test.module.css'.match(r.test)) && Array.isArray(r.use))) {
    for (const moduleRule of moduleRules) {
      if (cssLoader = moduleRule.use.find(u => u.loader.match('css-loader'))) {
        cssLoader.options = {
          ...cssLoader.options,
          // Any custom css loader options here
          modules: {
            ...cssLoader.options.modules,
            // Your custom css-modules options below.
            getLocalIdent: () => false, // Fall back to default getLocalIdent function
            localIdentName: process.env.NODE_ENV === 'production' ? '[hash:base64:8]' : '[name]__[local]___[hash:base64:5]',
          }
        }
      }
    }
  }

  // Locate sass-loader config
  if (scssRules = rule.oneOf.filter(r => ('test.scss'.match(r.test) || 'test.module.scss'.match(r.test)) && Array.isArray(r.use))) {
    for (const scssRule of scssRules) {
      if (sassLoader = scssRule.use.find(u => u.loader.match('sass-loader'))) {
        sassLoader.options = {
          ...sassLoader.options,
          // Your custom sass-loader options below.
          prependData: '@import "~styles/variables.scss";',
        }
      }
    }
  }
}

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants