Normal CSS with CSS Modules - css

I was previously using bootstrap css import fine previously.
However I'm trying to use CSS module so I added a few lines.
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true, //<- Added to enable css module
localIdentName: '[name]__[local]___[hash:base64:5]' //<-Added to enable css module
}
},
'postcss-loader'
]
},
Now I'm able to use the following sample codes
import styles from 'styles.css'
and use it in the code like this
<div className={styles.container}></div>
and it becomes like this in browser
<div class="styles__container___3dfEE"></div>
I have the following in my index.js
import 'bootstrap/dist/css/bootstrap.min.css';
Now, all my classes from bootstrap.min.css are no longer working.
How can i enable both css modules as well as continue to use bootstrap css normally?
I'm currently using a "dirty" way to do it, by saving my custom styles as styles.sss instead and added the following codes in webpack config. Not sure whether it will have any issues.
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader'
]
},
{
test: /\.sss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
'postcss-loader'
]
}

you need to import bootstrap's css without going through your original webpack config:
import "!style-loader!css-loader!bootstrap/dist/css/bootstrap.min.css";
this will activate the style-loader and css loader but without the modules: true option

I have learnt few methods before for this Github pull-request issue.
First, change the file name. Easiest way but ugly.
Change your styles.css to styles.m.css and separate module and plain css like
//Module
test: /\.m.css$/
//Plain
test: /\^((?!\.m).)*css$/
Second, separate the folders for module and plain css, while exclude each other.
//Module
exclude: /css/plain/
//Plain
exclude: /css/module/
Third, use resourceQuery
test: /\.css$/,
oneOf: [{
resourceQuery: /^\?raw$/,
use: [...]
}
And import as
import './bootstrap.min.css?raw'

Try to separate the loaders into different rules. Like this:
{
test: /\.css$/,
use: [
'style-loader',
]
},
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
'postcss-loader'
]
}

Related

Webpack - React unable to load videojs css file via webpack

I'm implementing video.js in a React web-app.
Using
import video.js/dist/video-js.min.css
it doesn't load all the css classes. Whilst if I use the following form it does.
require('!style-loader!css-loader!video.js/dist/video-js.min.css');
The latter form though triggers a import/no-webpack-loader-syntax eslint error.
How can I configure webpack in order for it to load the video-js.min.css file?
My webpack css loader config looks like this right now:
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer()
],
sourceMap: true
}
}
]
}

Css of node-modules

I am using css modules in my react application. After setting modules:true inwebpack.config.js, I am able to get css from files which I created in my src folder. I am importing some components from node-modules. But the css of components present in node-modules is not getting applied.
I also tried importing css of node-modules using import 'path'; but it didnt work.
If I set modules:false, css of node-modules is getting applied and css of files in src folder is not getting applied.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
},
}
],
},
],
},
};
This might be due to the node module you are using may not be following module syntax. I mean they might be setting classes directly with a string instead of using like style.someClassName. So, you need 2 entries in your rules 1 for your stuff and 1 for node modules.
for ex:
module.exports = {
module: {
rules: [{
test: /\.css$/,
exclude: /node_modules/,
use: [{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
},
}
],
}, {
test: /\.css$/,
include: /node_modules/,
use: [{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: false,
},
}
],
}],
},
};

Webpack: How to use CSS-modules and imported CSS from outside libraries?

I am using css-modules in my react application, however when I try to import outside files in .js files, I cannot import them globally because I cannot wrap them in a :global block, and webpack interprets them as styles meant to be used as objects.
How do I import CSS files as global CSS from external libraries? This is CSS that is supposed to match imported plugins.
e.g.in src/index.js
import 'draft-js/dist/Draft.css';
//cannot wrap in a :global block since it is imported
import 'react-responsive-carousel/lib/styles/carousel.min.css';
// is wrapped in a :global {...} block, so it works
import './styles/app.css';
Webpack configuration, from Create-React-App
test: /\.css$/,
loader: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
minimize: true,
},
},
'postcss-loader'
]
One option is to have two separate rules for src styles and node_modules styles and only set modules to true in your src config. It should look similar to below (I didn't test this) - the important options are include and exclude and to remove modules from the rule that applies to node_modules.
{
test: /\.css$/,
exclude: /node_modules/,
loader: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
minimize: true,
},
},
'postcss-loader'
]
},
{
test: /\.css$/,
include: /node_modules/,
loader: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
},
},
'postcss-loader'
]
}

Tilde in url with css modules does not work

Do you have some example config that works?
setting for webpack:
{
test: /\.scss$/,
use: ['style-loader', {
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]--[hash:base64:5]',
},
}, 'sass-loader'],
},
Usage:
background: url('~assets/arrow-white.svg') center no-repeat;
Output:
Module not found: Error: Can't resolve './assets/arrow-white.svg'
I can omit ~ or use ~/../assets and it works , but I would like to use it just ~.
Probably relevant bug: CSS modules break build if used with ~ https://github.com/webpack-contrib/css-loader/issues/589
I just copy your comment in order that you may close this question
the problem is that css-modules mode changes path resolution and
doesn't respect webpack module resolution
Use this package https://github.com/P0lip/url-tilde-loader
// In your webpack config
{
test: /\.s?css$/,
use: [
'style-loader',
{
loader: "css-loader",
options: {
modules: true,
},
},
{
loader: 'url-tilde-loader'
options: {
replacement: '~/../', // string to replace with
traverse: false, // use manual traversing
},
},
]
}

Webpack.config not running Sass-Loader before PostCSS-Loader

My config file currently has the following possibly relevant code:
{
// do not exclude `node_modules`
test: /\.css$/,
loader: ExtractTextPlugin.extract(
'style-loader',
'css',
{ publicPath: '../' }
)
},
{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract(
'style-loader',
['css-loader', 'postcss-loader', 'sass-loader'],
{ publicPath: '../' }
)
},
It's important that I run sass-loader first because PostCSS-loader (Autoprefixer) is unable to reach code within a #mixin that I have.
So far I've been unable to apply the relevant vendor prefix to the #mixin code being imported in. Everything works as expected if I move the #mixin code to where I #include it.
For Webpack 1 the extract function is expecting two parameters.
The first parameter will be applied when you're not extracting css to a file (fallback).
The second parameter is a list of loaders separated by an exclamation mark (!) , these loaders are applied from right to left.
ExtractTextPlugin.extract(
'style-loader',
'css-loader!postcss-loader!sass-loader'
);
For Webpack 2:
The ExtractTextPlugin is expecting a loader or an object.
ExtractTextPlugin.extract(options: loader | object)
Example:
{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
loader: [
"css-loader",
"postcss-loader",
"sass-loader"
]
})
}
I've discovered the issue in my code. My entry-point files, where the scss files were being imported, were importing as such:
import styles from '!style-loader!css!sass!postcss-loader!./styles/styles.scss'
This was overwriting the configurations in my webpack.config files, so I simply changed all my import lines to have the correct loader order.

Resources