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
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?
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
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>
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.
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';