CSS Modules + Ant design in ReactJs does not work - css

I am trying to use CSS Modules for CSS styling of my ReactJs project, for this I applied ant design documentation (see here: https://pro.ant.design/docs/style), however unfortunately it doesn't work.
The problem is that I want to override the component style of ant Button and it does not get the style.
Below there is a short sample of my code:
CSS class: in MyContainer.less file:
.antButton{
:global {
.ant-btn-primary {
background-color: rgb(215, 226, 233);
border-color: #848586;
font-size: 7pt;
color: red !important;
}
}
}
code:
import React from 'react';
import { Button } from 'antd';
import 'antd/dist/antd.less';
import styles from './MyContainer.less';
const MyContainer= () => {
return (
<Button type="primary" size="small" className={styles.antButton} >Download</Button>
);
};
export default MyContainer;
I'm using Ant design (Version 4.3.0) in react (Version 16.13.1 ) with Webpack (Version 4.42.0).I also installed less-loader (Version 7.3.0) and babel-plugin-import (Version 1.13.3).
I don't know if there is any specific config of the Webpack that I am missing or the problem is somewhere else?

Finally I could handle my problem with antd, when you use css modules you have to add extra config for antd styles to work, I've found my solution in this web site:
https://www.programmersought.com/article/3690902311/ As described there if you add these configs in these order in your Webpack.config in Rule section it will work with Css modules and overriding less styles of antd components.
{
test: /\.less$/,
include: [/src/],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: true
},
},
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: { lessOptions:{javascriptEnabled: true }}
},
],
},
{
test: /\.css$/,
exclude: /node_modules|antd\.css/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
// change
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
},
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
{
test: /\.css$/,
include: /node_modules|antd\.css/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
// change
// modules: true, // new support for css modules
// localIndetName: '[name]__[local]__[hash:base64:5]', //
},
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
Also you need to add babel import in your package.json:
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript"
],
"plugins": [
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "lib",
"style": true
}
]
]
},
and you have to set style to the wrapper div of antd Components in this way:
import React from 'react';
import { Button } from 'antd';
//import 'antd/dist/antd.less'; you don't need this line when add babel.
import styles from './MyContainer.less';
const MyContainer= () => {
return (
<div className={styles.antButton}>
<Button type="primary" size="small" >Download</Button>
</div >
);
};
export default MyContainer;
I wish it help

Related

Imported css by className is not worked on react

I should use simple css with styled-component.
But, imported css is not applied to component.
It is my webpack.config.ts
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: [
!isProduction && {
loader: 'babel-loader',
options: { plugins: ['react-hot-loader/babel'] },
},
'ts-loader',
].filter(Boolean),
},
// css
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: !isProduction,
importLoaders: 1,
localIdentName: isProduction
? '[hash:base64:5]'
: '[local]__[hash:base64:5]',
},
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-preset-env')({
/* use stage 2 features (defaults) */
stage: 2,
}),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction,
}),
],
},
},
],
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{ test: /\.(a?png|svg)$/, use: 'url-loader?limit=10000' },
{
test: /\.(jpe?g|gif|bmp|mp3|mp4|ogg|wav|eot|ttf|woff|woff2)$/,
use: 'file-loader',
},
],
},
I am importing css like this.
import './chipContainer.css'
import React, { useState } from 'react'
...
And, it is chipContainer.css
.chipContainer{
overflow: scroll;
min-height: 30px !important;
max-height: 100px;
}
Then, it is confirmed className on console.
class="WAMuiChipInput-standard-422 WAMuiChipInput-chipContainer-420 chipContainer"
But, it is not applied.
css defined as an element in the css file, such as body {...}, works fine, but css defined as className does not work.
what is the problem?

Why module style is overlap when same filename

I'm try to style for each component separately by using css-loader plugin of Webpack. But when files has the same name (for example: 'index.scss') and has the same property (for example: '.container') it will combine both style, but in this case I just need ones. How can I solve that
This is my Webpack configuration:
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: 'style-loader',
options: {
insertAt: 'top',
sourceMap: true
}
},
{
// Handle import/ require css
// It help to css for each component
// https://github.com/webpack-contrib/css-loader#scope
loader: 'css-loader',
options: {
sourceMap: true ,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
camelCase: true,
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
// minimize: true,
plugins: () => [
require('postcss-flexbugs-fixes'),
// Help to generate specific css for each component
// require('postcss-modules'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
}
},
{ loader: 'sass-loader', options: { sourceMap: true } },
],
},
]
Example:
src/screen1/index.tsx
const styles = require('./index.scss')
const Dashboard = ({ children, url }: IDashboardPropsIn) => {
return (
<div className={styles.body}>
{children}
</div>
)
}
And I has 2 files: src/screen2/index.scss and src/screen1/index.scss
Somehow in class which name body--[hash:64] has both styles from 2 files
src/screen1/index.scss
:local {
.body {
grid-area: body;
background-color: $white;
}
}
and src/screen2/index.scss
:local {
.body {
display: flex;
}
}
Style of body--[hash:64] will be
grid-area: body;
background-color: $white;
display: flex;
But in this case I only one import the file src/screen1/index.scss such as
grid-area: body;
background-color: $white;
How can I solve that?
You did not specify the modules option in your config
{
// Handle import/ require css
// It help to css for each component
// https://github.com/webpack-contrib/css-loader#scope
loader: 'css-loader',
options: {
sourceMap: true ,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
camelCase: true,
modules: true, // or 'local' | 'global' | false
}
},
Read more in the docs
Update css-loader package to 0.28.11 version

Add sass/css modules to typescript react app

