I'm using CSS Modules (through Webpack css loader) in a new React project, and even though it's working great, I'm having trouble getting the SCSS for React Select to work. I imagine this is because it tries to create local
classNames, which the JS in react-select
is unaware of. Is there a way to import an entire .scss
file, but scoped globally instead of locally?
A CSS Module is a CSS file that defines class and animation names that are scoped locally by default.
To be able to use CSS in your webpack app, you need to set up a new loader. Out-of-the-box, webpack only understands Javascript and JSON. With a loader, you can translate another type of file to a format that webpack understands and can work with. There are many webpack loaders and each loader has a specific purpose.
The CSS in a CSS module is no different than normal CSS, but the extension of the file is different to mark that the file will be processed. In this example, a CSS module is imported and declared as a JavaScript object called containerStyles .
I generally define two CSS loaders like this:
// Global CSS
// We make the assumption that all CSS in node_modules is either
// regular 'global' css or pre-compiled.
loaders.push({
test: /\.css$/,
include: /node_modules/,
loader: 'style-loader!css-loader'
});
// CSS modules
loaders.push({
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader?modules'
});
I've also migrated an app to CSS modules in the past and found it was useful to define a convention based on file extension, e.g. {filename}.module.css === CSS Modules vs {filename}.css === Global CSS
// Global CSS
loaders.push({
test: /\.css$/,
exclude: /\.module\.css$/,
loader: 'style-loader!css-loader'
});
// CSS modules
loaders.push({
test: /\.module\.css$/,
loader: 'style-loader!css-loader?modules'
});
When you user css loader in your Webpack configuration, typically you'd want to activate CSS Modules with ?modules
enabled in the querystring, therefore you will activate the :local
scope by default. This means that if you want to declare .selector { ... }
without being converted, you have to use it into a :global(.selector) {}
.
Since you are using SASS loader, in case you want to include css from a vendor, you can import it using @import "~react-select"
. The problem as you said is that this is going to get all selectors from the library converted to local. To avoid this, you can enclose the import in :global
the same way you do with a selector like: :global { @import "~react-select"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With