In a new project, I need to add scss/css modules to a typescript/react app.
I added "typings-for-css-modules-loader" to the project and webpack.config.dev.js
like so : (here is the entire webpack.config.dev.js)
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('typings-for-css-modules-loader'),
options: {
importLoaders: 1,
modules: true
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},{
test: /\.scss$/,
use: [
require.resolve('style-loader'),
require.resolve('sass-loader'),
{
loader: require.resolve('typings-for-css-modules-loader'),
options: {
namedexport: true,
camelcase: true,
modules: true
}
}
]
},
When i add a test.scss file to my project, the compilation successfully creates a test.scss.d.ts which contains :
export interface ITestScss {
'toto': string;
}
export const locals: ITestScss;
When i try to import this css in my project like so :
import styles from './scss/test.scss';
I get this error :
Module '"/home/cyprien/projets/test/typescript-sass-modules-boilerplate/src/scss/test.scss"' has no default export.
Finally, In the browser, i get this error :
Failed to compile
./src/scss/test.scss
Module build failed:
.toto{
^
Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex"
in /home/cyprien/projets/test/typescript-sass-modules-boilerplate/src/scss/test.scss (line 1, column 1)
You need to use the plugin mini-css-extract-plugin. Here is an example of configuration with TypeScript and SASS SCSS (but without CSS modules neither PostCSS):
// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
mode: "development",
devtool: "source-map",
resolve: {
extensions: [".ts", ".js"]
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: "ts-loader"
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new MiniCssExtractPlugin()
]
}
I hope you'll be able to adapt it.
Found this solution:
webpack config (dev), this is for less :
{
test: /\.modules\.less$/,
use: [{
loader: 'style-loader' // creates style nodes from JS strings
},{
loader: 'typings-for-css-modules-loader',
options:{
modules:true,
namedExport: true,
camelCase: true,
localIdentName:'[path][name]---[local]---[hash:base64:5]'
}
},{
loader: 'less-loader',
options: { javascriptEnabled: true }// compiles Less to CSS
}]
}
then name your less file something.modules.less
import it in the js as so:
import * as styles from './something.modules.less';
and use it like this:
<div className={styles.yourClassName}></div>

Use PrimeReact Themes with CSS Modules Enabled in React Application

I have enabled CSS modules within webpack.config in my React application so that I can locally scope CSS files to individual components. I'm also trying to use the TabView component from PrimeReact. When I do so the themes from PrimeReact are not applied. If I create a separate project and do not enable CSS modules the themes apply correctly.
How can I use PrimeReact themes and enable CSS modules?
I've tested moving the content located in Tabs.js directly into App.js and get the same results.
CSS Modules Enabled
Webpack.config
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash_base64:5]'
},
},
App.js
import React, { Component } from 'react';
import classes from './App.css';
import Tabs from './UI/Tabs';
class App extends Component {
render() {
return (
<Tabs/>
);
}
}
export default App;
Tabs.js
import React from 'react';
import {TabView, TabPanel} from 'primereact/components/tabview/TabView';
import classes from 'primereact/resources/primereact.css';
import theme from 'primereact/resources/themes/cupertino/theme.css';
const Tabs = () => (
<TabView>
<TabPanel header="Tab One">
This is content for Tab One.
</TabPanel>
<TabPanel header="Tab Two">
This is content for Tab Two.
</TabPanel>
</TabView>
);
export default Tabs;
Default React Global CSS Scoping
CSS Modules Enabled (Local Component Scoping)
I was able to use CSS modules and selectively apply global scoping to PrimeReact's themes by modifying webpack.config as follows below.
Original:
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
Modified:
{
test: /\.css$/,
//Exclude 3rd party css that needs to be scoped globally from using
//css-loader with modules enabled
exclude: [
path.resolve('node_modules/primereact/resources/primereact.css'),
path.resolve('node_modules/primereact/resources/themes/cupertino/theme.css'),
],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash_base64:5]'
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
//Additional css-loader configuration
{
test: /\.css$/,
//Inlcude only 3rd party css that needs to be scoped globally to use
//css-loader with modules disabled
include: [
path.resolve('node_modules/primereact/resources/primereact.css'),
path.resolve('node_modules/primereact/resources/themes/cupertino/theme.css'),
],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
Use the below two npm commands to install the CSS and Style loader:
npm install style-loader - You can add the Version of the loaded if required
npm install css-loader
You are not required to change anything else.

webpack sass-loader not generating css

I can't figure out how to render css with the webpack sass-loader.
App.js file:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Test from "./Test";
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<Test />
</div>
);
}
}
export default App;
Test.jsx file:
import React, { Component } from 'react';
import './Test.scss';
class Test extends Component {
render() {
return (
<p className="intro">
Test
</p>
);
}
}
export default Test;
Test.scss file:
.intro{
background-color: #dddddd;
color: red;
}
webpack.config.dev.js file:
{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
{
test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
}
Image:
Result
Expected
I'm doing something wrong with the sass loader. What is it? Please help.
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.scss$/,
/\.json$/,
/\.bmp$/,
/\.gif$/,
/\.jpe?g$/,
/\.png$/,
],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
}
I added /.scss$/ here, the code is running successfully, thank you all
This is how I use sass-loader together with the help of extract-text-webpack-plugin to create a separate file instead of just including it to bundle.js file.
I'm using webpack v2.6.1
// webpack-config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module: {
rules: [
{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader']}) },
{ test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'sass-loader']}) },
],
},
plugins: [
new ExtractTextPlugin('[name]-[chunkhash].css'),
]
and import it to my index.js, like so:
import '../public/assets/sass/style.scss';

Resources